Excel 本身不会自己「调 AI」,能落地的做法只有两种:一是用 Excel 内置能力(Copilot、Office 脚本、Power Query)在表格里就地处理,二是把单元格内容读成文件、交给模型接口、再把结果写回新列。判断标准很简单:只跑一次、行数在几百行以内,先用内置能力;要反复跑、结果要能复现、要留痕核对,就走脚本这条路。下面按排查顺序写,先确认前提,再跑最短路径,最后给一个能照抄的场景和三处最常见的卡点。
Excel 里的 AI 处理,本质是「读单元格 → 交给模型 → 写回新列」,Excel 只负责前后两头。行数少且一次性的,用 Microsoft 365 里的 Copilot 或 Office 脚本更省事;要批量、要复现,用 pandas 读 xlsx、用 HTTP 调模型、结果另存新文件。无论走哪条路,都先另存副本再动手,用脚本写回会丢掉格式、公式和数据验证。模型名、额度、限速以你所用服务商控制台里显示为准。
AI表格数据处理之前先确认这三件事
这三件事任意一件没确认,后面都会卡在一个看起来像「AI 不好用」的地方,实际上是环境问题。
- 版本:在 Excel 里点「文件 → 账户 → 产品信息」,看产品名是不是 Microsoft 365 订阅版。Copilot、Office 脚本这类入口通常只在订阅版或网页版出现,买断版(如 Excel 2021)多数情况下看不到。走脚本路线的话,在终端执行
python -V和pip show pandas openpyxl,确认 Python 版本和这两个包都装在同一环境里。 - 权限:在「开始 → 敏感度」看文件是否被打了敏感度标签,带标签的文件读写可能被限制;再看文件属性里是否「只读」,以及文件是否放在 OneDrive 同步目录且正处于打开状态。接口侧看服务商控制台的「用量 / 额度」页,确认 Key 还有效、额度没耗尽,不要凭印象。
- 入口位置:Power Query 在「数据 → 获取数据」;Office 脚本在功能区「自动化」;Copilot 图标在「开始」选项卡右侧。图标是灰的或整块不存在,先回到上一条查版本和组织策略,不要在按钮上反复点。
AI表格数据处理:最短可用路径
以下五步做完就能拿到一列 AI 结果,每步只做一件事。
- 另存副本:把原表另存为
反馈.xlsx,与原文件分开。做完应看到目录下多了一个同名副本,原文件没被动过。 - 核对表头:确认工作簿里的 sheet 名和列名,脚本里要逐字对上(含空格和全角符号)。做完应能在
df.columns里看到你写的那几个列名,拼错会直接 KeyError。 - 跑脚本:把下面的骨架存成
ai_fill.py,放在 xlsx 同目录,先在终端设置两个环境变量AI_API_KEY、AI_BASE_URL,再执行python ai_fill.py。接口路径、请求字段按你所用服务商的文档改,这里只是通用骨架。 - 看输出:终端应打印「写出 反馈_已标注.xlsx N 行;未标注 0」。未标注数不为 0,说明有批次返回的格式没对上,先记下来别急着覆盖。
- 抽检:打开新文件,随机看十行左右,确认类别只在预设的几类里、摘要没有串行。
# ai_fill.py —— 与 反馈.xlsx 放在同一目录
import json, os, time, requests, pandas as pd
SRC, DST = "反馈.xlsx", "反馈_已标注.xlsx"
SHEET, COL = "反馈", "反馈内容"
BASE_URL = os.environ["AI_BASE_URL"] # 换成服务商文档里的完整路径
API_KEY = os.environ["AI_API_KEY"]
MODEL = os.environ.get("AI_MODEL", "填控制台里看到的模型名")
BATCH = 20
def ask(texts):
prompt = (
"对每条反馈判断类别,类别只能取:功能、价格、稳定性、其他。"
"只输出 JSON 数组,不要解释、不要代码围栏。"
"格式:[{\"i\":0,\"类别\":\"功能\",\"摘要\":\"不超过20字\"}]"
f"\n输入:{json.dumps(texts, ensure_ascii=False)}"
)
body = {"model": MODEL, "temperature": 0,
"messages": [{"role": "user", "content": prompt}]}
r = requests.post(BASE_URL, json=body, timeout=60,
headers={"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"})
r.raise_for_status()
return json.loads(r.json()["choices"][0]["message"]["content"])
df = pd.read_excel(SRC, sheet_name=SHEET)
texts = df[COL].fillna("").astype(str).tolist()
res = {}
for s in range(0, len(texts), BATCH):
for item in ask(texts[s:s + BATCH]):
res[s + item["i"]] = item
time.sleep(1)
df["AI分类"] = [res.get(i, {}).get("类别", "") for i in range(len(df))]
df["AI摘要"] = [res.get(i, {}).get("摘要", "") for i in range(len(df))]
df.to_excel(DST, index=False)
print("写出", DST, len(df), "行;未标注", sum(1 for i in range(len(df)) if i not in res))
AI表格数据处理:一个真实场景的完整做法
场景:一张 1200 行的客户反馈表,对象是纯文本单元格,目标是给每行打一个类别标签并生成一句不超过 20 字的摘要,标签限定在四类以内,方便后面在 Excel 里做数据透视。
具体取值与位置:数据在 反馈.xlsx 的 反馈 工作表,待处理列名 反馈内容;类别集合写在脚本的 prompt 里,改类别就改这一行;BATCH 取 20,行少可调小,返回格式错得多就调小;temperature 取 0,尽量让同类文本得到同样的标签;timeout 取 60 秒,长文本多时不易超时;批间 sleep(1) 是给接口留余量,具体能跑多快以服务商文档的限速说明为准。

执行顺序:先另存副本 → 用 pd.read_excel 读一次,只打印 df.head(3) 核对列名和内容有没有被当成 NaN → 先只跑一个批次(把循环上限改成 20 行)看返回值 → 确认格式没问题再跑全量 → 抽检十行 → 需要合并回原表时,用 XLOOKUP 或 VLOOKUP 按唯一行号匹配,不要手工复制粘贴。
这里最容易踩的坑:to_excel 写出的是「数据」,不是「你的原表」。合并单元格、公式、条件格式、数据验证、列宽这些都不会跟着走。所以永远写到一个新文件,再决定怎么把新列并回母表;反过来,如果原表有合并单元格,read_excel 读出来的表头可能是空的,先取消合并再读。
AI表格数据处理:跑不通先查这三处
按出现频率排,下面三个报错覆盖了大部分「跑不动」的情况。
- 模块找不到:报错原文
ModuleNotFoundError: No module named 'openpyxl',或者装了 pandas 却提示缺 openpyxl。检查位置:在同一个终端执行pip -V和python -V,看两条路径是不是同一环境;如果你用过虚拟环境或 conda,多半是装到了另一个 Python 里。先激活对应环境再pip install openpyxl。 - 模型返回解析失败:报错原文
json.decoder.JSONDecodeError,或者内容里带着三反引号围栏。检查位置:打印原始返回内容看前 200 个字符。多数是 prompt 没写死「只输出 JSON」,或者批次里混入了超长文本把输出截断。把批次调小、把「不要代码围栏」写进 prompt、必要时用正则截取第一个[到最后一个]。 - 写文件失败:报错原文
PermissionError: [Errno 13] Permission denied,或openpyxl.utils.exceptions.IllegalCharacterError。检查位置:前者看目标文件是不是正在 Excel 里打开、目录是不是网盘同步中,关掉文件重跑;后者是单元格里混进了控制字符(常见于从网页复制的文本),写回前用str.replace清一遍不可见字符。
顺带一句:如果前面每一步都没报错,但结果整列都是空的,先去看未标注计数和 res 的键是不是从 0 开始连续——索引对不上时脚本不报错,只是安静地写空值。