
給大家分享新書《對比Excel,輕松學習Python報表自動化》中關于報表自動化實戰的一篇內容。
本篇文章將帶你了解報表自動化的流程,并教你用Python實現工作中的一個報表自動化實戰,篇幅較長,建議先收藏,文章具體的目錄為:
1.Excel的基本組成
2.一份報表自動化的流程
3.報表自動化實戰
- 當日各項指標同環比情況
- 當日各省份創建訂單量情況
- 最近一段時間創建訂單量趨勢
4.將不同的結果進行合并
- 將不同結果合并到同一個Sheet中
- 將不同結果合并到同一個工作簿的不同Sheet中
我們一般在最開始做報表的時候,基本都是從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中的難點在于不同表結果的結構不一樣,而且需要在不同結果之間進行留白。
首先插入核心指標表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插入數據即可,具體實現代碼如下:
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中:
到這里我們的一份自動化報表的代碼就完成了,以后每次需要用到這份報表的時候,把上面代碼執行一遍,結果馬上就可以出來,當然了也可以設置定時執行,到時間結果就自動發送到你郵箱里面啦。
來源:俊紅的數據分析之路
作者:張俊紅
數據分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
CDA數據分析師證書考試體系(更新于2025年05月22日)
2025-05-26解碼數據基因:從數字敏感度到邏輯思維 每當看到超市貨架上商品的排列變化,你是否會聯想到背后的銷售數據波動?三年前在零售行 ...
2025-05-23在本文中,我們將探討 AI 為何能夠加速數據分析、如何在每個步驟中實現數據分析自動化以及使用哪些工具。 數據分析中的AI是什么 ...
2025-05-20當數據遇見人生:我的第一個分析項目 記得三年前接手第一個數據分析項目時,我面對Excel里密密麻麻的銷售數據手足無措。那些跳動 ...
2025-05-20在數字化運營的時代,企業每天都在產生海量數據:用戶點擊行為、商品銷售記錄、廣告投放反饋…… 這些數據就像散落的拼圖,而相 ...
2025-05-19在當今數字化營銷時代,小紅書作為國內領先的社交電商平臺,其銷售數據蘊含著巨大的商業價值。通過對小紅書銷售數據的深入分析, ...
2025-05-16Excel作為最常用的數據分析工具,有沒有什么工具可以幫助我們快速地使用excel表格,只要輕松幾步甚至輸入幾項指令就能搞定呢? ...
2025-05-15數據,如同無形的燃料,驅動著現代社會的運轉。從全球互聯網用戶每天產生的2.5億TB數據,到制造業的傳感器、金融交易 ...
2025-05-15大數據是什么_數據分析師培訓 其實,現在的大數據指的并不僅僅是海量數據,更準確而言是對大數據分析的方法。傳統的數 ...
2025-05-14CDA持證人簡介: 萬木,CDA L1持證人,某電商中廠BI工程師 ,5年數據經驗1年BI內訓師,高級數據分析師,擁有豐富的行業經驗。 ...
2025-05-13CDA持證人簡介: 王明月 ,CDA 數據分析師二級持證人,2年數據產品工作經驗,管理學博士在讀。 學習入口:https://edu.cda.cn/g ...
2025-05-12CDA持證人簡介: 楊貞璽 ,CDA一級持證人,鄭州大學情報學碩士研究生,某上市公司數據分析師。 學習入口:https://edu.cda.cn/g ...
2025-05-09CDA持證人簡介 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度、美團、阿里等 ...
2025-05-07相信很多做數據分析的小伙伴,都接到過一些高階的數據分析需求,實現的過程需要用到一些數據獲取,數據清洗轉換,建模方法等,這 ...
2025-05-06以下的文章內容來源于劉靜老師的專欄,如果您想閱讀專欄《10大業務分析模型突破業務瓶頸》,點擊下方鏈接 https://edu.cda.cn/g ...
2025-04-30CDA持證人簡介: 邱立峰 CDA 數據分析師二級持證人,數字化轉型專家,數據治理專家,高級數據分析師,擁有豐富的行業經驗。 ...
2025-04-29CDA持證人簡介: 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度,美團,阿里等 ...
2025-04-28CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-27數據分析在當今信息時代發揮著重要作用。單因素方差分析(One-Way ANOVA)是一種關鍵的統計方法,用于比較三個或更多獨立樣本組 ...
2025-04-25CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-25