page contents

告别手动发周报:Python自动发邮件完整方案

现在我用AI辅助写Python把整个流程写成脚本,每周一早8点,报表自己生成、自己出图、自己整理邮件,等我到公司,点上杯瑞幸,然后过一遍数据和邮件内容就行了。

attachments-2026-07-S2iiwk6t6a601fd552e39.png以前每周一一大早的"标准动作"是:打开邮箱、打开Excel、跑SQL、把数据贴到Excel里、做几张图、调格式、写分析、转PDF、写邮件内容、挨个加抄送......

这一套下来,保底两小时,遇到数据异常特殊情况的,3-5个小时就搭进去了。

更崩溃的是,每周一都是一样的套路,连改都没法改,纯硬活

现在我用AI辅助写Python把整个流程写成脚本,每周一早8点,报表自己生成、自己出图、自己整理邮件,等我到公司,点上杯瑞幸,然后过一遍数据和邮件内容就行了。

整体工作流程没有想象的复杂,今天给大家分享一下整体方案

整体方案:四个模块串成一条线

整条自动化流程,差不多四个模块:

取数:pandas读SQL/Excel/中间表,输出DataFrame

出图:matplotlib生成销售趋势、Top门店、品类分布三张图

发邮件:yagmail或smtplib发HTML邮件,附件带图片和Excel

定时:schedule库每周一8点自动触发,全程零人工

第一步:取数(pandas读数据)

我用pandas从SQL直接拉数据,示例代码:

import pandas as pd

from sqlalchemy import create_engine

# 引擎配置,按自己公司改

engine = create_engine('mysql+pymysql://user:pwd@host:3306/db')

# 每周一跑上周数据

sql = """

SELECT

    store_name,

    SUM(sales) AS total_sales,

    COUNT(DISTINCT member_id) AS member_cnt

FROM daily_sales

WHERE sale_date BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)

                    AND DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY)

GROUP BY store_name

ORDER BY total_sales DESC

"""

df = pd.read_sql(sql, engine)

注意一个小坑:任务最好放在凌晨跑,用`DATE_SUB`比写死日期省心,跨月跨年都不会出错。

第二步:出图(matplotlib三张图)

用matplotlib生成三张关键图,存到本地临时目录:

import matplotlib.pyplot as plt

import os

# 中文字体配置(Mac/Win不一样,按你电脑改)

plt.rcParams['font.sans-serif'] = ['PingFang SC', 'Hiragino Sans GB']

plt.rcParams['axes.unicode_minus'] = False

os.makedirs('/tmp/report_img', exist_ok=True)

# 图1:门店销售Top10

top10 = df.head(10)

plt.figure(figsize=(10, 6))

plt.barh(top10['store_name'], top10['total_sales'], color='#E74C3C')

plt.title('门店销售Top10', fontsize=16)

plt.gca().invert_yaxis()

plt.tight_layout()

plt.savefig('/tmp/report_img/top10.png', dpi=120)

plt.close()

剩下两张图(趋势图、品类分布)写法一样,就是改下数据和颜色。这块代码是死的,跑一次就能复用。

第三步:发邮件(yagmail最省事)

我对比过smtplib和yagmail。yagmail就够用,比smtplib少写一半代码,附件、内嵌图片、HTML正文都一行搞定。

import yagmail

# 一次性配好(密码用QQ邮箱授权码,不是登录密码)

yag = yagmail.SMTP(

    user='your@qq.com',

    password='你的QQ邮箱授权码',  # QQ邮箱设置里生成

    host='smtp.qq.com'

)

# HTML正文

html = f"""

<h2>上周销售周报(自动生成)</h2>

<p>本周总销售额:<b>{df['total_sales'].sum():,.0f}元</b></p>

<p>活跃会员数:<b>{df['member_cnt'].sum():,}人</b></p>

<p>详见附件和图片。</p>

"""

# 发送(收件人+抄送+附件+正文,一行搞定)

yag.send(

    to=['leader@company.com'],

    cc=['me@company.com'],

    subject='【周报】上周销售数据',

    contents=[yagmail.inline('/tmp/report_img/top10.png'), html],

    attachments=['/tmp/report_img/top10.png', '/tmp/report_img/趋势.png']

)

 

几个容易踩的坑:

• 授权码不是密码:QQ/163/企业邮箱都要去后台单独开授权码

• 图片内嵌用yagmail.inline():不然图片在收件人那边是裂的

• 抄送cc和密送bcc要分清:cc所有人可见,bcc不可见

第四步:定时(schedule最简单)

定时方案我试过三个,schedule、cron、APScheduler——个人推荐schedule,10行代码搞定:

import schedule

import time

def job():

    # 把前三步打包成一个函数

    run_full_pipeline()

# 每周一早8点跑

schedule.every().monday.at('08:00').do(job)

while True:

    schedule.run_pending()

    time.sleep(60)  # 每分钟检查一次

这个脚本扔到服务器后台跑(用`nohup python script.py &`),周一早上你还没到工位,报表已经躺在领导邮箱里了。

我自己用的时候,还多了两块活儿

基础版能节约2小时。我自己用的版本还多了两块:

多门店报表自动拆分,用`groupby('store_name')`拆分数据,每个店长只看自己店的数据,邮件正文用f-string动态插入店长名字,加个`for`循环解决。

写在最后:数据人最该先自动化什么

个人认为,最该自动化的不是分析环节,是"交付环节"。

分析再花哨,最后一公里是"让该看的人看到"。Excel再漂亮,没有触达到目标用户手上就是零。Python这玩意儿最大的价值不是帮你算数据,是把"算完数据→送到决策者手里"这条链路打通。

额外再插一嘴,现在各种AI工具已经基本成熟了,推荐使用workbuddy创建自动任务,可以帮助0编程基础的数据员,从头梳理各种卡点,它会帮你调试代码搭建自动任务,不过需要警惕的是AI出的数据结果一定要自己复核一遍,我被坑了好多次了,唉......

更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

 

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

2247 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. Pack 2247 文章
  3. 小柒 2228 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章