一、背景:被日报周报绑架的加班狗
我在FAB做YE(良率工程师)时,每天早会前要交一份昨日良率日报:从MES导3个Excel(WIP、测试、缺陷),算各站点良率,画3张趋势图,写一段分析,邮件发出。机械重复,每天2小时,经常因此晚走一个小时,家里人颇有怨言。
更烦的是周报,要汇总一周数据、对比上周、标出异常批次,3小时起步。有次我休假,同事代做周报把良率算反了(把报废率当良率报成98%),闹了笑话,也暴露了"这活离了我就出错"的脆弱–说明流程绑死在人身上,本身就是风险。
2023年我下定决心把这套彻底自动化。核心思路:数据从接口拉(不手动导)、计算用脚本(不手算)、报告用模板生成(不手敲)、定时任务发(不手动点)。三个月后,日报周报全自动,我终于准点下班,同事代班也不会再算反。
这件事让我意识到:工程师的价值在分析和决策,不在搬运和复制粘贴。把重复劳动交给脚本,把省下的时间用来做真正需要脑子的事,才是正循环。
二、技术原理:自动化报表的四块积木
自动化的本质是"把人做的重复动作变成代码"。拆开看就四块:数据源、计算、渲染、调度。每块都有成熟工具,组合起来就是一条流水线。
数据源:最理想是直连数据库(pymysql/pyodbc)或用MES的REST API拉JSON。退一步用openpyxl读导出的Excel也行,但尽量别让人手动导–手动导就还没全自动,且容易漏文件。我厂MES开放了只读API,我直接拉,彻底免去手动导出。
计算:pandas是绝对主力。groupby算各站点良率、merge关联WIP和测试、rolling算趋势,几行搞定。比Excel公式稳(不会引用错单元格),且完全可复现–同样输入永远同样输出,这点对审计很重要。
渲染:报告用python-docx按模板生成(标题、表格、段落、图片),图表用matplotlib存PNG再嵌入。Excel报表用openpyxl写入带公式的模板。PDF用docx转或reportlab。模板定好后,换数据即可,样式零改动。
调度:Windows用任务计划程序(Task Scheduler),Linux用crontab。设每天08:00跑日报、周一08:00跑周报,跑完自动发邮件(smtplib)。全程无人值守,连点鼠标都不用。
为什么不用现成BI(PowerBI/Tableau)?BI适合交互式看板,但"生成一份可邮件发送的标准周报"这种固定格式输出,BI反而麻烦(要配订阅、导出)。脚本更灵活,且零授权成本,改格式改逻辑都快。
一个经验:渲染层尽量和逻辑层分离。计算用纯pandas,渲染用单独函数,模板用独立docx文件。这样改报告样式不用动计算,改计算不影响样式,维护清爽。
调度层有个坑:脚本依赖的运行环境(Python版本、库)要和调度机器一致。我曾因调度机Python版本低导致脚本失败,后来把环境固化成requirements.txt加虚拟环境,问题解决。
三、实战:我的日报自动化流水线
具体实现,三个脚本串起来,一个bat批量触发:
脚本一 fetch_data.py:调MES API拉昨日WIP/测试/缺陷数据,存成本地parquet(比csv省空间、读得快)。加try-except,接口挂了就发告警而不是静默失败–我吃过静默失败的亏。
脚本二 build_report.py:pandas算良率(按站点、按产品、按班次),matplotlib画3张图(良率趋势、缺陷Top、WIP分布),python-docx组装成docx,套用固定模板(厂名、日期、签名位自动填,连"拟稿:XXX"都自动)。
脚本三 send_mail.py:把docx转PDF(或用docx直接发),smtplib发到产线邮件组,主题自动带日期和"良率是否正常"的摘要标记。
任务计划设08:00触发run_all.bat(依次跑三个脚本)。上线后我每天到点收邮件就行,偶尔看一眼异常标红项。周报同理,多一步7日聚合和环比分析。
效果:日报从2小时→0人工(偶尔1分钟抽查),周报从3小时→5分钟复核。一年省出约500小时,够学一门新技术或者陪家人了。效率和生活质量双丰收。
四、为什么要这样写代码
这段代码是报表调度核心。用subprocess串行跑三个脚本,保证顺序(先取数再出报告再发信),任一环节失败就停,避免发出空报告或旧报告。
logging把每一步记到日志文件,出问题能回放。我吃过"静默失败"的亏–有次接口挂了脚本没报错,发出一份空周报,被老板问。现在失败必告警,且日志可查。
ret=subprocess.call(…)拿返回码判断成败,比看输出文本可靠。0=成功,非0=失败,清晰。配合try/except,任何环节异常都转化为明确失败信号,绝不悄悄成功。
五、效果对比:时间账和准确账
自动化前后,时间账一目了然:日报2h→0,周报3h→0.1h,月度报告半天→0.5h。按22个工作日算,每月省约50小时,一年600小时,相当于多了75个工作日。
更重要的是准确性和一致性:手工算容易错(我同事算反良率就是例子),脚本每次用同一逻辑,结果稳定可审计。代做的同事再没出过错,因为逻辑固化在代码里,人不经手计算。
还有个意外收益:数据可追溯。每次报告对应的原始数据都存了parquet,半年后有人质疑某周良率,我能秒级调出当时的数据和算法,不像以前Excel早删了。
报告格式统一后,跨月、跨年对比变得容易。以前各人各写,格式五花八门,想看去年同期根本对不上;现在模板统一,历史报告直接可比,年度复盘效率翻倍。
六、实施建议:从最痛的一份开始
1. 从最痛的一份报表切入:别想一口气全自动化,先挑每天必做、最机械的那份(通常就是日报),跑通再扩展。我就是这样,先日报后周报,阻力最小。
2. 先打通数据源:自动化的最大拦路虎往往是"数据拿不到"。优先推动MES开只读API,拿不到就先用openpyxl读导出文件过渡,别卡在第一步。
3. 模板先行:报告格式先和老板对齐定死,脚本按模板填,避免反复改样式。格式定了,后面只动数据。
4. 失败要告警不要静默:调度任务必须配置失败通知(邮件/钉钉),否则你以为跑了对其实挂了。我设了"脚本未跑=告警"。
5. 保留人工复核位:全自动不是完全无人看,关键报表留一个"人工确认后发送"的开关,防灾难。我们日报自动发,周报人工点一下确认再发。
6. 脚本也要版本管理:把报表脚本放Git,改了能回滚。我曾改坏一个公式导致周报全错,靠Git回滚十分钟恢复。
把"人审"做成可选关卡而非必选:日报自动发,周报因涉及决策留人工确认。既省事又控风险,平衡好自动化和兜底。
文档化你的流水线:谁改过哪段逻辑、数据结构是什么,写进README。我离职交接时,继任者照着README半天就接手了,没来问我一个问题。
七、进阶方向:从模板到智能洞察
报表自动化下一步是"智能洞察":脚本不只罗列数据,而是自动标出异常(如某站点良率环比跌超2σ)并写一句原因分析草稿,人只需改几个字。这比纯模板灵活,也更省人。
再进一步接大模型,让AI根据数据自动生成分析段落,工程师做最终把关。这比纯模板灵活,是我正在试的方向–把"数据→结论"的最后一公里也自动化。
多厂/多产线时,可以把报表调度做成服务(Airflow),统一编排依赖、重试、告警,比单机任务计划更稳更可控,也方便多人协作。
时机成熟可以把报表服务化:不止自己用,也让工艺、质量同事能自助拉报告。服务化后,IT从"做报表的人"变成"提供报表能力的人",杠杆更大。
效果对比
|
报表 |
手工耗时 |
自动化后 |
节省/月 |
准确性 |
|
日报 |
2h |
0(抽查1min) |
~44h |
稳定 |
|
周报 |
3h |
0.1h |
~60h |
稳定 |
|
月报 |
0.5天 |
0.5h |
~10h |
稳定 |
|
临时分析 |
不定 |
脚本复用 |
显著 |
可复现 |
完整代码
import subprocess, logging, datetime
logging.basicConfig(filename='report.log', level=logging.INFO)
today = datetime.date.today()
def run_step(name, cmd):
logging.info(f"{today} 开始 {name}")
ret = subprocess.call(cmd, shell=True)
if ret != 0:
logging.error(f"{name} 失败, 返回码{ret}")
raise SystemExit(f"{name} 失败")
logging.info(f"{name} 完成")
try:
run_step("取数", "python fetch_data.py")
run_step("出报告", "python build_report.py")
run_step("发邮件", "python send_mail.py")
print("日报自动化完成")
except Exception as e:
print("日报失败:", e)








