启用 read_only=true 可将内存占用从500mb+降至10–50mb、速度提升5–10倍,但需配合 iter_rows()、values_only=true、wb.close() 及 min_row/max_row 范围控制,禁用 ws['a1'] 等随机访问操作。

启用 read_only=True 避免全量加载内存
openpyxl 默认会把整个 Excel 文件解析成 DOM 对象,10MB 的 .xlsx 可能吃掉 500MB+ 内存,load_workbook() 卡住几十秒甚至触发 MemoryError 就是这个原因。设 read_only=True 后,底层改用 SAX 流式解析 XML,内存压到 10–50MB,速度提升 5–10 倍。
但要注意:read_only=True 下不能用 ws['A1']、ws.max_row、ws.merged_cells——这些调用会强制扫描全表或重建对象,直接拖回原速甚至崩溃。
- 必须搭配
iter_rows()或iter_cols()使用,不能转成list() -
values_only=True要一起加,跳过样式/字体/公式对象,只取计算后值 - 读完务必调用
wb.close(),否则文件句柄泄漏,多次运行后系统可能报“Too many open files”
用 iter_rows(min_row=..., max_row=...) 控制解析范围
不设 min_row 和 max_row,iter_rows() 默认遍历全部行,哪怕你只想要第 1000–2000 行。实测显示,限定范围后解析耗时下降 60% 以上。
常见场景:日志表头在第 1 行,数据从第 2 行开始;或者你只处理最近 1 万条记录。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 先读首行获取列名:
headers = next(ws.iter_rows(min_row=1, max_row=1, values_only=True))[0] - 再按需读数据:
for row in ws.iter_rows(min_row=2, max_row=10000, values_only=True): - 别在循环里调用
ws.cell(row=i, column=j),它会绕过流式逻辑,触发重解析
写入大文件时禁用样式并批量 append()
逐行 ws.append([val1, val2]) 是性能杀手:每调一次都重建行列元数据和样式缓存,10 万行可能耗时几分钟。换成 write_only=True 模式 + 批量写入,速度可稳定在 2 万行/秒左右。
这个模式下无法访问已写单元格、不能设样式、不支持 ws['A1'],但它本来就是为“只生成数据”设计的。
- 初始化:
wb = Workbook(write_only=True),不是load_workbook() - 组织好二维数据:
data_batch = [[a,b,c], [d,e,f], ...],每子列表是一行 - 一次性写入:
ws.append(data_batch),比单行 append 快 5–8 倍 - 如果数据是流式生成的,攒够 1000 行再
append()一次,平衡内存与吞吐
合并单元格和空行需手动补值
read_only=True 下 ws.iter_rows() 不展开合并单元格,也不会填充空行。比如报表中「部门」列合并了 5 行,实际只有首行有值,其余为 None——这不是 bug,是流式解析的必然结果。
如果你依赖结构化字段(如 Pandas DataFrame),必须自己缓存上一行非空值做前向填充。
- 示例逻辑:
last_dept = None; for row in ws.iter_rows(...): dept = row[0] or last_dept; last_dept = dept or last_dept - 若必须精确还原合并逻辑(比如导出带格式的报表),只能退回到
read_only=False模式,用ws.merged_cells.ranges处理,但速度回归原点 - 空行判断别用
not row,因row是 tuple,全None也不等于空;应检查all(cell is None for cell in row)
read_only + values_only;要样式或合并信息就得接受慢;写报表就别碰 active sheet 的 append,直接切 write_only。漏掉 wb.close() 或误用 max_row 这类 API,比算法本身更容易让优化失效。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










