设计自动化报表系统
需求
设计自动化报表系统,支持:
- 日报/周报/月报定时生成和推送
- 多格式输出(邮件、PDF、企微、钉钉)
- 自助报表定制(拖拽式)
- 异常指标自动高亮
架构设计
核心模块
| 模块 | 功能 | 技术方案 |
|---|---|---|
| 报表模板 | 可视化模板编辑 | Jinja2 模板 + 图表组件 |
| 调度引擎 | 定时/事件驱动执行 | Airflow / Celery Beat |
| 数据查询 | 从指标平台取数 | SQL + API |
| 渲染引擎 | 生成报表文件 | WeasyPrint(PDF) + openpyxl(Excel) |
| 分发推送 | 多渠道推送 | SMTP + Webhook |
报表模板设计
# 日报模板示例(Jinja2)
report_template = """
# {{ report_name }} - {{ date }}
## 核心指标
| 指标 | 今日 | 昨日 | 环比 | 目标 | 状态 |
|------|------|------|------|------|------|
{% for metric in metrics %}
| {{ metric.name }} | {{ metric.today }} | {{ metric.yesterday }} | {{ metric.change }} | {{ metric.target }} | {{ '✅' if metric.achieved else '❌' }} |
{% endfor %}
## 异常预警
{% for alert in alerts %}
- ⚠️ **{{ alert.metric }}** {{ alert.message }}
{% endfor %}
## Top 变化
{% for insight in top_changes %}
- {{ insight }}
{% endfor %}
"""
异常自动高亮
def check_anomaly(metric_value, baseline, threshold_pct=20):
"""检查指标是否异常"""
change_pct = (metric_value - baseline) / baseline * 100
if abs(change_pct) > threshold_pct:
direction = "上升" if change_pct > 0 else "下降"
return {
"is_anomaly": True,
"message": f"{direction} {abs(change_pct):.1f}%,超过阈值 {threshold_pct}%",
"severity": "critical" if abs(change_pct) > 50 else "warning"
}
return {"is_anomaly": False}
常见面试问题
Q1: 报表数据如何保证准确性?
答案:
- 数据源统一:所有报表从指标平台取数,不直接查原始表
- 数据就绪检查:报表生成前检查上游数据是否就绪(Airflow Sensor)
- 自动校验:报表生成后自动校验关键指标与前一天的波动范围
- 版本管理:报表模板和 SQL 纳入 Git 版本管理
Q2: 如何处理"大家不看报表"的问题?
答案:
- 减少报表数量:合并冗余报表,只保留有价值的
- 突出异常:正常数据灰色显示,异常数据红色高亮
- 推送优化:只在有异常时推送,避免信息疲劳
- 交互式:提供链接跳转到 BI 看板,支持深入分析