Python实现报表自动化生成与邮件发送全流程
本文详细介绍如何利用Python实现报表自动化流程,涵盖从数据源读取、DataFrame计算、统计指标处理到图表生成的全过程。重点讲解使用Matplotlib和Echarts绘制可视化图表,并通过smtplib与email模块实现报表自动打包及发送至指定邮箱的功能,旨在提升数据分析效率并减少人工操作错误。
项目背景
作为数据分析师,日常工作中涉及大量的统计分析图表制作。当报表数量庞大时,手动制作往往占据大量时间,从而挤占了深入挖掘数据背后关联信息的时间。数据分析师的核心价值在于洞察数据背后的逻辑,而非单纯地制表。既然报表制作是必要环节,我们应利用技术手段优化这一流程。通过开发Python自动化脚本,让程序自动执行报表生成任务,从而释放人力专注于高价值的数据分析工作。这一过程即被称为报表自动化。
一、报表自动化目的
1.节省时间,提高效率
自动化脚本能显著节省时间并提升工作效率。通过降低代码模块间的耦合度,使程序更易于维护。这将为我们节省大量时间,使我们能够专注于更有价值的工作内容。
2.减少错误
经过验证的代码可以重复使用且结果稳定,而人工操作容易因疲劳或疏忽产生错误。将任务交给固定程序处理更加可靠。当需求发生变更时,只需修改相关代码片段即可适应新情况,无需重新执行整个流程。
二、报表自动化范围
首先,需根据业务需求确定需要自动化的报表类型。并非所有报表都适合自动化,部分涉及复杂二次开发的指标数据,其自动化实现难度较大且可能引入潜在Bug。因此,需对工作中常用的报表特性进行归纳,综合考虑以下因素:
1.频率
对于业务中高频使用的报表,如客户信息清单、销售额流量报表、业务流失报表、环比同比报表等,应纳入自动化程序的范围。


高频使用的报表非常有必要进行自动化处理。而对于偶尔使用、涉及二次开发指标或仅需简单复制统计的报表,则无需实现自动化。
2.开发时间
这类似于成本与收益的权衡。如果某些报表的自动化实现难度大,且开发脚本所耗费的时间超过人工制作报表的时间,则无需实现自动化。在启动自动化工作前,需评估开发脚本时间与人工制表时间的长短。本文提供的方案仅适用于常用且简单的报表场景。
3.流程
不同公司的报表处理流程和步骤存在差异。我们需要根据具体的业务场景编码实现各个步骤的功能,确保制作的流程符合业务逻辑,程序运行也符合逻辑规范。

三、实现步骤
首先明确所需的统计指标:
指标
- 总体概览指标
反映某一数据指标的整体规模大小。
- 对比性指标
- 环比
计算相邻时间段内指标的差值。
- 同比
对比相邻时间段内同一特定时间点的指标。
- 集中趋势指标
- 中位数
- 众数
- 平均数/加权平均数
- 离散程度指标
- 标准差
- 方差
- 四分位数
- 全距(极差)
- 最大界减最小界
- 相关性指标
- r

接下来,我们将通过一个简单报表的模拟实现来展示具体操作:
第一步:读取数据源文件
首先需明确数据来源,即数据源。最终的数据处理均转化为DataFrame格式进行分析,因此需要将数据源转换为DataFrame形式:
import pandas as pd
import json
import pymysql
from sqlalchemy import create_engine
# 打开数据库连接
conn = pymysql.connect(host='localhost',
port=3306,
user='root',
passwd='xxxx',
charset = 'utf8'
)
engine=create_engine('mysql+pymysql://root:xxxx@localhost/mysql?charset=utf8')
def read_excel(file):
df_excel=pd.read_excel(file)
return df_excel
def read_json(file):
with open(file,'r')as json_f:
df_json=pd.read_json(json_f)
return df_json
def read_sql(table):
sql_cmd ='SELECT * FROM %s'%table
df_sql=pd.read_sql(sql_cmd,engine)
return df_sql
def read_csv(file):
df_csv=pd.read_csv(file)
return df_csv以上代码均通过测试可以正常使用,但是pandas的read函数针对不同的形式的文件读取,其read函数参数也有不同的含义,需要直接根据表格的形式来调整。
其他read函数将会在文章写完之后后续补上,除了read_sql需要连接数据库之外,其他的都是比较简单的。
第二步:DataFrame计算
我们以用户信息为例:

我们需要统计的指标为:
#指标说明
单表图:
前十个产品受众最多的地区
#将城市空值的一行删除
df=df[df['city_num'].notna()]
#删除error
df=df.drop(df[df['city_num']=='error'].index)
#统计 df = df.city_num.value_counts()
我们仅获取前10名的城市就好了,封装为饼图:
def pie_chart(df):
#将城市空值的一行删除
df=df[df['city_num'].notna()]
#删除error
df=df.drop(df[df['city_num']=='error'].index)
#统计
df = df.city_num.value_counts()
df.head(10).plot.pie(subplots=True,figsize=(5, 6),autopct='%.2f%%',radius = 1.2,startangle = 250,legend=False)
pie_chart(read_csv('user_info.csv'))
将图表保存起来:
plt.savefig('fig_cat.png')要是你觉得matplotlib的图片不太美观的话,你也可以换成echarts的图片,会更加好看一些:
pie = Pie()
pie.add("",words)
pie.set_global_opts(title_opts=opts.TitleOpts(title="前十地区"))
#pie.set_series_opts(label_opts=opts.LabelOpts(user_df))
pie.render_notebook()
封装后就可以直接使用了:
def echart_pie(user_df):
user_df=user_df[user_df['city_num'].notna()]
user_df=user_df.drop(user_df[user_df['city_num']=='error'].index)
user_df = user_df.city_num.value_counts()
name=user_df.head(10).index.tolist()
value=user_df.head(10).values.tolist()
words=list(zip(list(name),list(value)))
pie = Pie()
pie.add("",words)
pie.set_global_opts(title_opts=opts.TitleOpts(title="前十地区"))
#pie.set_series_opts(label_opts=opts.LabelOpts(user_df))
return pie.render_notebook()
user_df=read_csv('user_info.csv')
echart_pie(user_df)可以进行保存,可惜不是动图:
from snapshot_selenium import snapshot
make_snapshot(snapshot,echart_pie(user_df).render(),"test.png")保存为网页的形式就可以自动加载JS进行渲染了:
echart_pie(user_df).render('problem.html')
os.system('problem.html')
第三步:自动发送邮件
生成的一系列报表通常需要发送给相关人员。对于需要每日发送指定邮箱或多封报表的场景,可以使用Python自动发送邮件。
在Python发送邮件主要借助到smtplib和email这个两个模块。
- smtplib:主要用来建立和断开与服务器连接的工作。
- email:主要用来设置一些些与邮件本身相关的内容。
不同种类的邮箱服务器连接地址不一样,大家根据自己平常使用的邮箱设置相应的服务器进行连接。这里博主用网易邮箱展示:
首先需要开启POP3/SMTP/IMAP服务:

之后便可以根据授权码使用python登入了。
import smtplib
from email import encoders
from email.header import Header
from email.utils import parseaddr,formataddr
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
#发件人邮箱
asender="fanstuck@163.com"
#收件人邮箱
areceiver="1079944650@qq.com"
#抄送人邮箱
acc="fanstuck@163.com"
#邮箱主题
asubject="谢谢关注"
#发件人地址
from_addr="fanstuck@163.com"
#邮箱授权码
password="####"
#邮件设置
msg=MIMEMultipart()
msg['Subject']=asubject
msg['to']=areceiver
msg['Cc']=acc
msg['from']="fanstuck"
#邮件正文
body="你好,欢迎关注fanstuck,您的关注就是我继续创作的动力!"
msg.attach(MIMEText(body,'plain','utf-8'))
#添加附件
htmlFile = 'C:/Users/10799/problem.html'
html = MIMEApplication(open(htmlFile , 'rb').read())
html.add_header('Content-Disposition', 'attachment', filename='html')
msg.attach(html)
#设置邮箱服务器地址和接口
smtp_server="smtp.163.com"
server = smtplib.SMTP(smtp_server,25)
server.set_debuglevel(1)
#登录邮箱
server.login(from_addr,password)
#发生邮箱
server.sendmail(from_addr,areceiver.split(',')+acc.split(','),msg.as_string())
#断开服务器连接
server.quit()运行测试:

下载文件:

完全没问题!!!
以上就是基于Python实现报表自动化并发送到邮箱的详细内容,更多关于Python报表自动化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













