pandas读写Excel效率低因全量加载且不保留格式;纯数据用pandas分块读取,需样式用openpyxl,需图表或Excel应用用xlwings;文件遍历推荐pathlib+glob,批量保存避免重复打开,出错时用logging记录并分类处理。

用 pandas 读写 Excel 效率低?换 openpyxl 或 xlwings
直接用 pandas.read_excel() 和 pandas.to_excel() 批量处理上千个文件,很容易卡在 I/O 或内存上——尤其当文件含样式、图表、合并单元格时。pandas 底层依赖 openpyxl 或 xlsxwriter,但默认不保留格式,且每次读写都全量加载,开销大。
实操建议:
- 纯数据转换(无样式需求):用
pandas+chunksize参数分块读取大表,避免单次加载整表 - 需保留原格式(字体、边框、列宽等):直接用
openpyxl.load_workbook(),它支持原地修改、不丢样式,但不支持 .xls(旧版 Excel) - 要操作图表、公式或跨进程调用 Excel 应用:用
xlwings,但必须本机装 Excel,且速度慢、不适合无界面服务器 - 统一转为 .xlsx 且无需样式?可先用
pyxlsb(处理 .xlsb)或xlrd(仅 v1.2.0- 支持 .xls),但注意xlrd从 2.0 起已弃用 .xls 支持
路径遍历和文件筛选别靠 os.listdir() 硬写
上千个文件混在多级目录里,手动拼路径或嵌套 for 循环极易漏文件或报 PermissionError。更稳的方式是用 pathlib + glob。
示例片段:
立即学习“Python免费学习笔记(深入)”;
from pathlib import Path
<p>root = Path("data_input")
xlsx_files = list(root.rglob("<em>.xlsx")) # 递归找所有 .xlsx
xls_files = [f for f in root.rglob("</em>") if f.suffix.lower() in {".xls", ".xlsb"}]</p><h1>过滤掉临时文件(如 ~$ 开头、._ 开头)</h1><p>valid_files = [f for f in xlsx<em>files if not f.name.startswith(("~$", ".</em>"))]注意:rglob 可能扫到挂载点或权限受限目录,加 try/except PermissionError 包裹更安全;.suffix.lower() 避免大小写问题(如 .XLSX)。
诊断并修复涉及公式、命名范围、Power Query 刷新、数据透视表、VBA/宏保存等问题的 Microsoft Excel XLSX 工作簿
批量保存时别每个文件都新建一个 Workbook
用 openpyxl 时常见错误:循环里反复 load_workbook() → 修改 → save(),看似没问题,但每个 save() 都触发完整序列化,磁盘写入压力大,还容易因未关闭导致文件锁残留。
关键点:
- 改完立刻
wb.close(),不要等 GC 回收 - 避免在循环内重复打开同一模板文件——提前读一次,用
copy_workbook()复制(需openpyxl≥ 3.1) - 若只是统一调整列宽/字体,可用
ws.column_dimensions["A"].width = 15这类细粒度操作,比全量重写快 - 并发写入?别用
threading——openpyxl非线程安全;改用multiprocessing,但注意进程间不能传Workbook对象,得传路径再各自加载
出错时别让整个批次中断,记录日志比 print 更有用
上千个文件里总有几个损坏、密码保护或编码异常,try/except 全包一层是底线,但只 print 错误信息根本没法定位问题。
建议做法:
- 用
logging写入文件,每行包含时间、文件路径、错误类型、简短消息 - 对特定错误分类处理:比如
InvalidFileException(非 Excel 文件)跳过;ReadOnlyWorkbookException尝试加read_only=False参数重试 - 记录成功数/失败数/跳过数,最后输出汇总,而不是靠肉眼数 print 行数
- 失败文件路径存进
failed_paths.txt,方便后续人工查——别指望脚本自动修复加密或损坏文件
真正麻烦的不是代码怎么写,而是某几个文件用了非常规字体、嵌入了 OLE 对象,或者用 WPS 保存的“伪 .xlsx”——这些只能靠日志暴露,没法预判。

















