← 博客
技术2026-08-313 次阅读

Python 自动化实战:批量处理产线日报与邮件推送

# Python# 自动化# Excel# 邮件发送# 制造业IT

背景:每个早晨 9 点的 Excel 地狱

在 MES 运维岗位上,每天早上 9 点前,产线主管会在群里@所有人:昨天的生产数据汇总做好了吗?良率、UPH、停机原因分析,每个车间要交 Excel,人工汇总至少 2 小时,还容易出错。

我当时的状态:打开 12 个 Excel 文件,复制粘贴,公式核对,然后再用 Outlook 一封一封发邮件。有一次把 A 车间良率 95.23% 错贴成 9.5%,被生产副总在群里点名。

后来我用 Python 写了一个脚本,10 秒完成全部工作,现在几乎每天都在跑。本文记录完整实现过程和踩过的坑。

解决思路:三大模块

脚本拆成三个部分:

  • 数据采集:从各车间 Excel 中读取关键指标
  • 数据汇总:自动计算整体良率、UPH、停机时长
  • 邮件发送:用 Python 直接发带附件的邮件,无需人工操作 Outlook

第一步:安装依赖

pip install pandas openpyxl

其中:

  • pandas:数据处理核心库,读取/写入 Excel 的利器
  • openpyxl:pandas 读写 .xlsx 格式的底层引擎
  • smtplib:Python 标准库,直接发信,不需要额外安装

第二步:批量读取 Excel 数据

假设各车间日报格式统一,表头为:[时间, 产品, 批次, 良率, UPH, 停机原因, 停机时长]:

import pandas as pd
import os

def batch_read_excel(folder):
    # 批量读取文件夹下所有 Excel
    dfs = []
    for file in os.listdir(folder):
        if file.endswith('.xlsx') and not file.startswith('~$'):
            df = pd.read_excel(os.path.join(folder, file))
            df['车间'] = file.split('_')[0]  # 从文件名提取车间名
            dfs.append(df)
    return pd.concat(dfs, ignore_index=True)

# 使用
all_data = batch_read_excel('C:/产线日报/')
print(f"共读取 {len(all_data)} 条记录")

注意排除 ~$ 开头的临时文件,否则 Excel 打开时会报权限错误。

第三步:计算汇总指标

# 按车间汇总
summary = all_data.groupby('车间').agg({
    '良率': 'mean',
    'UPH': 'mean',
    '停机时长': 'sum'
}).round(2)

print(summary)

输出示例:

          良率     UPH   停机时长
车间
A车间  95.23  120.5     45.0
B车间  92.18  115.2     68.0
C车间  96.50  128.0     32.0

一行 groupby + agg 搞定多维度汇总,比 Excel 透视表快得多,而且不会因为拖拽出错。

第四步:发送带附件的邮件

用 QQ 邮箱 SMTP 发信,需要在网页端设置中开启 SMTP 并生成授权码(不是登录密码):

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from datetime import datetime

def send_email(summary_df, sender, auth_code, receivers):
    today = datetime.now().strftime('%Y-%m-%d')
    subject = f'{today} 产线日报汇总'
    
    msg = MIMEMultipart()
    msg['From'] = sender
    msg['To'] = ', '.join(receivers)
    msg['Subject'] = subject
    
    # 邮件正文(HTML 格式,支持中文)
    body = "<h3>今日产线日报汇总</h3>"
    body += summary_df.to_html(index=True, border=1)
    body += "<p>详细数据见附件 Excel。</p>"
    msg.attach(MIMEText(body, 'html', 'utf-8'))
    
    # 生成附件
    attach_path = f'D:/产线日报备份/{today}_汇总.xlsx'
    summary_df.to_excel(attach_path)
    
    with open(attach_path, 'rb') as f:
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(f.read())
        encoders.encode_base64(part)
        part.add_header('Content-Disposition',
                        'attachment',
                        filename=f'{today}_汇总.xlsx')
        msg.attach(part)
    
    # 发信
    server = smtplib.SMTP_SSL('smtp.qq.com', 465)
    server.login(sender, auth_code)
    server.send_message(msg)
    server.quit()
    print(f"邮件已发送至 {len(receivers)} 人")

# 调用
send_email(
    summary_df=summary,
    sender='your_email@qq.com',
    auth_code='your_auth_code',  # QQ邮箱SMTP授权码
    receivers=['manager@company.com', 'vp@company.com']
)

踩坑记录

  • 坑 1:Excel 百分比格式。有些单元格显示"95.23%"但底层值是 0.9523,直接读出来是浮点数。需要统一转换:df['良率'] = df['良率'].apply(lambda x: x*100 if x < 1 else x)
  • 坑 2:文件被占用。Excel 正在打开时 pandas 无法读取,报 PermissionError。解决方案:脚本里加 try-except 跳过被占用的文件,最后报告哪些没读到。
  • 坑 3:QQ 邮箱 SMTP 地址。SMTP 是 smtp.qq.com:465(SSL),不是 imap.qq.com(那是收信用的)。
  • 坑 4:附件中文名乱码。Python 3 的 email 库对中文文件名支持不太好,用 email.header 的 Header 类包装可以解决,或者干脆用英文名加日期。
  • 坑 5:Windows 计划任务路径。用 Windows 任务计划程序定时跑脚本时,必须设工作目录,否则相对路径全部找不到文件。

进阶:用 Windows 计划任务实现全自动

最后一步,把脚本挂到 Windows 计划任务上,每天早上 8:50 自动执行:

# 创建计划任务(管理员 PowerShell)
schtasks /create /tn "DailyProductionReport" `
    /tr "python D:\scripts\daily_report.py" `
    /sc daily /st 08:50 /rl HIGHEST

这样每天 8:50 脚本自动跑,9 点前领导就能在邮箱里看到汇总报告。

总结

这个脚本用了大半年,累计节省工时约 60 小时。核心经验三条:

  1. 先标准化:让各车间按统一模板提交 Excel,比后期处理更重要
  2. 错误处理要提前:在脚本里加 try-except,避免某个车间文件异常导致整个流程中断
  3. 本地备份:每日汇总后自动拷贝一份到备份目录,防止误删或覆盖

下一步优化方向:对接 MES 数据库直接取数据(省去人工导出 Excel)、增加异常预警(良率低于 90% 自动标红)、用飞书机器人推送到群。

——工程师写给工程师:自动化不是为了炫技,而是为了解决每天重复的痛点。从一个脚本开始,你会发现工作效率提升不止一点点。

评论 (0)