You need to enable JavaScript to run this app. Pandas v1.2.2搭配openpyxl加载ExcelWriter触发BadZipFile报错
优惠活动
大模型
产品
解决方案
定价
更多

Pandas v1.2.2搭配openpyxl加载ExcelWriter触发BadZipFile报错

问题成因
  • 核心入参不匹配:load_workbook()要求传入的入参是磁盘上已存在的合法.xlsx文件路径、或指向已完整生成的xlsx文件的可读文件对象。你代码中传入的writer是Pandas的ExcelWriter对象,既不是有效文件路径也不是可读xlsx文件句柄,openpyxl内部解析时会将其按文件来源处理,尝试用zip格式读取时就会触发zipfile.BadZipFile: File is not a zip file报错。
  • 操作时序错位:在Pandas v1.2.2版本中,基于openpyxl引擎的ExcelWriter在进入上下文块时,仅会初始化空白文件句柄,不会生成xlsx文件本质的zip目录结构;必须等完成数据写入、退出上下文触发保存流程后,落盘的文件才是符合规范的可读取xlsx文件。在上下文块内、文件结构未生成时就尝试读取,本身逻辑不成立。
  • 报错为连锁触发:首先在with块内传入错误入参调用load_workbook,抛出BadZipFile;异常触发了with上下文的退出流程,ExcelWriter执行自动保存时,因为全程没有创建任何可见工作表、写入任何数据,openpyxl的保存校验逻辑触发了第二阶段的IndexError: At least one sheet must be visible,后者的堆栈会显示在控制台输出的末尾,造成多层报错的观感。
解决方案
  • 通用注意点:无论什么场景,都不要在pd.ExcelWriter的上下文块内,调用load_workbook()加载当前正在写入的目标文件,此时文件尚未完成合法结构写入,必然读取失败。
    根据实际使用场景选择对应实现:
  • 场景1:写入完数据后,需要后续用openpyxl编辑已保存的文件
    先完整走完Pandas的写入、保存流程,确保文件完全落盘后,再调用load_workbook()加载文件。示例实现:
    import pandas as pd
    from openpyxl import load_workbook
    
    # 先完整完成Pandas写入、保存流程
    with pd.ExcelWriter("test.xlsx", engine="openpyxl") as writer:
        # 必须写入数据,生成至少一个有效工作表
        pd.DataFrame({"sample_col": [1, 2, 3]}).to_excel(writer, sheet_name="raw_data")
    
    # 文件完全落盘后再加载
    wb = load_workbook("test.xlsx")
    
  • 场景2:在Pandas写入流程中,直接用openpyxl的能力编辑工作簿,避免重复读写磁盘
    不需要额外调用load_workbook(),直接通过ExcelWriter实例的book属性,拿到Pandas内部已经初始化好的openpyxl工作簿对象操作即可。示例实现:
    import pandas as pd
    
    with pd.ExcelWriter("test.xlsx", engine="openpyxl") as writer:
        # 先写入基础数据
        pd.DataFrame({"sample_col": [1, 2, 3]}).to_excel(writer, sheet_name="raw_data")
        # 直接复用Pandas初始化好的工作簿实例,不要重复加载
        wb = writer.book
        # 自定义编辑操作,比如新增工作表、调整格式
        custom_sheet = wb.create_sheet("edited_sheet")
        custom_sheet["A1"] = "自定义写入的内容"
    

内容的提问来源于stack exchange,提问作者Andi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 04:45:04