openpyxl无法直接用append()拼接不同工作簿的行,因其只接受python原生数据(如list/tuple),不支持worksheet行对象;正确做法是逐单元格读取value并写入目标表,注意跳过空行、处理合并单元格、避免permissionerror及格式丢失。

直接合并多个 Excel 文件的 sheet 数据,openpyxl 本身不提供“一键批量合并”函数,必须手动加载、遍历、复制单元格值——但只要避开它不支持写入已打开文件、不维护公式/样式等限制,完全可行。
为什么不能用 append() 直接拼接不同工作簿的行?
append() 只接受 Python 原生数据(如 list 或 tuple),不能传入另一个 Worksheet 对象的行对象。试图写 target_sheet.append(source_row) 会报 TypeError: append() takes only one argument 或更隐蔽的 Cell is not in worksheet 错误。
- 正确做法是逐单元格读取
source_cell.value,再写入目标表对应位置 - 注意跳过空行:检查
row[0].value is None不够,得用all(cell.value is None for cell in row) - 如果源表有合并单元格,
openpyxl读取时只在左上角单元格返回值,其余为None,需额外处理worksheet.merged_cells.ranges
如何安全加载多个文件并避免 PermissionError?
Windows 下常见错误:PermissionError: [Errno 13] Permission denied,通常是因为某个 Excel 文件正被 Excel 进程或其它 Python 进程占用。这不是代码问题,而是系统级锁。
- 确保所有待合并文件未在 Excel 中打开,也未被
openpyxl.load_workbook(..., keep_vba=True)以外的方式加载过 - 用
try/except包裹load_workbook(),失败时打印具体文件路径,方便排查 - 不要复用同一个
Workbook实例:每个文件都应调用独立的load_workbook(filename) - 加载后立即调用
wb.close()(尤其在循环中),否则可能触发资源泄漏
合并时要不要保留原表头?怎么控制起始行?
多数场景下,你只需要第一张表的表头,后续表跳过首行。但 openpyxl 没有“跳过前 N 行”的内置参数,必须手动控制行索引。
- 初始化一个
target_row = 1计数器;对第一个文件,从第 1 行开始复制;对其余文件,从第 2 行开始复制 - 写入时用
target_sheet.cell(row=target_row, column=col_idx, value=cell.value),比append()更可控 - 如果列数不一致(比如某些表少一列),
cell.value会是None,可设默认值:or "",但要注意数字0和空字符串的区别 - 时间格式、数字精度可能丢失——
openpyxl读取时把日期转成datetime对象,写回时默认按 Excel 默认格式显示,不保留原始格式字符串
真正麻烦的不是循环读写,而是跨文件的合并单元格、条件格式、图表、VBA 宏——这些 openpyxl 全都不支持复制。如果原始文件依赖这些特性,合并后得人工补救。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











