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
相关产品推荐
相关产品推荐

