第二张表覆盖第一张是因为ExcelWriter未保存前多次to_excel()会清空同名sheet或引擎不支持追加;须用with上下文管理、显式指定不同sheet_name,大表优先选xlsxwriter引擎。

用 pd.ExcelWriter 写入多张表时,为什么第二张表覆盖了第一张?
因为没调用 save() 之前,ExcelWriter 是内存中的临时对象,多次 to_excel() 不会自动追加——它默认每次写都清空目标 sheet(如果同名),或新建 sheet。但如果你反复用同一个 ExcelWriter 实例、又没关掉它,底层引擎(如 xlsxwriter)可能拒绝重复写同名 sheet。
- 务必用
with pd.ExcelWriter(...)上下文管理,确保自动关闭和保存 - 显式指定
sheet_name,避免默认重名;不同表用不同名字,比如"sales_2024"、"users_summary" - 如果要用
xlsxwriter引擎(默认),它不支持“追加到已有文件”,必须一次性写完所有 sheet;改用openpyxl引擎才能读-改-写,但需提前安装:pip install openpyxl - 示例:
with pd.ExcelWriter("report.xlsx", engine="openpyxl") as writer: df1.to_excel(writer, sheet_name="overview") df2.to_excel(writer, sheet_name="details")
导出含中文的 Excel,打开乱码或报错 UnicodeEncodeError
这不是 Pandas 的问题,是底层引擎对编码/字体的处理差异。xlsx 格式本身不依赖系统编码,但 Windows 上双击打开时,Excel 有时会误判为 ANSI 编码,尤其当内容含中文且未嵌入字体信息时。
- 不用管
encoding参数——to_excel()完全忽略它(只对to_csv()有效) - 确保用
openpyxl或xlsxwriter引擎,二者原生支持 UTF-8 字符,不会报UnicodeEncodeError - 如果用
xlsxwriter,可加粗标题、设列宽来提升可读性:writer = pd.ExcelWriter("report.xlsx", engine="xlsxwriter") df.to_excel(writer, index=False) workbook = writer.book worksheet = writer.sheets["Sheet1"] worksheet.set_column("A:Z", 15) - 真正乱码多发生在用旧版 Excel 打开 .xlsx 时——不是代码问题,是客户端兼容性,建议用户升级 Office 或换 WPS
导出大表格(10 万+ 行)卡死或生成文件超大
Pandas + openpyxl 在写入时会把整张表加载进内存再序列化,10 万行 × 50 列很容易吃光 2GB 内存;而 xlsxwriter 流式写入更轻量,但不支持读取已有文件。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 优先选
xlsxwriter引擎:pd.ExcelWriter("big.xlsx", engine="xlsxwriter") - 避免在
to_excel()中传入index=True,索引列无业务意义还占空间 - 导出前用
df.select_dtypes(include=["number", "object"])过滤掉category或datetime64[ns, tz]等复杂类型列,它们会显著拖慢写入 - 如果真要保留时间戳,转成字符串:
df["created_at"] = df["created_at"].dt.strftime("%Y-%m-%d %H:%M:%S")
如何给 Excel 加简单样式(比如标题居中、数字千分位)
pandas 本身不提供样式 API,得靠底层引擎。直接调 openpyxl 或 xlsxwriter 的原生方法最稳,别信“pandas 内置样式”这种误导。
立即学习“Python免费学习笔记(深入)”;
- 用
xlsxwriter时,先定义格式:workbook = writer.book fmt_title = workbook.add_format({"align": "center", "bold": True}) worksheet.write(0, 0, "销售额汇总", fmt_title) - 数字列加千分位:
fmt_num = workbook.add_format({"num_format": "#,##0.00"}) worksheet.set_column("C:C", 12, fmt_num) - 注意:这些操作必须在
df.to_excel()之后、writer.close()之前做,且要通过writer.sheets["Sheet1"]拿到 worksheet 对象 - 不要尝试用
Styler导出 Excel——df.style.to_excel()只支持openpyxl,且样式兼容性差,常丢格式或报错
df 里有没有 NaN 嵌套在 list/dict 类型字段里。Excel 不认这种结构,会静默转成字符串 "[nan]" 或直接报 ValueError。导出前跑一遍 df.applymap(type) 或用 df.map(lambda x: isinstance(x, (list, dict))) 扫描异常字段,比事后排查快得多。

















