范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

一个Python报表自动化实战案例

  给大家分享新书 《对比Excel,轻松学习Python报表自动化》 中关于报表自动化实战的一篇内容。
  本篇文章将带你了解报表自动化的流程,并教你用Python实现工作中的一个报表自动化实战,篇幅较长,建议先收藏,文章具体的目录为:
  1.Excel的基本组成
  2.一份报表自动化的流程
  3.报表自动化实战
  - 当日各项指标同环比情况
  - 当日各省份创建订单量情况
  - 最近一段时间创建订单量趋势
  4.将不同的结果进行合并
  - 将不同结果合并到同一个Sheet中
  - 将不同结果合并到同一个工作簿的不同Sheet中   Excel的基本组成
  我们一般在最开始做报表的时候,基本都是从Excel开始的,都是利用Excel在做报表,所以我们先了解下Excel的基本组成。
  下图是Excel的中各个部分的组成关系,我们工作中每天会处理很多Excel文件,一个Excel文件其实就是一个工作簿。你在每次新建一个Excel文件时,文件名都会默认是工作簿x,其中x就是你新建的文件个数。而一个工作簿里面又可以有多个Sheet,不同Sheet之间是一个独立的表。每一个Sheet里面又由若干个单元格组成。每一个单元格又有若干的元素或属性,我们一般针对Excel文件进行设置最多的其实就是针对单元格的元素进行设置。
  而针对单元格元素进行设置的主要内容其实就是如下图菜单栏中显示,比如字体、对齐方式、条件格式等内容。本书也是按照Excel菜单栏中的各个模块进行编写。
  一份自动化报表的流程
  下图是我整理的做一份自动化报表需要经历的流程,主要分为5个步骤:
  第一步是对要做的报表进行步骤拆解,这个步骤拆解和用不用工具或者是用什么工具没有直接关系,比如做报表的第一步一般都是收集数据,这个数据可能是线下人员记录在纸质笔记本上的,也可能是存储在Excel表里面的,还有可能是存储在数据库里面的。会因为数据源的类型或者是存储方式不同,对应的收集数据方式会不一样,但是收集数据这个步骤本身是不会变的,这个步骤的目的就是把数据收集过来。
  第二步是去想第一步里面涉及到的每一个具体步骤对应的代码实现方式,一般都是去找对应每一步的代码,比如导入数据的代码是什么样的,再比如重复值删除的代码是什么样的。
  第三步是将第二步中各个步骤对应的代码进行组合,组合成一个完整的代码。
  第四步是对第三步完整代码得出来的报表结果进行验证,看结果是否正确。
  第五步就是等待调用,看什么时候需要制作报表了,然后就将写好的代码执行一遍就行。
  其实报表自动化本质上就是 让机器代替人工做事情的过程 ,我们只需要把我们人工需要做的每一个步骤转化成机器可以理解的语言,也就是代码,然后让机器自动去执行,这其实就是实现了自动化。 报表自动化实战
  这一节给大家演示下在实际工作中如何结合Pandas和openpyxl来自动化生成报表。
  假设我们现在有如下一份数据集:
  现在我们需要根据这份数据集来制作每天的日报情况,会主要包含三方面:  当日各项指标的同环比情况;  当日各省份创建订单量情况;  最近一段时间创建订单量趋势
  接下来分别来实现这三部分。  当日各项指标的同环比情况:
  我们先用Pandas对数据进行计算处理,得到各指标的同环比情况,具体实现代码如下:  #导入文件 import pandas as pd df = pd.read_excel(r"D:Data-Scienceshareexcel-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
  运行上面代码会得到如下结果:
  上面只是得到了各指标的同环比绝对数值,但是我们一般的日报在发出去之前都要做一些格式调整的,比如调整字体之类的。而格式调整就需要用到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-Scienceshareexcel-python报表自动化核心指标_原始.xlsx")
  运行上面代码会得到如下结果,可以看到原始的数据文件看起来是很混乱的:
  接下来我们针对上面原始数据文件进行格式调整,具体调整代码如下:  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)      #第二行是空的,删除第二行 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-Scienceshareexcel-python报表自动化核心指标.xlsx")
  运行上面代码会得到如下结果:
  可以看到各项均已设置成功。  当日各省份创建订单量情况:
  我们同样先利用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
  运行上面代码会得到如下结果:
  在得到各省份当日创建订单量的绝对数值之后,同样对其进行格式设置,具体设置代码如下:  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",                     color="FF638EC6", 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-Scienceshareexcel-python报表自动化各省份销量情况.xlsx")
  运行上面代码会得到如下结果:
  最近一段时间创建订单量趋势:
  一般用折线图的形式反映某个指标的趋势情况,我们前面也讲过,在实际工作中我们一般用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-Scienceshareexcel-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-Scienceshareexcel-python报表自动化4.2 - 4.11 创建订单量分日趋势.png")  ws.add_image(img, "A1")  wb.save(r"D:Data-Scienceshareexcel-python报表自动化4.2 - 4.11 创建订单量分日趋势.xlsx")
  运行上面代码会得到如下结果,可以看到图表已经被成功插入到Excel中:
  将不同的结果进行合并
  上面我们是把每一部分都单独拆开来实现,最后存储在了不同的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默认是从第一行开始插入的,而我们前面几行已经有df_view表的数据了,所以就不能用appen的方式进行插入,而只能通过遍历每一个单元格的方式进行插入。
  那我们怎么知道要遍历哪些单元格呢?核心需要知道遍历开始的行列和遍历结束的行列。  遍历开始的行 = 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 = 1 + j).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行,即2 + 2 + 1 = 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] + 6 + i,column = 1 + j).value = df_province.iloc[i,j]
  接下来就该插入图片了,插入图片的方式与前面单独的插入是一致的,具体代码如下:  #插入图片 img = Image(r"D:Data-Scienceshareexcel-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",                     color="FF638EC6", 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中:
  将不同的结果合并到同一工作簿的不同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-Scienceshareexcel-python报表自动化4.2 - 4.11 创建订单量分日趋势.png")  ws2.add_image(img, "A1")  wb.save(r"D:Data-Scienceshareexcel-python报表自动化多结果合并_多Sheet.xlsx")
  运行上面代码,会得到如下结果,可以看到创建了3个Sheet,且不同的内容保存到了不同Sheet中:
  到这里我们的一份自动化报表的代码就完成了,以后每次需要用到这份报表的时候,把上面代码执行一遍,结果马上就可以出来,当然了也可以设置定时执行,到时间结果就自动发送到你邮箱里面啦。
  来源:俊红的数据分析之路
  作者:张俊红

从比尔盖茨乔布斯到扎克伯格,马斯克,从他们身上看到了什么?比尔盖茨乔布斯扎克伯格马斯克这些名字罗列在一起,大家很自然地想到了超级富豪,想到了几千亿的身家。看过他们传记的人,还为他们神奇的经历和荒诞的思想所吸引,被他们的奋斗精神打动,对他们小米OPPOvivo,一大波新机蓄势待发双十一已经过去,小米OPPOvivo好像都关起门来偷偷搞事情,貌似风平浪静,实则危机四伏!一小米当然是小米12系列了,好像还有个mini版,但首发骁龙898(暂且还叫898吧捂脸)华为mate40Pro用了一年,如今换成小米MIX4,心里憋了好多话要说华为mate40Pro是目前华为在售手机中最高端的5G旗舰,作为一名忠实的花粉,我在去年第一时间抢购了一台作为自己的主力手机使用,虽然今年华为又发布了P50系列,但是我还是依然在使特斯拉首款手机大曝光!这是要逼死iPhone啊看标题,你们惊讶吗?反正我不惊讶。大家也知道,现在各大手机厂商,都在准备跨界造新能源汽车,甚至连量产的时间都算好了。已经有消息就有苹果小米oppo这么多造手机的厂商依仗着自己的科技5GAI给日常生活增彩来源人民网人民日报海外版大圣版5G云端智能服务机器人在2021中国移动全球合作伙伴大会上亮相。海外网付勇超摄走进AI家庭,将操作行为转化成声音信号,可以实现对家用电器的全智能操控踏德生最便宜的中波收音机M10型在跳蚤市场以5块钱的价格购买了一台不知道是几手的德胜M10型高灵敏度中波收音机,5251610波段,电压3V,AA电池两节,开始以为这个是一个古董或者说以为是一个上个世纪的年代产品cpu和gpu的区别是什么?GPU是显卡吗?cpu和gpu的区别是什么?GPU是显卡吗?CPU,在电脑中起着控制计算机运行的作用,是电脑的中央处理器。GPU是一个附属型的处理器,主要处理计算机中与图形计算有关的工作,并将数据纸箱疯狂诞生中国第一个女首富,电商一年要发百亿件图片来源电商在线,此图片只做内容说明2006年,玖龙纸业在香港联交所敲钟。创办者张茵以72的股份,270亿元身家击败黄光裕,成为当年胡润富豪榜首富。胡润称她为世界上最富有的女白手起用小米watchs1对标华为watchGt2pro亦或是watchgt3?基本上是同样的功能以及内置ui外形都不尽相同,但是小米却比华为便宜了很多,而且在各项功能上S1都要优于GT2最新出的华为watchGT3压力很大啊华为watchGT2Pro在拼夕夕阿里做手机,华为做支付,哪个更难?阿里做过手机,不算失败,但肯定没成功,所以阿里做手机很难。华为在做支付,华为钱包可以申请HuaweiCard,凭借智能手机保有量,华为做支付不难。阿里在早期打造过YUNos系统,不大V对比折叠屏华为OPPO三星各有特点,这些优缺点得知道在今年折叠屏迎来了新的拐点,前不久OPPO发布了首款折叠屏FindN以成熟的生态更丰富的功能成为了当下折叠屏的焦点。而作为横向折叠的产品人们不自觉的会将OPPOFindN与华为推出
扣丁学堂PHP培训之BeanbunPHP编写技术一名专业的PHP开发工程师必须要有过硬的技术水平,本篇文章扣丁学堂小编就和大家分享一个PHP开发工程师必须了解的技术BeanbunPHP编写的多进程网络爬虫框架。扣丁学堂PHP培训学习JavaEE开发技术对学历有要求吗JavaEE的应用近几年大家已经看到了,JavaEE的发展也是不可限量的,因此现在想要学习JavaEE的人不断的增加,那么想要学习JavaEE的话对学历有什么要求吗?是否需要参加J8大理由告诉你,入行IT为啥建议你首选Java美团王兴曾说2019年可能会是过去十年里最差的一年,却是未来十年里最好的一年。随着5G技术物联网云计算大数据人工智能的发展和普及,计算机专业又一次被推上了就业的高峰。一线城市对优秀蓝炬星集成灶好用吗?看完这些理由你就明白了随着人们对美食的需求越来越高,人们对厨房的品质要求也越来越高,从注重饮食逐渐向注重烹饪体验转移,并且由大厨房迅速发展到缩小厨电的空间使用率,提升厨房的使用感下厨的幸福感以及环境的舒2021年笔记本电脑推荐大学生程序员日常办公在大学刚入学的时候,很多小伙伴对于自己是不是需要电脑,需要什么类型的电脑还不是多清楚。为大家更新整理了一份笔记本电脑选购指南,大家根据自己的情况,选择购买哦一预算和需求这个是选购电如果鸿蒙OS是AndroidOpenSourceProject套壳,为啥谷歌不告华为?1,鸿蒙套壳AOSP是合法的,也是合理的!AOSP本身就是套壳Linux发展起来的,AOSP里面的大量代码本身就是来自其他开源社区,所以麻烦不要把AOSP当做google的私有财产净利润大增7倍,云南这家国企换将,去年薪酬约58万高管动态在担任云煤能源总经理副董事长将满两年时间,王炳海卸任了公司所有职务。云煤能源(600792)最新公告称,王炳海因工作变动原因申请辞去在公司第八届董事会中担任的副董事长董事及华夏银行最年长监事辞职,去年薪酬近214万,人均超过37万高管动态华夏银行11月4日晚间发布一项人事变动。孙彤军因年龄原因,辞去华夏银行(600015)职工监事职务以及监事会相关委员会委员的职务。资料显示,孙彤军出生于1961年,现年60浅谈Python中人工智能的详细介绍目前,人工智能这个被一时间带火的热词,已成为当下最火热的产业之一,从苹果Siri到谷歌的AlphaGo等,AI的大规模运用,将给当下的社会生产力带来爆炸式的增长,我们曾经憧憬的未来松下空调1。5匹R1新一级和R3新三级能效对比拆机松下空调一级能效和三级能效区别有多大,这次拆下松下R系列空调对比看下。R系列是松下最便宜的入门款变频空调,R1是新一级能效,R3是新三级能效,这次拆的都是1。5匹挂机。松下空调命名拆大金空调EMAX5J系列1。5匹新三级体积小静音好大家好,这个月拆了几台大金1。5匹新二级新三级的空调,基本上把产品不同能效的配置搞明白了。今天先发大金EMAX5J新三级的拆机,EMAX5J在大金内部称为J系列,和小鑫系列一同,是