使用OpenPyXL加载大Excel文件时内存占满的技术求助
兄弟,这问题我太有发言权了——你用的是openpyxl默认的加载模式,这玩意儿会把整个Excel文件的所有内容(包括格式、样式这些你根本不需要的东西)一股脑塞进内存,80万行数据撑爆8GB内存真的太正常了。咱们来一步步解决:
问题根源
openpyxl的load_workbook()默认参数read_only=False,会把所有工作表的所有单元格对象(含格式、样式、注释等冗余信息)全部加载到内存,哪怕你只需要几列数据,它也会把整个文件的内容都存下来,这对大文件来说内存开销直接拉满。
核心解决方案
1. 启用只读模式加载工作簿
这是最关键的一步,把load_workbook改成只读模式后,openpyxl会以流式读取的方式处理文件,不会一次性把所有数据塞进内存,内存占用会直接砍半甚至更多:
from openpyxl import load_workbook # read_only=True:开启流式读取;data_only=True:只读取单元格的实际值(而非公式) wb = load_workbook('Record.xlsx', read_only=True, data_only=True)
2. 优化数据读取逻辑,别存冗余对象
你现在的代码把完整的单元格对象(比如a, c, f, k)存进了列表,这些对象本身带着一堆你不需要的属性(比如单元格坐标、字体样式),纯纯浪费内存。应该直接提取单元格的值来存储,而且用生成器代替列表,避免一次性加载所有数据:
def process(ws): '''高效读取指定列的数据''' # 用iter_rows逐行遍历,values_only=True直接返回单元格值 for row in ws.iter_rows(min_row=1, values_only=True): # 索引对应列:A=0, C=2, F=5, K=10 yield [row[0], row[2], row[5], row[10]]
如果确实需要把所有数据存下来,再转成列表就行:
ws1 = wb.worksheets[0] data1 = list(process(ws1))
3. 用完就关,及时释放内存
在只读模式下,处理完一个工作表后可以手动关闭它,立刻释放对应的内存,再处理下一个工作表:
ws1 = wb.worksheets[0] data1 = list(process(ws1)) wb.close(ws1) # 关闭单个工作表,释放内存 ws2 = wb.worksheets[1] data2 = list(process(ws2)) wb.close(ws2)
额外优化建议
如果内存还是吃紧,或者你需要更高效的数据处理,可以试试用pandas配合openpyxl引擎读取指定列,pandas的内存优化做得更到位,还支持分块读取:
import pandas as pd # 只读取A、C、F、K列,每次读1万行(chunksize可根据内存调整) chunk_iter = pd.read_excel('Record.xlsx', sheet_name=0, usecols=['A', 'C', 'F', 'K'], chunksize=10000) for chunk in chunk_iter: # 在这里处理每一块数据,比如转成列表或者直接做分析 process_chunk(chunk)
内容的提问来源于stack exchange,提问作者arush1836
相关产品推荐
相关产品推荐

