影刀RPA新手教程:多Excel文件合并完全指南——按列合并、去重汇总与格式统一化实战
影刀RPA新手教程:多Excel文件合并完全指南——按列合并、去重汇总与格式统一化实战
本文作者:林焱 | 转载请注明出处
开篇案例:12个部门的Excel,合并完格式全乱了
今年初做一个项目,要把12个分公司的月度报表合并成一张总表。
每个分公司的Excel格式都一样(都是人力资源部发的模板),我想当然地用影刀的"合并Excel"指令一键合并。
合并完打开一看:第3列在第5个文件里变成了日期格式,第7列的数字变成了科学计数法,表头行数还不统一(有的分公司多了一行说明文字)。
原因是:虽然用了模板,但各分公司填的时候,Excel自动把某些列的格式给改了。
比如某分公司在"工号"列里填了"00123",Excel自动把前面的0去掉了,格式也从文本变成了数字。
这次经历让我明白:合并Excel之前,一定要先统一格式,否则合并完还要花更多时间清洗。
本文所有案例,围绕"12个分公司月度报表合并"这条真实业务线展开。
模块一:安装与准备工作
合并多个Excel,推荐用Python的pandas库。
安装:pip install pandas openpyxl
pandas的concat和merge功能非常强大,比影刀自带指令灵活很多。
如果你还没配置好Python环境,参考 home.linyan.cloud 上的安装教程。
新建流程,命名为"多Excel合并Demo"。
模块二:元素定位(从网页下载多个Excel)
多个Excel往往需要从网页后台批量下载。
比如:每个月要在后台选12个分公司,分别点"导出",下载12个Excel。
批量下载的实现
importtime# 伪代码,对应影刀的循环+点击指令forbranchin["北京","上海","广州","深圳",...]:# 选择分公司select_branch(branch)# 点击导出click_export()# 等待下载完成time.sleep(3)更高效的做法:用API批量导出
如果后台有API,可以一次请求导出所有分公司的数据,不需要逐个点击。
用影刀的"发送HTTP请求"指令,或者Python的requests库。
模块三:变量与数据类型(合并时的数据类型冲突)
合并多个Excel时,最常见的问题是:同一列在不同文件里的数据类型不一样。
拼多多店群自动化上架方案
比如:
- 文件1的"工号"列是文本(“00123”)
- 文件2的"工号"列是数字(123)
合并时pandas会尝试自动推断类型,可能导致数据丢失(前面的0被去掉)。
解决方法:读取时强制指定类型
importpandasaspddefread_excel_with_types(filepath,type_map):""" 读取Excel,强制指定列类型 type_map: {"列名": "str"} # 强制工号列为字符串 """df=pd.read_excel(filepath,dtype=type_map)returndf# 用法type_map={"工号":str,"手机号":str,# 手机号必须是字符串,否则前面的0会丢"身份证号":str,# 同理}df=read_excel_with_types("北京分公司.xlsx",type_map)我当时踩过这个坑:合并完才发现工号前面的0全没了,只好重新处理一遍。
模块四:流程控制(合并流程的标准结构)
多Excel合并的标准流程:
1. 扫描文件夹,获取所有Excel文件路径 2. 对每一个文件: 2.1 检查文件是否完整(能正常打开) 2.2 读取数据,统一格式 2.3 检查必要列是否存在 2.4 追加到总表 3. 对总表进行去重和清洗 4. 保存合并结果 5. 生成合并报告(每个文件的行数、合并后总行数、去重情况)在影刀里,步骤1用"获取文件列表"指令,步骤2用循环,步骤3-4用Python代码,步骤5用写入Excel指令。
模块五:网页自动化(结合Excel合并)
有些场景不需要先下载Excel再合并,可以直接在网页上抓取所有分公司的数据,存到一个Excel里。
这样就跳过了"合并"这一步。
判断该不该先下载再合并
- 如果数据量小(每个文件不到1000行),直接在网页上抓,存到一个Excel里。
- 如果数据量大,或者网页有反爬,先导出再合并。
模块六:数据处理——按列合并(横向合并)
"按列合并"是指:两个表的行数相同,把它们的列拼在一起。
比如:表A有"工号、姓名",表B有"部门、职位",按工号对齐后合并成一张表。
importpandasaspddefmerge_excel_horizontal(file1,file2,output_path,key_column):""" 横向合并两个Excel(类似VLOOKUP,但是用pandas做) """df1=pd.read_excel(file1)df2=pd.read_excel(file2)# 用merge横向合并result=pd.merge(df1,df2,on=key_column,how="left")result.to_excel(output_path,index=False)print(f"横向合并完成:{file1}+{file2}->{output_path}")print(f"结果:{len(result)}行,{len(result.columns)}列")多文件横向合并(按相同列名自动对齐)
importpandasaspdimportglobdefmerge_multiple_excel_horizontal(file_pattern,output_path,key_column):""" 多个Excel按key_column横向合并 适用于:每个文件是一个月的销售数据,要合并到一张表里 """files=glob.glob(file_pattern)print(f"找到{len(files)}个文件")# 读取第一个文件作为基准result=pd.read_excel(files[0])# 逐个横向合并forfilepathinfiles[1:]:df=pd.read_excel(filepath)result=pd.merge(result,df,on=key_column,how="outer",suffixes=("",f"_{get_month_from_filename(filepath)}"))result.to_excel(output_path,index=False)print(f"多文件横向合并完成,结果保存到:{output_path}")模块七:数据处理——纵向合并(追加行)
"纵向合并"是最常用的:把多个结构相同的Excel拼成一个,就是把行追加起来。
importpandasaspdimportglobdefmerge_excel_vertical(file_pattern,output_path):""" 纵向合并多个Excel(追加行) file_pattern: 如 "C:/Reports/分公司*.xlsx" """files=glob.glob(file_pattern)print(f"找到{len(files)}个Excel文件")all_dfs=[]file_rows={}# 记录每个文件的行数forfilepathinfiles:try:df=pd.read_excel(filepath)file_rows[filepath]=len(df)# 加一列"来源文件",方便追溯df["_来源文件"]=filepath.split("\\")[-1]all_dfs.append(df)print(f"已读取:{filepath}({len(df)}行)")exceptExceptionase:print(f"读取失败:{filepath},错误:{e}")# 纵向合并result=pd.concat(all_dfs,ignore_index=True)# 保存result.to_excel(output_path,index=False)# 打印报告print(f"\n=== 合并报告 ===")print(f"输入文件数:{len(files)}")print(f"合并前行数:{sum(file_rows.values())}")print(f"合并后行数:{len(result)}")print(f"结果保存到:{output_path}")returnresult模块八:数据处理——去重汇总
合并完后,可能有重复行(比如某个分公司的数据被导出了两次)。
importpandasaspddefdeduplicate_and_summarize(df,key_columns):""" 去重并汇总 key_columns: 用于去重的列(如 ["工号"] 或 ["工号", "月份"]) """print(f"去重前列数:{len(df)}")# 去重(保留第一次出现)df_dedup=df.drop_duplicates(subset=key_columns,keep="first")print(f"去重后行数:{len(df_dedup)}")print(f"删除了{len(df)-len(df_dedup)}条重复数据")# 汇总统计(以数值列为例)numeric_cols=df_dedup.select_dtypes(include=["number"]).columnsiflen(numeric_cols)>0:print("\n=== 数值列汇总 ===")print(df_dedup[numeric_cols].sum())returndf_dedup模块九:鼠标键盘与图像操作(处理加密Excel)
合并时遇到加密Excel,需要先解密。
如果是"打开密码",可以用以下方法批量去除(需要知道密码):
fromopenpyxlimportload_workbookdefremove_password_batch(file_list,password,output_dir):""" 批量去除Excel打开密码 注意:这个方法只适用于知道密码的情况 不知道密码的情况需要用专业工具 """importos os.makedirs(output_dir,exist_ok=True)forfilepathinfile_list:try:# openpyxl无法直接处理有打开密码的文件# 需要用msoffcrypto-toolimportmsoffcrypto decrypted_path=os.path.join(output_dir,os.path.basename(filepath))withopen(filepath,"rb")asf:office_file=msoffcrypto.OfficeFile(f)ifoffice_file.is_encrypted():withopen(decrypted_path,"wb")asout:office_file.decrypt(password,out)print(f"已解密:{filepath}")else:# 没有加密,直接复制importshutil shutil.copy(filepath,decrypted_path)exceptExceptionase:print(f"解密失败:{filepath},错误:{e}")安装解密工具:pip install msoffcrypto-tool
模块十:进阶技能
技能一:合并时统一格式
合并前先统一所有文件的格式,避免合并后格式混乱:
fromopenpyxlimportload_workbookdefnormalize_excel_format(filepath,output_path):""" 统一Excel格式:所有列设为文本格式 """wb=load_workbook(filepath)ws=wb.activeforcolinws.columns:forcellincol:# 把单元格格式设为文本cell.number_format="@"wb.save(output_path)print(f"格式已统一:{output_path}")技能二:处理合并单元格
合并Excel时,如果某个文件有合并单元格,读取时会只有左上角有值,其他单元格是空的。
用前面文章里介绍的unmerge_cells函数处理。
技能三:大批量Excel合并(内存优化)
如果Excel文件很多(超过100个),或者每个文件很大,不要一次性读入内存。
用逐文件处理方式:
importpandasaspddefmerge_large_excels(file_pattern,output_path,chunk_size=5000):""" 大批量Excel合并,逐块写入,节省内存 """importglob files=glob.glob(file_pattern)writer=pd.ExcelWriter(output_path,engine="openpyxl")first=Trueforfilepathinfiles:df=pd.read_excel(filepath)iffirst:df.to_excel(writer,index=False,startrow=0)first=Falseelse:# 追加写入,不要表头df.to_excel(writer,index=False,startrow=writer.sheets["Sheet1"].max_row,header=False)writer.close()print(f"大批量合并完成:{output_path}")模块十一:平台实战
把Excel合并流程部署到影刀控制台时,注意以下几点。
要点一:文件路径用配置管理
创建一个merge_config.json:
{"input_dir":"C:/Reports/raw","output_dir":"C:/Reports/merged","file_pattern":"分公司*.xlsx","key_columns":["工号"],"notify_email":"admin@example.com"}流程启动时读取配置,换环境时只改配置文件。
TEMU店群如何管理运营?
要点二:合并完成后自动通知
defsend_merge_notification(result_path,row_count):""" 合并完成后发通知(用影刀的"发送钉钉消息"或"发送邮件"指令) """message=f"Excel合并完成\n结果文件:{result_path}\n总行数:{row_count}"print(f"发送通知:{message}")要点三:用控制台查看合并任务执行状态
在影刀控制台的任务监控页面,可以看到合并任务的执行时长和结果。
如果某次合并特别慢,可能是某个Excel文件格式有问题,需要单独检查。
模块十二:系统联动与工程化规范
工程化规范一:合并前先备份
importshutilimportosfromdatetimeimportdatetimedefbackup_before_merge(input_dir):backup_dir=f"C:/Reports/backup/{datetime.now().strftime('%Y%m%d')}"os.makedirs(backup_dir,exist_ok=True)forfilenameinos.listdir(input_dir):iffilename.endswith(".xlsx"):src=os.path.join(input_dir,filename)dst=os.path.join(backup_dir,filename)shutil.copy(src,dst)print(f"原始文件已备份到:{backup_dir}")工程化规范二:合并报告自动生成
defgenerate_merge_report(files,result_df,output_path):""" 生成合并报告(HTML格式,方便邮件发送) """report=f""" <html> <body> <h2>Excel合并报告</h2> <p>合并时间:{datetime.now()}</p> <p>输入文件数:{len(files)}</p> <p>合并后行数:{len(result_df)}</p> <p>合并后列数:{len(result_df.columns)}</p> <h3>各文件行数</h3> <ul> """forfinfiles:# ... 统计每个文件的行数report+=f" <li>{f}</li>\n"report+="</ul></body></html>"withopen("merge_report.html","w",encoding="utf-8")asf:f.write(report)print("合并报告已生成:merge_report.html")速查表:Excel合并方式选择
| 场景 | 合并方式 | pandas函数 |
|---|---|---|
| 多个相同结构的表 | 纵向合并(追加行) | pd.concat |
| 两个表按关键列关联 | 横向合并(类似VLOOKUP) | pd.merge |
| 按关键字聚合 | 分组汇总 | df.groupby() |
| 去重 | 删除重复行 | df.drop_duplicates() |
报错排查指南
报错:ValueError: Length of values does not match length of index
原因:横向合并时,两个表的行数不对齐。
解决:检查关键列的值是否一一对应,用how="outer"保留所有行。
报错:UnicodeDecodeError when reading Excel
原因:Excel文件损坏或者格式不对。
解决:用Excel手动打开文件,另存为新的xlsx文件,再用pandas读取。
总结
多Excel文件合并,核心要点:合并前先统一格式、用pandas的concat或merge、合并后去重并生成报告。
把这三个步骤做到位,合并出来的数据就不会再有格式问题。
更多Excel合并的高级场景和代码,访问 home.linyan.cloud 获取。
#影刀RPA #RPA教程 #Excel合并 #数据处理 #Pandas
作者:林焱
