使用openpyxl批量合并多组Excel文件时单元格复制失败问题求助
批量合并Excel时单元格复制不全问题排查
问题现象
编写批量循环处理程序,目标是将三组编号一一对应的Excel文件合并为单个输出文件,但程序无法完整复制引用的单元格区域:当参数l=10、m=20时,仅能输出j=1、a=1对应的单元格内容,其余位置无值,异常位置已在代码中标注。
问题根因
代码存在4个核心问题导致复制异常:
- 循环语法错误(核心故障):所有遍历行列的循环都漏写了
range(),比如for i in (1,k+1)实际是遍历仅包含两个元素的元组(1, k+1),只会循环2次,不会遍历1到k+1的所有整数。这直接导致当l=10、m=20时,j只会取1和11两个值、a只会取1和21两个值,仅j=1、a=1对应的位置是有效数据,其余行列根本没进入循环执行写入操作。 - 工作表索引错位:用
openpyxl.Workbook()新建工作簿时,默认会自带1个名为Sheet的空白工作表,循环k次新建工作表后,实际工作表总数是k+1,后续按索引取book.worksheets[i]时会出现索引偏移,遍历到最后一个i值时还会触发索引越界报错。 - 单元格偏移错误:读取源单元格时用了
row=j+1、column=a+1的偏移逻辑,会直接跳过源表的第一行、第一列有效数据,同时循环到最大行/列后再+1会读取到空单元格,覆盖已写入的有效内容。 - 保存逻辑错误:
book.save()写在了最外层文件遍历循环的缩进外部,只会保存最后一次循环生成的文件,前面近700个文件的处理结果都会直接丢失。
修复后可运行代码
# coding: UTF-8 import os import openpyxl # 统计目标文件夹下文件总数 path = r'C:/Users/Files' directory = os.listdir(path) counter = len(directory) # 统计结果显示当前文件总数约700,后续可复用该代码处理其他财年(FY)数据 for iii in range(1, counter+1): # xx1、xx2、xx3三类文件的编号一一对应 # 加data_only参数直接读取单元格计算后的值,避免公式引用失效 xx1 = openpyxl.load_workbook(f'C:/Users/imput1/result1_{iii}.xlsx', data_only=True) xx2 = openpyxl.load_workbook(f'C:/Users/imput2/result2_{iii}.xlsx', data_only=True) xx3 = openpyxl.load_workbook(f'C:/Users/imput3/result3_{iii}.xlsx', data_only=True) xx1_distance = xx1["distance"] # 以下xx1的工作表变量后续逻辑未使用,保留定义 xx1_P=xx1["P"] xx1_Q=xx1["Q"] xx1_W=xx1["W"] xx1_a_collect=xx1["a_collect"] # 第二类结果文件的工作表名使用日语命名 xx2_ana=xx2["解析"] xx2_kakei=xx2["家計"] xx2_ka_moto=xx2["家計元データ"] xx2_douro=xx2["道路面積"] xx2_ins=xx2["焼却場"] xx3_rate=xx3["Rate"] # 确认各工作表行列数,不同文件的行列参数存在差异 k = xx1_distance.max_column - 1 l = xx2_kakei.max_row m = xx2_kakei.max_column l3 = xx3_rate.max_row m3 = xx3_rate.max_column # 新建工作簿,先删除默认生成的空白Sheet避免索引错位 book = openpyxl.Workbook() book.remove(book.active) # 创建首页工作表 sheet1 = book.create_sheet("facility_houseconsumption") rate = dict() kakei = dict() for i in range(1, k+1): ia = book.create_sheet(f"facility_{i}") # 写入表头 ia.cell(row=1, column=1, value="rate") for a in range(1, m+1): ia.cell(row=1, column=a+1, value=xx2_kakei.cell(row=1, column=a).value) # 写入行数据,修正循环范围和偏移量 for j in range(1, l+1): rate_val = xx3_rate.cell(row=j, column=i+1).value ia.cell(row=j+1, column=1, value=rate_val) rate[(i,j)] = rate_val for a in range(1, m+1): kakei_val = xx2_kakei.cell(row=j, column=a).value ia.cell(row=j+1, column=a+1, value=kakei_val) kakei[(i,j,a)] = kakei_val # 保存逻辑移到单文件循环内部,按当前文件编号保存 book.save(f'C:/Users/output/output_{iii}.xlsx') # 关闭打开的工作簿释放内存,避免批量处理时内存溢出 xx1.close() xx2.close() xx3.close()
修复说明
- 所有行列遍历循环补全
range(),确保从1到最大行/列的所有单元格都能被遍历到,解决仅写入第一个单元格的问题。 - 新建工作簿后先删除默认生成的空白Sheet,统一用
create_sheet方法按顺序创建需要的工作表,彻底解决索引错位问题。 - 修正单元格读写的偏移量,源数据从第一行第一列开始读取,不再跳过有效内容,也不会读取到行列外的空值。
- 将文件保存逻辑移到每个编号文件的处理循环内部,每个文件处理完成后立刻按对应编号保存,不会丢失批量处理的结果。
- 增加工作簿关闭操作,批量处理700个文件时及时释放内存,避免程序卡顿。
- 删除了代码中导入的未使用依赖库,避免运行时因缺少无关库报错。
内容的提问来源于stack exchange,提问作者maki
相关产品推荐
相关产品推荐

