如何用Python读取Excel中大于50MB的pivot table且不占用过高内存
你遇到的问题根源是openpyxl的底层逻辑限制:普通加载模式会将整个工作簿的所有单元格、样式、对象全部载入内存,50MB带透视表的文件展开后很容易占用数十GB内存;只读模式为了降低内存占用,不会解析加载_pivots这类私有属性,所以会报属性不存在的错误。
以下是可行的解决方案:
方案1:调用本地Excel实例读取(优先推荐)
直接调用系统安装的Excel原生接口读取,所有文件解析逻辑由Excel原生处理,Python仅读取结果,内存占用和你直接双击打开该Excel文件的占用一致,不会出现内存爆炸的问题,同时可以完整读取透视表的所有属性(字段、缓存、筛选规则等)。
需要先安装依赖:
pip install xlwings pandas
示例代码:
import xlwings as xw import pandas as pd # 后台静默启动Excel,不显示界面、不弹出提示 with xw.App(visible=False, add_book=False) as app: app.display_alerts = False # 打开工作簿 wb = app.books.open("filename.xlsx") # 选中目标工作表 ws = wb.sheets["myWorksheet"] # 读取第一个透视表 pivot = ws.pivot_tables[0] # 读取透视表的数值转为DataFrame pivot_df = pivot.data_body_range.options(pd.DataFrame, index=False).value # 也可以读取透视表的行标签、列字段、值字段等属性 row_fields = [f.name for f in pivot.row_fields] value_fields = [f.name for f in pivot.data_fields] # 关闭工作簿不保存 wb.close(save=False)
- 优点:实现简单、内存占用极低、支持读取透视表全量属性
- 缺点:需要本地安装Microsoft Excel,支持Windows、macOS系统,不支持Linux
方案2:直接解析XLSX底层XML(跨平台无依赖)
XLSX本质是ZIP压缩包,透视表的定义、缓存、数据都单独存放在压缩包内的xl/pivotTables/、xl/pivotCache/目录下,无需加载整个工作簿,只需要提取对应的XML文件解析即可,内存占用仅几MB。
需要先安装依赖:
pip install lxml
示例代码:
import zipfile from lxml import etree # 定义OpenXML命名空间 NS = {"x": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"} with zipfile.ZipFile("filename.xlsx", "r") as zf: # 1. 先读取工作簿配置,找到目标工作表对应的ID wb_xml = zf.read("xl/workbook.xml") wb_root = etree.fromstring(wb_xml) target_sheet = wb_root.xpath("//x:sheet[@name='myWorksheet']", namespaces=NS)[0] sheet_id = target_sheet.attrib["sheetId"] # 2. 读取工作表的关系文件,找到关联的透视表路径 ws_rel_xml = zf.read(f"xl/worksheets/_rels/sheet{sheet_id}.xml.rels") rel_root = etree.fromstring(ws_rel_xml) pivot_rel = [r for r in rel_root.findall("*") if "pivotTable" in r.attrib["Type"]][0] pivot_path = pivot_rel.attrib["Target"].replace("../", "xl/") # 3. 读取透视表定义 pivot_xml = zf.read(pivot_path) pivot_root = etree.fromstring(pivot_xml) cache_id = pivot_root.attrib["cacheId"] # 4. 读取透视表缓存和数据 cache_def_xml = zf.read(f"xl/pivotCache/pivotCacheDefinition{cache_id}.xml") cache_record_xml = zf.read(f"xl/pivotCache/pivotCacheRecords{cache_id}.xml") # 自行解析XML即可拿到所有透视表字段、数据
- 优点:跨平台支持所有系统、无需安装Excel、内存占用最低
- 缺点:需要熟悉OpenXML规范自行解析XML结构,适合定制化开发场景
方案3:只读透视表所在单元格范围(仅需数值时使用)
如果你不需要读取透视表的结构属性,只需要获取透视表展示的数值,可以直接指定透视表所在的单元格范围读取,无需加载整个工作表。
需要先安装依赖:
pip install pandas openpyxl
示例代码:
import pandas as pd # 假设透视表在myWorksheet的A1到Z200单元格范围内,按需修改参数 pivot_df = pd.read_excel( "filename.xlsx", sheet_name="myWorksheet", usecols="A:Z", nrows=200 )
- 优点:实现最简单、适合快速拿数
- 缺点:需要提前知道透视表的单元格范围,无法读取透视表的结构、字段等元数据
内容的提问来源于stack exchange,提问作者KOMsandFriends
相关产品推荐
相关产品推荐

