调用已关闭文件close()触发UserWarning,仅能保存最后一个Excel工作表
问题分析与解决
问题根源
- 工作表被覆盖:循环内每次新建
pd.ExcelWriter时,默认使用mode='w'(写入模式),会直接覆盖原有文件,导致前三次生成的工作表被第四次操作清空,最终只剩最后一个工作表。 - 重复关闭警告:
with语句块会自动完成writer的保存与关闭操作,你在块外额外调用writer.save(),属于对已关闭文件执行操作,触发了警告。
修正后的代码
import openpyxl from os import path import pandas as pd def load_workbook(wb_path): if path.exists(wb_path): return openpyxl.load_workbook(wb_path) return openpyxl.Workbook() wb_path = './output/trail.xlsx' wb = load_workbook(wb_path) # 避免用list作为变量名(Python内置类型) company_codes = [530001, 530011, 530017, 530023] # 将ExcelWriter初始化移至循环外,启用追加模式 with pd.ExcelWriter(wb_path, engine='openpyxl', mode='a', if_sheet_exists='replace') as writer: writer.book = wb # 关联已加载的工作簿,防止覆盖原有内容 for item in company_codes: url_1 = f'https://www.screener.in/company/{item}/' df0 = pd.read_html(url_1) data1 = df0[1] data1.to_excel(writer, sheet_name=str(item), startcol=0, startrow=1, index=False)
关键改动说明
- 循环外初始化ExcelWriter:使用
mode='a'开启追加模式,指定engine='openpyxl'(pandas默认的xlsxwriter不支持追加),同时通过writer.book = wb关联已加载的工作簿,确保原有内容不会被清空。 if_sheet_exists参数:设置为'replace'时,若工作表已存在会自动替换;若需保留旧版本,可改为'new'生成新工作表。- 移除多余的
writer.save():with块结束时会自动完成保存和关闭操作,无需手动调用。 - 变量名优化:将
list改为company_codes,避免与Python内置的list类型冲突。
内容的提问来源于stack exchange,提问作者dixi trivedi
相关产品推荐
相关产品推荐

