ChatGPT 读 Excel 但不算公式(把公式当字符串)

上传 XLSX 后 ChatGPT 能读单元格值,但公式驱动的格子返回 '=SUM(A1:A10)' 这种字符串——openpyxl 默认行为,几步修好。

你上传一个塞满 =VLOOKUP(...)=SUMIFS(...) 和数据透视表的工作簿,让 ChatGPT 汇总——结果总数明显错了:要么是 0,要么直接返回 =SUM(B2:B100) 这种字面公式字符串。原因在于 Code Interpreter 用 openpyxl 读 Excel 时,默认返回的是公式字符串,不是 Excel 缓存的计算结果。修法有三:让 openpyxl 强制读缓存值、上传前在 Excel 里另存为”值”、或者把关键数字直接贴进对话。

常见原因

1. openpyxl 默认返回公式文本而不是值

openpyxl.load_workbook(file) 不加 data_only=True 返回公式;加上 data_only=True 返回 Excel 上次保存时的缓存值——但前提是文件最近被 Excel 打开并保存过。脚本生成的 XLSX(xlsxwriter、exceljs)经常根本没有缓存值。

如何判断:让 ChatGPT 打印一个公式单元格。输出是 =SUMIFS(...) 而不是数字,就是 openpyxl 在公式模式。

2. 文件是代码生成的,从没在 Excel 里打开过

pandas to_excel、xlsxwriter、openpyxl 写出的文件——只写公式文本。Excel 只在你真正打开并保存时才会计算公式并缓存值。Python 生成、没被 Excel 碰过的文件,缓存值字段是 None

如何判断openpyxl.load_workbook(..., data_only=True) 返回 None,就是没有缓存值。

3. 外部引用 / 实时数据连接

=INDIRECT("[other.xlsx]Sheet1!A1")=GETPIVOTDATA(...)、Power Query / 数据模型拉取的公式——只要源工作簿没一起上传,缓存值就没意义。即使 data_only=True,你拿到的也是 Excel 上次能访问源文件时的旧缓存,常常是过期值或 #REF!

4. 数据透视表是 Excel 算的,不是存的

Pivot table 以缓存 blob 形式存在,只有 Excel 自己能渲染。openpyxl 看得到源数据和一个 stub,但看不到透视表输出。ChatGPT 没法直接读透视表——只能读底层数据,用 pandas 重新聚合。

5. 易变函数永远不可靠缓存

NOW()TODAY()RAND()OFFSET()INDIRECT()——Excel 每次打开都会重算。缓存值(如果有)是上次保存时的快照,只在你知道文件何时最后被 Excel 打开的情况下才能信任。

最短修复路径

Step 1:让 openpyxl 强制读缓存值

明确告诉 ChatGPT:

import openpyxl
wb = openpyxl.load_workbook("file.xlsx", data_only=True)
ws = wb.active
for row in ws.iter_rows(values_only=True):
    print(row)

如果文件最后是 Excel 保存的,会返回数字。如果该有公式的位置都是 None,说明文件没缓存值——去 Step 2。

Step 2:上传前另存为”值”

Excel 里:全选 - 复制 - 选择性粘贴 - 数值 - 另存为新 .xlsx。所有公式单元格都变成静态数字。上传这个”纯值”版本。最可靠的修法,30 秒搞定。

也可以另存为 .csv——CSV 按定义只存计算结果。

Step 3:在 pandas 里重新算

如果不能改文件,让 ChatGPT 读底层数据、重算:

import pandas as pd
df = pd.read_excel("file.xlsx", sheet_name="Data")
# 用 pandas 重写 VLOOKUP / SUMIFS
totals = df.groupby("region")["amount"].sum()
print(totals)

代价是失去原始 Excel 公式审计链,但你得到正确数字,而且过程可复现。

Step 4:透视表 → 读源数据再聚合

import pandas as pd
df = pd.read_excel("file.xlsx", sheet_name="RawData")
pivot = df.pivot_table(
    index="category",
    columns="quarter",
    values="revenue",
    aggfunc="sum",
)
print(pivot)

比纠结透视表缓存 blob 更快、更灵活。

Step 5:实在不行就把关键数字单独贴

打开工作簿,把你真正需要的那 5-20 个数字复制出来,以 markdown 表格贴进对话。这样 ChatGPT 拿到的是权威值,完全绕过 Excel 内部解析。

验证修复

重新保存或重建后,再验一次读取:

import openpyxl
wb = openpyxl.load_workbook("file.xlsx", data_only=True)
ws = wb["Summary"]
for row in ws.iter_rows(min_row=1, max_row=10, values_only=True):
    print(row)

公式单元格现在应该是数字,不是 None、不是 = 字符串。还是 None,说明文件没经过 Excel——回到 Step 3 用 pandas 重建。

预防

  • Excel 文件在上传前一定要在 Excel 里打开并保存一次——这会缓存所有公式值。
  • 给 ChatGPT 分析的数据,优先用”选择性粘贴 - 数值”版本;公式版作为独立审计文件保留。
  • 准备给 LLM 分析的工作簿不要用外部引用、实时数据连接。
  • 重复性工作流从一开始就用 pandas / SQL 做聚合——Excel 只做查看器,ChatGPT 直接读原始数据。
  • 必须保留公式时,附带一个小文本文件列出预期总数,让 ChatGPT 能自检读取是否正确。

标签: #ChatGPT #ChatGPT 文件 #排查 #排查 #Excel