如何用Python复制Excel合并单元格?批量处理文件报错求助
解决方案:批量复制Excel指定区域(含合并单元格)
为什么不用pandas?
pandas擅长处理表格数据,但对Excel的格式(尤其是合并单元格、单元格样式)支持有限,复制带格式的区域时容易丢失合并状态或报错,这种场景用openpyxl更合适——它能直接操作Excel的单元格属性和合并区域,精准保留格式。
实现代码
import os from openpyxl import load_workbook from openpyxl.utils import column_index_from_string, get_column_letter # 配置核心参数 INTERIMS_FOLDER = "./Interims" FINALS_FOLDER = "./Finals" SOURCE_SHEET = "Financial Report Interim Mar 10" TARGET_SHEET = "Final Financial Report July 7" # 替换为你要复制的源区域,比如"A1:C15" SOURCE_RANGE = "A1:C10" # 替换为目标工作表的起始粘贴位置,比如"A1" TARGET_START = "A1" # 解析单元格坐标为行列数字 def parse_cell(cell_str): col_str = "" row_str = "" for c in cell_str: if c.isalpha(): col_str += c.upper() else: row_str += c return column_index_from_string(col_str), int(row_str) # 解析起始位置 target_col, target_row = parse_cell(TARGET_START) # 解析源区域的起止坐标 start_cell, end_cell = SOURCE_RANGE.split(":") src_start_col, src_start_row = parse_cell(start_cell) src_end_col, src_end_row = parse_cell(end_cell) # 遍历Interims文件夹下的Excel文件 for filename in os.listdir(INTERIMS_FOLDER): if not filename.endswith((".xlsx", ".xlsm")): continue src_path = os.path.join(INTERIMS_FOLDER, filename) target_path = os.path.join(FINALS_FOLDER, filename) # 跳过不存在的目标文件 if not os.path.exists(target_path): print(f"跳过:目标文件 {filename} 不存在") continue try: # 打开源文件(可读写)和目标文件(可读写) src_wb = load_workbook(src_path) target_wb = load_workbook(target_path) # 检查工作表是否存在 if SOURCE_SHEET not in src_wb.sheetnames: print(f"跳过:源文件 {filename} 无 {SOURCE_SHEET} 工作表") src_wb.close() target_wb.close() continue if TARGET_SHEET not in target_wb.sheetnames: print(f"跳过:目标文件 {filename} 无 {TARGET_SHEET} 工作表") src_wb.close() target_wb.close() continue src_ws = src_wb[SOURCE_SHEET] target_ws = target_wb[TARGET_SHEET] # 1. 复制单元格的值和样式 for row_offset in range(src_end_row - src_start_row + 1): for col_offset in range(src_end_col - src_start_col + 1): src_cell = src_ws.cell(row=src_start_row + row_offset, column=src_start_col + col_offset) tgt_cell = target_ws.cell(row=target_row + row_offset, column=target_col + col_offset) # 复制值 tgt_cell.value = src_cell.value # 复制样式(可选,不需要可删除以下行) tgt_cell.font = src_cell.font.copy() tgt_cell.fill = src_cell.fill.copy() tgt_cell.border = src_cell.border.copy() tgt_cell.alignment = src_cell.alignment.copy() # 2. 处理合并单元格 for merged_range in src_ws.merged_cells.ranges: # 判断合并区域是否在待复制范围内 if (merged_range.min_row >= src_start_row and merged_range.max_row <= src_end_row and merged_range.min_col >= src_start_col and merged_range.max_col <= src_end_col): # 计算目标区域的坐标 new_min_row = target_row + (merged_range.min_row - src_start_row) new_max_row = target_row + (merged_range.max_row - src_start_row) new_min_col = target_col + (merged_range.min_col - src_start_col) new_max_col = target_col + (merged_range.max_col - src_start_col) # 在目标表创建合并区域 target_ws.merge_cells(start_row=new_min_row, start_column=new_min_col, end_row=new_max_row, end_column=new_max_col) # 保存并关闭文件 target_wb.save(target_path) print(f"完成:{filename}") src_wb.close() target_wb.close() except Exception as e: print(f"出错:{filename} - {str(e)}") # 确保出错时关闭文件 try: src_wb.close() target_wb.close() except: pass
关键说明
- 合并单元格处理:先复制所有单元格的内容和样式,再遍历源表的合并区域,判断是否在指定复制范围内,最后在目标表对应位置创建合并区域,完美保留合并状态。
- 参数配置:根据实际路径修改
INTERIMS_FOLDER、FINALS_FOLDER,根据需求调整SOURCE_RANGE和TARGET_START。 - 异常防护:加入文件/工作表不存在的检查,以及通用异常捕获,避免单个文件出错导致批量任务中断。
注意事项
- 确保目标文件未被其他程序占用(比如Excel打开状态),否则会保存失败。
- 若源文件是
.xls格式,需替换为xlrd库读取,但建议统一使用.xlsx格式以获得更好的兼容性。 - 样式复制为可选操作,若不需要保留格式,可删除样式复制代码块以提升处理速度。
内容的提问来源于stack exchange,提问作者Howdy
相关产品推荐
相关产品推荐

