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

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

时间: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进行报表自动化的内容,欢迎阅读本书!

    推荐阅读
  • 常喝可乐的人后来都怎么样了(坚持喝4万多瓶可乐)

    舌尖上跳跃的味道,直接将郑大爷征服了。在可乐的长期腐蚀下,郑大爷口腔变成了酸性,此外还患有严重的骨质疏松,糖尿病也在向他招手,但是郑大爷根本不在乎。以上的行为,基本上都是“异食癖”的患者。不仅味道诱人,对健康的伤害也不容小觑。但是不能当作常规的饮品,长期食用不仅会造成肥胖,还会患上骨质疏松,损害到肾脏。喝牛奶可以提升自身的免疫力,补充所需的蛋白质,抵御感染疾病的风险。

  • 12月1日北碚区关于调整疫情风险区的通告

    北碚区关于调整疫情风险区的通告为高效统筹疫情防控和经济社会发展,按照《新型冠状病毒肺炎防控方案(第九版)》相关规定,经专家研判和北碚区新型冠状病毒肺炎疫情防控指挥部研究,报请市疫情防控指挥部批准,决定自2022年12月1日22时起,调整69个高风险区(或点位)为低风险区。聚集性活动继续暂停,密闭空间娱乐场所暂不开放;3.后续管理措施根据疫情形势适时动态调整。未尽事宜,以北碚区新冠肺炎疫情防控指挥部解释为准。

  • NBA全明星赛制(具体介绍)

    我们一起去了解并探讨一下这个问题吧!NBA全明星赛制NBA全明星赛的赛制,在第二节开始和第三节开始时,比分将会自动清零,也就是说,前三节的每一节都是0-0开始,每节比赛仍然将打12分钟。每一节比赛的胜出者将会为所代表的社区组织赢得10万美元的善款。到了末节,现场计时器将关闭,比赛进入不计时决战,将设立一个目标分数,哪支球队达标,哪支球队获胜。

  • 立春发朋友圈的早安问候语(关于立春的句子有哪些)

    立春发朋友圈的早安问候语春的味道越来越浓,立春的温暖悄悄降临,带来春天温暖的阳光,带来春天美丽的季节。立春节气来到了,发条短信祝福你,祝你生活春风得意,祝你事业春意昂然,祝你爱情春暖花开,祝你年年春光明媚,立春节气祝你春色满园!立春时节,乍暖还寒,一份关怀,贴心送暖;一句问候,快乐忘忧;一声祝福,情谊浓浓;一个短信,开怀无比。祝您立春愉快,天天开心!

  • 美术生校考选设计还是造型(什么是造型和设计)

    造型学为纯艺术专业,大致有以下专业方向:雕塑、绘画、美术。设计性专业的范围更广这是大多数同学上大学后会走的一条路,相对来说设计专业是艺术与商业的结合,所以实用性和适用性要优于纯艺术的专业。总体而言,设计行业更受欢迎,平均工资相对较高。

  • 鲜百合苦怎么处理才行(新鲜百合苦怎么处理)

    鲜百合苦怎么处理才行想除去鲜百合的苦涩味,先把百合一瓣瓣的扒开,随后再把每一瓣表层的皮都除去。在一个菜盘里边添加适量的凉水,把百合放下去侵泡两个小时,随后再捞出来凉干水份,放进锅里边用火烧开,再改为文火渐渐地的煮开。在酷热的夏天适度的吃一些百合是很好的,百合是一种滋养的食材,能够做到清肺热润肺阴的功效,并且可以清热解毒益心,这类配搭方式吃起來就不容易苦。

  • 五年级人教版上册语文园地4预习(四年级语文上册语文园地五课文笔记)

    爸爸买来了生日蛋糕,妈妈准备了香喷喷的饭菜。两个孩子祝奶奶“生日快乐”,奶奶高兴得合不拢嘴。*观察家人炒菜、擦玻璃或者做其他家务的过程,用段话把这个过程写下来,注意用上表示动作的词语。概括《小木船》这篇文章的主要内容。文章以“小木船”为线索写了和“我”和陈明之间友谊的建立、破裂和恢复的过程。

  • 菊花枸杞茶能天天喝吗(能随时当水喝吗)

    但不是每个人都适合喝枸杞菊花茶,脾胃虚寒之人经常饮用此茶,会导致腹泻等不适症状。很多上班族办公桌上必备一杯枸杞菊花茶,其实,过量饮用对健康反而有害。《中国药典》对枸杞、菊花的用量是有明确规定的,过量饮用枸杞菊花茶有可能伤害人体阳气。过度追求其治疗功效,也是不正确的。

  • 弱组词(弱的解释)

    下面内容希望能帮助到你,我们来一起看看吧!

  • 成人mba报考条件(成人mba报考条件有哪些)

    成人mba报考条件中华人民共和国公民。拥护中国党的领导,愿为社会主义现代化建设服务,品德良好,遵纪守法。考生的学历必须符合下列条件之一:具有国家承认的大学本科毕业学历后,有三年或三年以上工作经历者。已获硕士、博士学位,并有两年或两年以上工作经历者。得国家承认的大专毕业学历后,有五年或五年以上工作经历身体健康,符合规定的体检标准。此外,各校还可能在教育部门规定的MBA报考条件基础上制定本校的报考条件。