肥宅钓鱼网
当前位置: 首页 钓鱼百科

报表制作最快方法(实战如何制作数据报表并实现自动化)

时间:2023-06-14 作者: 小编 阅读量: 1 栏目名: 钓鱼百科

本章给大家演示一下在实际工作中如何结合Pandas库和openpyxl库来自动化生成报表。当日各项指标的同/环比情况。当日各省份创建订单量情况。而格式调整需要用到openpyxl库,我们将Pandas库中DataFrame格式的数据转化为适用openpyxl库的数据格式,具体实现代码如下。(图4)可以看到各项均已设置成功。

本章给大家演示一下在实际工作中如何结合 Pandas 库和 openpyxl 库来自动化生成报表。假设我们现在有如图 1 所示的数据集。

(图1)

现在需要根据这份数据集来制作每天的日报情况,主要包含以下 3 个方面。

  • 当日各项指标的同/环比情况。
  • 当日各省份创建订单量情况。
  • 最近一段时间创建订单量趋势。

接下来分别实现。

01、当日各项指标的同/环比情况

我们先用 Pandas 库对数据进行计算处理,得到各指标的同/环比情况,具体实现代码如下。

#导入文件 import pandas as pd df = pd.read_excel(r'D:\Data-Science\share\excel-python 报表自动化 \sale_data.xlsx') #构造同时获取不同指标的函数 def get_data(date): create_cnt = df[df['创建日期'] == date]['order_id'].count() pay_cnt = df[df['付款日期'] == date]['order_id'].count() receive_cnt = df[df['收货日期'] == date]['order_id'].count() return_cnt = df[df['退款日期'] == date]['order_id'].count() return create_cnt,pay_cnt,receive_cnt,return_cnt #假设当日是 2021-04-11 #获取不同时间段的各指标值 df_view = pd.DataFrame([get_data('2021-04-11') ,get_data('2021-04-10') ,get_data('2021-04-04')] ,columns = ['创建订单量','付款订单量','收货订单量','退款订单量'] ,index = ['当日','昨日','上周同期']).T df_view['环比'] = df_view['当日'] / df_view['昨日'] - 1 df_view['同比'] = df_view['当日'] / df_view['上周同期'] - 1 df_view

运行上面代码会得到如图 2 所示结果。

(图2)

上面只是得到了各指标的同/环比绝对数值,但是日报在发出去之前一般都要做一些格式调整,比如调整字体。而格式调整需要用到 openpyxl 库,我们将 Pandas 库中DataFrame 格式的数据转化为适用 openpyxl 库的数据格式,具体实现代码如下。

from openpyxl import Workbook from openpyxl.utils.dataframe import dataframe_to_rows #创建空工作簿 wb = Workbook() ws = wb.active #将 DataFrame 格式数据转化为 openpyxl 格式 for r in dataframe_to_rows(df_view,index = True,header = True): ws.append(r) wb.save(r'D:\Data-Science\share\excel-python 报表自动化\核心指标_原始.xlsx')

运行上面代码会得到如图 3 所示结果,可以看到原始的数据文件看起来是很混乱的。

(图3)

接下来,对上面的原始数据文件进行格式调整,具体调整代码如下。

from openpyxl import Workbook from openpyxl.utils.dataframe import dataframe_to_rows from openpyxl.styles import colors from openpyxl.styles import Font from openpyxl.styles import PatternFill from openpyxl.styles import Border, Side from openpyxl.styles import Alignment wb = Workbook() ws = wb.active for r in dataframe_to_rows(df_view,index = True,header = True): ws.append(r) #第 2 行是空的,删除第 2 行 ws.delete_rows(2) #给 A1 单元格进行赋值 ws['A1'] = '指标' #插入一行作为标题行 ws.insert_rows(1) ws['A1'] = '电商业务方向 2021/4/11 日报' #将标题行的单元格进行合并 ws.merge_cells('A1:F1') #合并单元格#对第 1 行至第 6 行的单元格进行格式设置 for row in ws[1:6]: for c in row: #字体设置 c.font = Font(name = '微软雅黑',size = 12) #对齐方式设置 c.alignment = Alignment(horizontal = "center") #边框线设置 c.border = Border(left = Side(border_style = "thin",color = "FF000000"), right = Side(border_style = "thin",color = "FF000000"), top = Side(border_style = "thin",color = "FF000000"), bottom = Side(border_style = "thin",color = "FF000000")) #对标题行和表头行进行特殊设置 for row in ws[1:2]: for c in row: c.font = Font(name = '微软雅黑',size = 12,bold = True,color = "FFFFFFFF") c.fill = PatternFill(fill_type = 'solid',start_color ='FFFF6100') #将环比和同比设置成百分比格式 for col in ws["E":"F"]: for r in col: r.number_format = '0.00%' #调整列宽 ws.column_dimensions['A'].width = 13 ws.column_dimensions['E'].width = 10 #保存调整后的文件 wb.save(r'D:\Data-Science\share\excel-python 报表自动化\核心指标.xlsx')

运行上面代码会得到如图 4 所示结果。

(图4)

可以看到各项均已设置成功。

02、当日各省份创建订单量情况

我们同样先利用 Pandas 库处理得到当日各省份创建订单量的情况,具体实现代码如下。

df_province = pd.DataFrame(df[df['创建日期'] == '2021-04-11'].groupby('省份 ')['order_id'].count()) df_province = df_province.reset_index() df_province = df_province.sort_values(by = 'order_id',ascending = False) df_province = df_province.rename(columns = {'order_id':'创建订单量'}) df_province

运行上面代码会得到如图 5 所示结果。

(图5)

在得到各省份当日创建订单量的绝对数值之后,同样对其进行格式设置,具体设置代码如下。

from openpyxl import Workbook from openpyxl.utils.dataframe import dataframe_to_rows from openpyxl.styles import colors from openpyxl.styles import Font from openpyxl.styles import PatternFill from openpyxl.styles import Border, Side from openpyxl.styles import Alignment from openpyxl.formatting.rule import DataBarRule wb = Workbook() ws = wb.active for r in dataframe_to_rows(df_province,index = False,header = True): ws.append(r) #对第 1 行至第 11 行的单元格进行设置 for row in ws[1:11]: for c in row: #字体设置 c.font = Font(name = '微软雅黑',size = 12) #对齐方式设置 c.alignment = Alignment(horizontal = "center") #边框线设置 c.border = Border(left = Side(border_style = "thin",color = "FF000000"), right = Side(border_style = "thin",color = "FF000000"), top = Side(border_style = "thin",color = "FF000000"), bottom = Side(border_style = "thin",color = "FF000000")) #设置进度条条件格式 rule = DataBarRule(start_type = 'min',end_type = 'max', , showValue=True, minLength=None, maxLength= None) ws.conditional_formatting.add('B1:B11',rule) #对第 1 行标题行进行设置 for c in ws[1]: c.font = Font(name = '微软雅黑',size = 12,bold = True,color = "FFFFFFFF") c.fill = PatternFill(fill_type = 'solid',start_color='FFFF6100') #调整列宽 ws.column_dimensions['A'].width = 17 ws.column_dimensions['B'].width = 13 #保存调整后的文件 wb.save(r'D:\Data-Science\share\excel-python 报表自动化\各省份销量情况.xlsx')

运行上面代码会得到如图6所示结果。

(图6)

03、最近一段时间创建订单量趋势

一般用折线图反映某个指标的趋势情况,我们前面也讲过,在实际工作中一般用matplotlib 库或者其他可视化库进行图表绘制,并将其保存,然后利用 openpyxl 库将图表插入 Excel 中。

先利用 matplotlib 库进行绘图,具体实现代码如下。

%matplotlib inline import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"]='SimHei'#解决中文乱码 #设置图表大小 plt.figure(figsize = (10,6)) df.groupby('创建日期')['order_id'].count().plot() plt.title('4.2 - 4.11 创建订单量分日趋势') plt.xlabel('日期') plt.ylabel('订单量') #将图表保存到本地 plt.savefig(r'D:\Data-Science\share\excel-python 报表自动化\4.2 - 4.11 创建订单量 分日趋势.png')

将保存到本地的图表插入 Excel 中,具体实现代码如下。

from openpyxl import Workbook from openpyxl.drawing.image import Image wb = Workbook() ws = wb.active img = Image(r'D:\Data-Science\share\excel-python 报表自动化\4.2 - 4.11 创建订单量 分日趋势.png') ws.add_image(img, 'A1') wb.save(r'D:\Data-Science\share\excel-python 报表自动化\4.2 - 4.11 创建订单量分日 趋势.xlsx')

运行上面代码会得到如图 7 所示结果,可以看到图表已经被成功插入 Excel 中。

(图7)

04、将不同的结果进行合并

上面我们是把每一部分都单独拆开来实现的,最后存储在了不同的 Excel 文件中。

当然,有时放在不同文件中会比较麻烦,就需要把这些结果合并在同一个 Excel 的相同 Sheet 或者不同 Sheet 中。

将不同的结果合并到同一个 Sheet 中

将不同的结果合并到同一个 Sheet 中的难点在于不同表结果的结构不一样,而且需要在不同结果之间进行留白。

首先,插入核心指标表 df_review,插入方式与单独插入是一样的,具体代码如下。

for r in dataframe_to_rows(df_view,index = True,header = True): ws.append(r)

然后,插入各省份情况表 df_province,因为 append()方法默认是从第 1 行开始插入的,而我们前面几行已经有 df_view 表的数据了,所以就不能用 append()方法插入,而只能通过遍历每一个单元格的方式。

那我们怎么知道要遍历哪些单元格呢?核心是需要知道遍历开始的行/列和遍历结束的行/列。

遍历开始的行 = df_view 表占据的行留白的行(一般表与表之间留 2 行)1

遍历结束的行 = 遍历开始的行df_province 表占据的行

遍历开始的列 = 1

遍历结束的列 = df_province 表占据的列

又因为 DataFrame 中获取列名的方式和获取具体值的方式不太一样,所以我们需要分别插入,先插入列名,具体代码如下。

for j in range(df_province.shape[1]): ws.cell(row = df_view.shape[0]5,column = 1j).value = df_province.columns[r] df_province.shape[1]表示获取 df_province 表有多少列,df_view.shape[0]表示获取 df_view 表有多少行。

前面说过,遍历开始的行是表占据的行加上留白的行再加 1,一般留白的行是 2,

可是这里为什么是 df_view.shape[0]5 呢?因为 df_view.shape[0]是不包括列名行的,而且在插入 Excel 中时会默认增加 1 行空行,所以需要在留白行的基础上再增加 2 行,

即 221 = 5。

因为 range()函数默认是从 0 开始的,而 Excel 中的列是从 1 开始的,所以 column需要加 1。

上面的代码只是把 df_province 表的列名插入进来,接下来插入具体的值,方式与插入列名的方式一致,只不过需要在列名的下一行开始插入,具体代码如下。

for i in range(df_province.shape[0]): for j in range(df_province.shape[1]): ws.cell(row = df_view.shape[0]6i,column = 1j).value = df_province.iloc[i,j]

接下来,插入图片,插入图片的方式与前面的单独插入方法是一致的,具体代码如下。

#插入图片 img = Image(r'D:\Data-Science\share\excel-python 报表自动化\4.2 - 4.11 创建订单量 分日趋势.png') ws.add_image(img, 'G1')

将所有的数据插入以后就该对这些数据进行格式设置了,因为不同表的结构不一样,所以我们没法直接批量对所有单元格进行格式设置,只能按范围分别进行设置,而不同范围的格式可能是一样的,所以我们先预设一些格式变量,这样后面用到的时候直接调取这些变量即可,减少代码冗余,具体代码如下。

#格式预设 #表头字体设置 title_Font_style = Font(name = '微软雅黑',size = 12,bold = True,color = "FFFFFFFF") #普通内容字体设置 plain_Font_style = Font(name = '微软雅黑',size = 12) Alignment_style = Alignment(horizontal = "center") Border_style = Border(left = Side(border_style = "thin",color = "FF000000"), right = Side(border_style = "thin",color = "FF000000"), top = Side(border_style = "thin",color = "FF000000"), bottom = Side(border_style = "thin",color = "FF000000")) PatternFill_style = PatternFill(fill_type = 'solid',start_color ='FFFF6100')

格式预设完之后就可以对各个范围分别进行格式设置了,具体代码如下。

#对 A1 至 F6 范围内的单元格进行设置 for row in ws['A1':'F6']: for c in row: c.font = plain_Font_style c.alignment = Alignment_style c.border = Border_style #对第 1 行和第 2 行的单元格进行设置 for row in ws[1:2]: for c in row: c.font = title_Font_style c.fill = PatternFill_style #对 E 列和 F 列的单元格进行设置 for col in ws["E":"F"]: for r in col: r.number_format = '0.00%' #对 A9 至 B19 范围内的单元格进行设置 for row in ws['A9':'B19']: for c in row: c.font = plain_Font_style c.alignment = Alignment_style c.border = Border_style #对 A9 至 B9 范围内的单元格进行设置 for row in ws['A9':'B9']: for c in row: c.font = title_Font_style c.fill = PatternFill_style #设置进度条 rule = DataBarRule(start_type = 'min',end_type = 'max', , showValue=True, minLength=None, maxLength=None) ws.conditional_formatting.add('B10:B19',rule) #调整列宽ws.column_dimensions['A'].width = 17 ws.column_dimensions['B'].width = 13 ws.column_dimensions['E'].width = 10

最后,将上面所有代码片段合并在一起,就是将不同的结果文件合并到同一个Sheet 中的完整代码,具体如下。

Sheet 中的完整代码,具体如下。from openpyxl import Workbook from openpyxl.utils.dataframe import dataframe_to_rows from openpyxl.styles import colors from openpyxl.styles import Font from openpyxl.styles import PatternFill from openpyxl.styles import Border, Side from openpyxl.styles import Alignment from openpyxl.formatting.rule import DataBarRule wb = Workbook() ws = wb.active #先将核心指标 df_view 表插入进去 for r in dataframe_to_rows(df_view,index = True,header = True): ws.append(r) #再将各省份情况 df_province 表插入进去 #先将表头插入 for j in range(df_province.shape[1]): ws.cell(row = df_view.shape[0]5,column = 1j).value = df_province.columns[r] #再把具体的值插入 #先遍历行 for i in range(df_province.shape[0]): #再遍历列 for j in range(df_province.shape[1]): ws.cell(row = df_view.shape[0]6i,column = 1j).value = df_province. iloc[i,j] #插入图片 img = Image(r'D:\Data-Science\share\excel-python 报表自动化\4.2 - 4.11 创建订单量 分日趋势.png') ws.add_image(img, 'G1') ##---格式调整--- ws.delete_rows(2) ws['A1'] = '指标' ws.insert_rows(1) ws['A1'] = '电商业务方向 2021/4/11 日报' ws.merge_cells('A1:F1') #合并单元格 #格式预设 #表头字体设置 title_Font_style = Font(name = '微软雅黑',size = 12,bold = True,color = "FFFFFFFF") #普通内容字体设置 plain_Font_style = Font(name = '微软雅黑',size = 12) Alignment_style = Alignment(horizontal = "center") Border_style = Border(left = Side(border_style = "thin",color = "FF000000"), right = Side(border_style = "thin",color = "FF000000"), top = Side(border_style = "thin",color = "FF000000"), bottom = Side(border_style = "thin",color = "FF000000")) PatternFill_style = PatternFill(fill_type = 'solid',start_color='FFFF6100') #对 A1 至 F6 范围内的单元格进行设置 for row in ws['A1':'F6']: for c in row: c.font = plain_Font_style c.alignment = Alignment_style c.border = Border_style #对第 1 行和第 2 行的单元格进行设置 for row in ws[1:2]: for c in row: c.font = title_Font_style c.fill = PatternFill_style #对 E 列和 F 列的单元格进行设置 for col in ws["E":"F"]: for r in col: r.number_format = '0.00%' #对 A9 至 B19 范围内的单元格进行设置 for row in ws['A9':'B19']: for c in row: c.font = plain_Font_style c.alignment = Alignment_style c.border = Border_style #对 A9 至 B9 范围内的单元格进行设置 for row in ws['A9':'B9']: for c in row: c.font = title_Font_style c.fill = PatternFill_style #设置进度条 rule = DataBarRule(start_type = 'min',end_type = 'max', , showValue=True, minLength=None, maxLength= None) ws.conditional_formatting.add('B10:B19',rule) #调整列宽 ws.column_dimensions['A'].width = 17 ws.column_dimensions['B'].width = 13 ws.column_dimensions['E'].width = 10 #将结果文件进行保存 wb.save(r'D:\Data-Science\share\excel-python 报表自动化\多结果合并.xlsx')

运行上面代码,会得到如图 8 所示结果,可以看到不同结果文件合并在了一起,并且各自的格式设置完好。

(图8)

将不同的结果合并到同一工作簿的不同 Sheet 中

将不同的结果合并到同一工作簿的不同 Sheet 中比较好实现,只需要新建几个Sheet,然后对不同的 Sheet 插入数据即可,具体实现代码如下。

from openpyxl import Workbook from openpyxl.utils.dataframe import dataframe_to_rows wb = Workbook() ws = wb.active ws1 = wb.create_sheet() ws2 = wb.create_sheet() #更改 sheet 的名称 ws.title = "核心指标" ws1.title = "各省份销情况" ws2.title = "分日趋势" for r1 in dataframe_to_rows(df_view,index = True,header = True): ws.append(r1) for r2 in dataframe_to_rows(df_province,index = False,header = True): ws1.append(r2) img = Image(r'D:\Data-Science\share\excel-python 报表自动化\4.2 - 4.11 创建订单量 分日趋势.png') ws2.add_image(img, 'A1') wb.save(r'D:\Data-Science\share\excel-python 报表自动化\多结果合并_多 Sheet.xlsx')

运行上面代码,会得到如图 9 所示结果,可以看到创建了 3 个 Sheet,且不同的内容被保存到了不同 Sheet 中。

(图9)

本文节选自《对比Excel,轻松学习Python报表自动化》一书,更多关于使用Python进行报表自动化的内容,欢迎阅读本书!

    推荐阅读
  • 泰迪狗为什么让人讨厌(不少人讨厌的泰迪)

    前几年,泰迪可谓是烂大街,遛狗都能遇上好几只。而且很多女生养狗的话,第一反应也是养一只可爱的泰迪。体型小,也意味着运动量少,二哈一天要运动2个小时,而泰迪最多只需要散步1个小时,超轻松。主人洗发加剪发只要50,而泰迪要200。其实泰迪这种狗狗,真的很适合城市饲养,优点一抓一大把。

  • 胡萝卜生理期可以吃吗(胡萝卜的好处)

    胡萝卜生理期可以吃吗月经期间是可以吃胡萝卜的。胡萝卜营养丰富,胡萝卜中含有丰富的维生素A、胡萝卜素、纤维素等。胡萝卜中的维生素A含量比较高,有利于维护正常的视力;维生素A和胡萝卜素还可以促进皮肤细胞的新陈代谢,延缓皮肤衰老,有美容作用。胡萝卜素具有较强的抗氧化作用,可以有效抑制自由基的活性,减少对细胞膜的伤害,对免疫功能有一定的调节作用。

  • 春兰什么品种好养(春兰什么品种好养易花)

    春兰多有珍品和名品,好养的春兰品种有集圆、西湖梅、天兴梅、桂圆梅、贺神梅、汤梅、祥字、绿英、瑞梅、梁溪梅、宋梅等。春兰什么品种最好春兰品种众多,而且栽培历史悠久,春兰好的品种有宋梅、贺神梅、汤梅、绿英、瑞梅、集圆、余姚第一梅、萧山蔡梅等。春兰余蝴蝶香味如何春兰余蝴蝶香味浓郁,它的花香味幽远、持久,仅次于宋梅,在众多春兰之中,可谓极为出众的闻香型兰花,种养起来也很方便,花色也非常的好看。

  • 男人如何讨好一个女人(男人要想征服一个女人)

    就如同男人喜欢漂亮、身材好的女人一样,女人对有才华的男人,基本上是毫无抵抗力的。樱子就是这样,她和自己的男友谈了两年多,她的男友属于普通的工薪阶层,一个月拿着4千块的薪水。虽说满足不了樱子买奢侈品的向往,但是普通人的生活还是能保证的。樱子一下对他心动了,于是和男友分手,选择了和他在一起。小丽已经有过将近50次的相亲史了,每一次都是因为各种原因拒绝了对方。

  • 金刚狼5电影完全版(电影产业促进法实施让行业迎来了变革的契机)

    据悉,该法律的颁布,旨在促进电影产业健康繁荣发展,弘扬社会主义核心价值观,规范电影市场秩序,丰富人民群众精神文化生活。这一要求不仅仅是针对国务院,而且精准到了县级以上人民政府。若法人、其他组织对专家评审意见存有异议,电影主管部门可另行组织专家再次评审。

  • 入党介绍人发言(入党介绍人发言范文)

    作为同志的培养联系人,我认为该同志在政治思想上能自觉地同以江泽民同志为核心的党中央保持一致,坚持四项基本原则,注意学习马列主义、毛泽东思想、邓小平理论和党的基本知识,对党的认识正确,入党动机端正。思想品德端正,团结同志,对党忠诚老实,为人正派,有为共产主义奋斗终身的决心。用党章规定的标准全面衡量同志,我认为他已具备了共产党员的条件,我愿介绍同志加入中国共产党。

  • 王丽坤受欢迎的电视剧(王丽坤凤凰无双首演重生复仇女)

    下面内容希望能帮助到你,我们来一起看看吧!王丽坤受欢迎的电视剧

  • 脱唇毛的生活小妙招(脱唇毛的方法分享)

    处在生长期毛囊内的黑色素最多,对激光发出的光吸收最强,就成了激光脱毛机的最佳作用目标。激光脱毛的过程简单、快捷,治疗后一般不留疤痕。

  • 大鹅和天鹅有啥区别 天鹅和大鹅有什么区别

    大鹅则是人类驯化野生大雁后的动物,属于家禽。鹅的主要品种有6种,分别为狮头鹅、四川白鹅、乌鬃鹅、太湖鹅、豁眼鹅、莱茵鹅。以四川白鹅为例,在四川白鹅中最出名的是开江白鹅,它的个头比较大,一只鹅差不多有3-4公斤,而且它的毛质好、产毛量高、肉质嫩、产蛋率高、生长较快,它最主要作用是作为羽绒服装加工的优质填充原料。

  • 关于小暑的谚语(关于小暑的句子)

    关于小暑的谚语关于小暑的谚语小暑有雨旱,小寒有雨冷。伏天热得狠,丰收才有准。六月初一,一雷压九台,无雷便是台。大暑小暑,有米懒煮。入伏不种黍和豆。小暑热过头,九月早寒流。小暑热得透,大暑凉悠悠。伏里无雨,谷里无米。蚊虫叮咬不断,飞蝇骚扰难平,骄阳似火难耐,骤雨时常无期,有伞遮阳无伞遮雨,乱七八糟难分难理,还要有我送你祝福,收到短信,注意保持平常心,微笑脸,用平静的心欢度小暑天气。