影刀RPA Excel模板创建:标准报表模板复用
作者:林焱
什么情况用什么
每周生成格式一样的周报、每月生成结构一样的月报——每次从零开始搭表格太浪费时间。在影刀RPA里可以先创建一个标准模板文件,然后每次只填充数据,格式、公式、图表都自动继承。这比每次用代码重建格式高效得多。
适用场景:周报/月报/季报标准化生成、多部门统一报表格式、自动化报表分发、固定格式的数据导出。
怎么做
创建模板文件
拼多多店群自动化报活动上架!
importopenpyxlfromopenpyxl.stylesimportFont,PatternFill,Alignment,Border,Side,numbersdefcreate_report_template(output_path):"""创建标准报表模板"""wb=openpyxl.Workbook()# ===== Sheet1: 数据明细 =====ws_data=wb.active ws_data.title="数据明细"# 标题行ws_data.merge_cells('A1:F1')ws_data['A1']='销售数据明细报表'ws_data['A1'].font=Font(name='微软雅黑',size=16,bold=True,color='FFFFFF')ws_data['A1'].fill=PatternFill(start_color='1F4E79',end_color='1F4E79',fill_type='solid')ws_data['A1'].alignment=Alignment(horizontal='center',vertical='center')ws_data.row_dimensions[1].height=35# 表头headers=['日期','地区','产品','数量','单价','金额']forcol,headerinenumerate(headers,1):cell=ws_data.cell(row=2,column=col,value=header)cell.font=Font(name='微软雅黑',size=11,bold=True,color='FFFFFF')cell.fill=PatternFill(start_color='4472C4',end_color='4472C4',fill_type='solid')cell.alignment=Alignment(horizontal='center',vertical='center')# 预设公式行(第3行到第1002行)forrowinrange(3,1003):# 金额 = 数量 * 单价ws_data.cell(row=row,column=6).value=f'=IF(AND(D{row}<>"",E{row}<>""),D{row}*E{row},"")'# 数字格式forrowinrange(3,1003):ws_data.cell(row=row,column=4).number_format='#,##0'ws_data.cell(row=row,column=5).number_format='#,##0.00'ws_data.cell(row=row,column=6).number_format='#,##0.00'# 列宽col_widths={'A':12,'B':10,'C':20,'D':10,'E':12,'F':14}forcol,widthincol_widths.items():ws_data.column_dimensions[col].width=width# ===== Sheet2: 汇总统计 =====ws_summary=wb.create_sheet("汇总统计")ws_summary.merge_cells('A1:C1')ws_summary['A1']='汇总统计'ws_summary['A1'].font=Font(name='微软雅黑',size=14,bold=True,color='FFFFFF')ws_summary['A1'].fill=PatternFill(start_color='1F4E79',end_color='1F4E79',fill_type='solid')ws_summary['A1'].alignment=Alignment(horizontal='center',vertical='center')# 统计项summary_items=[('总订单数','=COUNTA(数据明细!C3:C1002)'),('总金额','=SUM(数据明细!F3:F1002)'),('平均金额','=IFERROR(AVERAGE(数据明细!F3:F1002),0)'),('最大金额','=IFERROR(MAX(数据明细!F3:F1002),0)'),('最小金额','=IFERROR(MIN(数据明细!F3:F1002),0)'),]fori,(label,formula)inenumerate(summary_items,2):ws_summary.cell(row=i,column=1,value=label).font=Font(name='微软雅黑',size=11,bold=True)cell=ws_summary.cell(row=i,column=2,value=formula)cell.number_format='#,##0.00'ifi>2else'#,##0'ws_summary.column_dimensions['A'].width=15ws_summary.column_dimensions['B'].width=18# ===== Sheet3: 地区分析 =====ws_region=wb.create_sheet("地区分析")ws_region['A1']='地区'ws_region['B1']='订单数'ws_region['C1']='总金额'regions=['北京','上海','广州','深圳','成都','杭州']fori,regioninenumerate(regions,2):ws_region.cell(row=i,column=1,value=region)ws_region.cell(row=i,column=2,value=f'=COUNTIF(数据明细!B:B,A{i})')ws_region.cell(row=i,column=3,value=f'=SUMIF(数据明细!B:B,A{i},数据明细!F:F)')# 保存模板wb.save(output_path)returnoutput_path# 创建模板create_report_template(r"C:\Templates\sales_report_template.xlsx")使用模板填充数据
importshutilimportopenpyxlimportpandasaspddeffill_template(template_path,data_df,output_path):"""用模板生成报表"""# 1. 复制模板shutil.copy2(template_path,output_path)# 2. 打开复制的模板wb=openpyxl.load_workbook(output_path)ws=wb['数据明细']# 3. 填充数据(从第3行开始)foridx,rowindata_df.iterrows():excel_row=idx+3ws.cell(row=excel_row,column=1,value=row['日期'])ws.cell(row=excel_row,column=2,value=row['地区'])ws.cell(row=excel_row,column=3,value=row['产品'])ws.cell(row=excel_row,column=4,value=row['数量'])ws.cell(row=excel_row,column=5,value=row['单价'])# 金额列有公式,不用手动填# 4. 保存wb.save(output_path)returnoutput_path# 读取数据df=pd.read_excel(r"C:\Data\july_sales.xlsx")df=df[['日期','地区','产品','数量','单价']]# 用模板生成报表fill_template(template_path=r"C:\Templates\sales_report_template.xlsx",data_df=df,output_path=r"C:\Reports\2026年7月销售报表.xlsx")模板版本管理
importosfromdatetimeimportdatetimedefgenerate_versioned_report(template_path,data_df,output_dir,report_name):"""生成带版本号的报表"""# 确保输出目录存在os.makedirs(output_dir,exist_ok=True)# 生成带日期的文件名date_str=datetime.now().strftime('%Y%m%d_%H%M%S')filename=f"{report_name}_{date_str}.xlsx"output_path=os.path.join(output_dir,filename)# 用模板填充fill_template(template_path,data_df,output_path)returnoutput_path# 使用output=generate_versioned_report(template_path=r"C:\Templates\sales_report_template.xlsx",data_df=df,output_dir=r"C:\Reports\历史版本",report_name="销售月报")多模板选择
defselect_template(report_type):"""根据报表类型选择模板"""templates={'daily':r"C:\Templates\daily_report.xlsx",'weekly':r"C:\Templates\weekly_report.xlsx",'monthly':r"C:\Templates\monthly_report.xlsx",'quarterly':r"C:\Templates\quarterly_report.xlsx",}ifreport_typenotintemplates:raiseValueError(f"不支持的报表类型:{report_type}")ifnotos.path.exists(templates[report_type]):raiseFileNotFoundError(f"模板文件不存在:{templates[report_type]}")returntemplates[report_type]# 在影刀流程中# 【设置变量】report_type = "monthly"# 【执行Python代码】选择模板并填充template=select_template('monthly')fill_template(template,df,output_path)有什么坑
坑1:模板中的公式不自动计算
openpyxl写入数据后,模板里的公式不会自动重新计算,需要在Excel中打开后才会更新:
# 问题:填充数据后,汇总统计的值还是0# 因为openpyxl不计算公式# 解决1:用win32com触发计算importwin32com.client excel=win32com.client.Dispatch("Excel.Application")wb=excel.Workbooks.Open(output_path)excel.CalculateFull()# 强制重新计算所有公式wb.Save()wb.Close()excel.Quit()# 解决2:用data_only=False读取,在Python中算好值直接写入# 而不是依赖Excel公式坑2:shutil.copy2复制后文件损坏
某些情况下复制模板后文件打不开:
TEMU店群矩阵自动化运营核价报活动
# 问题:模板文件正被其他程序占用shutil.copy2(template_path,output_path)# 可能报错# 解决:先关闭模板文件,或用openpyxl另存wb=openpyxl.load_workbook(template_path)wb.save(output_path)# 用openpyxl另存更安全坑3:模板数据行数不够
模板预设了1000行公式,但实际数据有1500行:
# 解决:动态扩展公式行defensure_formula_rows(ws,template_last_row,needed_row,formula_col=6):"""确保公式行数足够"""ifneeded_row<=template_last_row:return# 获取模板公式template_formula=ws.cell(row=template_last_row,column=formula_col).value# 扩展公式forrowinrange(template_last_row+1,needed_row+1):# 替换行号formula=template_formula.replace(str(template_last_row),str(row))ws.cell(row=row,column=formula_col).value=formula# 复制格式ws.cell(row=row,column=formula_col).number_format='#,##0.00'坑4:模板中的图表引用失效
模板里做了图表,填充数据后图表数据源不对了:
# openpyxl对图表的支持有限,建议用win32com操作# 或者在模板中把图表数据源设为整个列(如A:A),而不是固定行范围# 另一个方案:用Python直接生成图表,不依赖模板importmatplotlib.pyplotasplt fig,ax=plt.subplots(figsize=(8,5))df.groupby('地区')['金额'].sum().plot(kind='bar',ax=ax,color='#4472C4')ax.set_title('各地区销售额')ax.set_ylabel('金额(元)')plt.tight_layout()plt.savefig(r"C:\Reports\chart.png",dpi=150)# 然后把图片插入Excelws=wb['地区分析']ws.add_image(openpyxl.drawing.image.Image(r"C:\Reports\chart.png"),'E2')坑5:多用户同时使用模板冲突
多个影刀流程同时用同一个模板生成报表,文件锁冲突:
# 解决:每个流程先复制模板到临时目录importtempfileimportuuiddefsafe_fill_template(template_path,data_df,output_path):"""安全的模板填充"""# 复制到临时文件temp_dir=tempfile.gettempdir()temp_template=os.path.join(temp_dir,f"template_{uuid.uuid4().hex}.xlsx")shutil.copy2(template_path,temp_template)try:# 用临时模板填充fill_template(temp_template,data_df,output_path)finally:# 清理临时文件ifos.path.exists(temp_template):os.remove(temp_template)returnoutput_path