You need to enable JavaScript to run this app. Python 3.9环境下Pandas导出DataFrame到xlsx的openpyxl报错咨询
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.9环境下Pandas导出DataFrame到xlsx的openpyxl报错咨询

报错根因
  • 升级后的pandas对ExcelWriter的初始化逻辑做了两项关键调整:
    1. 实例化ExcelWriter时如果采用默认的w(覆盖写入)模式,会立即在目标路径创建一个空的占位文件,覆盖原有文件内容,该空文件无合法xlsx(本质为规范zip压缩包)格式结构
    2. 废弃了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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 09:36:03