Python 3.9环境下Pandas导出DataFrame到xlsx的openpyxl报错咨询
报错根因
- 升级后的pandas对
ExcelWriter的初始化逻辑做了两项关键调整:- 实例化
ExcelWriter时如果采用默认的w(覆盖写入)模式,会立即在目标路径创建一个空的占位文件,覆盖原有文件内容,该空文件无合法xlsx(本质为规范zip压缩包)格式结构 - 废弃了
writer.save()方法,原逻辑中直接调用该方法会出现兼容性问题
- 实例化
- 原函数的执行流程存在时序错误:先以默认覆盖模式初始化
ExcelWriter实例,该操作已经清空了原有目标文件、生成了空占位文件,后续再调用load_workbook(filename)读取时,读到的是完全为空的无效文件,直接触发zipfile.BadZipFile报错。 - 该问题在目标文件不存在、目标文件已存在两种场景下都会触发。
修复方案
核心调整点:
- 调整执行时序,先判断目标文件的存在状态,存在时优先加载原有工作簿
- 初始化
ExcelWriter时根据文件状态指定读写模式:文件存在时用a(追加)模式打开,避免原文件被覆盖清空;文件不存在时用w(新建)模式创建 - 适配新版pandas的接口规范,替换废弃方法,增加资源释放逻辑,避免文件句柄占用
- 完全保留原函数的入参结构与核心能力,原有的调用代码无需做任何修改
修复后可直接运行的代码
import os import pandas as pd from openpyxl import load_workbook def append_df_to_excel(filename, df, sheet_name='Sheet1', startrow=None, truncate_sheet=False, **to_excel_kwargs): # 移除传入的重复engine参数 if 'engine' in to_excel_kwargs: to_excel_kwargs.pop('engine') # 先判断目标文件是否存在 file_exists = os.path.isfile(filename) writer = None try: # 如果文件存在,先加载已有工作簿,避免被新生成的空占位文件覆盖 if file_exists: book = load_workbook(filename) # 以追加模式初始化Writer,避免清空原文件 writer = pd.ExcelWriter( filename, engine='openpyxl', mode='a' ) writer.book = book writer.sheets = {ws.title: ws for ws in book.worksheets} # 自动计算起始行:未指定startrow时取已有sheet的最后一行 if startrow is None and sheet_name in writer.book.sheetnames: startrow = writer.book[sheet_name].max_row # 处理sheet截断逻辑 if truncate_sheet and sheet_name in writer.book.sheetnames: idx = writer.book.sheetnames.index(sheet_name) writer.book.remove(writer.book.worksheets[idx]) writer.book.create_sheet(sheet_name, idx) else: # 文件不存在时以新建模式初始化Writer writer = pd.ExcelWriter(filename, engine='openpyxl', mode='w') # 未指定起始行时默认从第0行开始 if startrow is None: startrow = 0 # 将DataFrame写入指定位置 df.to_excel(writer, sheet_name, startrow=startrow, **to_excel_kwargs) finally: # 确保Writer资源正常释放、文件保存 if writer is not None: writer.close() # 测试示例代码 pathExport = r"F:\PYTHON\NB-Suite_python39\MNE\outputData\df.xlsx" df1 = pd.DataFrame({'numbers': [1, 2, 3], 'colors': ['red', 'white', 'blue'], 'colorsTwo': ['yellow', 'white', 'blue'] }) append_df_to_excel(pathExport, df1, sheet_name="DF1", index=False, startcol=0, startrow=0)
运行说明
- 替换代码中的
pathExport为本地实际导出目录即可运行 - 该代码兼容pandas 1.2.3及以上所有版本、openpyxl 3.0.6及以上所有版本,无需回退原有包版本
- 完全保留原函数的核心能力:自动从已有sheet的最后一行追加DataFrame内容、支持自定义起始行/起始列、支持截断重建sheet
内容的提问来源于stack exchange,提问作者Baggio
相关产品推荐
相关产品推荐

