如何在Excel中调用Python脚本,实现数据自动化处理!
Excel 里最烦的,从来不是函数不够用。
是你明明想把一列脏数据清一下、几张表合一下、顺手再跑个规则校验,结果最后变成了:复制一遍,粘贴一遍,改一遍公式,再人工盯一遍。量一大,人先崩。
这时候再死磕公式,已经有点不划算了。该上 Python 了。
如何在 Excel 中调用 Python 脚本,实现数据自动化处理
很多人第一次听到“Excel 调 Python”,脑子里会自动冒出一个误区:是不是得把 Excel 全换掉?
不用。
大多数场景根本不是替代 Excel,而是把 Excel 继续当输入输出界面,脏活累活交给 Python。用户还是点表格、填数据、看结果,你把清洗、计算、汇总、校验这些重复动作塞进脚本里。
我平时更愿意把它理解成一件事:让 Excel 负责展示,让 Python 负责干活。
比如下面这类活,Excel 自己做就开始别扭了:
-
批量清洗手机号、身份证、订单号 -
合并多个工作表,再按规则生成结果表 -
自动校验空值、重复值、异常值 -
根据 Excel 数据调接口,补齐字段 -
每天定时处理一批报表,再导出新文件
这些事,不是 Excel 做不了。是做起来太碎,太容易出错,而且很难复用。
手里有一个 Excel,里面是运营同学导出来的订单数据,长这样:
|
|
|
|
|
|
|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
现在要做几件事:
-
去掉手机号为空的数据 -
标记重复手机号 -
只保留已支付订单 -
按用户汇总支付金额 -
输出一个新 Excel 给业务同学
这种需求,Excel 里不是不能做。 但你真让人天天这么拖公式、筛选、透视,迟早有人把原始表改坏。
这种活我一般直接上 pandas。
先准备环境
先装两个库:
pip install pandas openpyxl
一个负责处理数据,一个负责读写 Excel。
然后准备一个脚本,比如叫 excel_task.py。
第一版脚本,先把活跑通
import pandas as pd
input_file = "订单数据.xlsx"
output_file = "处理结果.xlsx"
# 读取 Excel
df = pd.read_excel(input_file)
# 1. 去掉手机号为空的数据
df = df[df["手机号"].notna()]
# 2. 标记重复手机号
df["手机号是否重复"] = df["手机号"].duplicated(keep=False).map({True: "是", False: "否"})
# 3. 只保留已支付订单
paid_df = df[df["状态"] == "paid"].copy()
# 4. 按用户名汇总支付金额
summary_df = (
paid_df.groupby("用户名", as_index=False)["金额"]
.sum()
.rename(columns={"金额": "支付总金额"})
)
# 5. 导出到新的 Excel
with pd.ExcelWriter(output_file, engine="openpyxl") as writer:
df.to_excel(writer, sheet_name="清洗后明细", index=False)
summary_df.to_excel(writer, sheet_name="支付汇总", index=False)
print(f"处理完成,结果已输出到:{output_file}")
这段代码不花哨,但够用。
重点不是代码多高级,而是这套动作以后可以重复跑。 下次运营再甩你一个新文件,不用再手工折腾,双击脚本就行。
真正麻烦的,往往不是“处理”,而是“调用”
很多人 Python 脚本会写一点,但卡在最后一步:
Excel 里怎么调用 Python?
这事其实有几种路子,复杂度不一样。我按平时最常见的三种说。
方式一:最省事,直接让 Python 读写 Excel 文件
这个最稳,也最适合大多数人。
流程很简单:
-
用户把原始 Excel 放到指定目录 -
运行 Python 脚本 -
脚本读取 Excel,处理完再生成一个新 Excel
这种方式虽然不是“在单元格里直接调 Python”,但线上真干活时反而最省心。 因为它不依赖 Office 版本,也不容易被某个插件环境搞炸。
比如你可以再封一层批处理脚本,业务同学点一下就能跑:
python excel_task.py
pause
Windows 下存成 run_excel_task.bat,双击即可。
这种方式我挺喜欢。原因很简单:能跑、稳定、少折腾。
方式二:用 xlwings,把 Python 和 Excel 真连起来
如果你非要在 Excel 里点按钮触发 Python,那 xlwings 是个很常见的方案。
先装:
pip install xlwings
然后写个脚本:
import xlwings as xw
import pandas as pd
defprocess_excel():
wb = xw.Book.caller()
sheet = wb.sheets["Sheet1"]
# 读取 Excel 区域数据
data = sheet.range("A1").options(pd.DataFrame, header=1, index=False, expand="table").value
# 清洗数据
data = data[data["手机号"].notna()]
data["手机号是否重复"] = data["手机号"].duplicated(keep=False).map({True: "是", False: "否"})
data = data[data["状态"] == "paid"]
summary = (
data.groupby("用户名", as_index=False)["金额"]
.sum()
.rename(columns={"金额": "支付总金额"})
)
# 输出结果到新工作表
result_sheet = None
try:
result_sheet = wb.sheets["结果"]
result_sheet.clear()
except Exception:
result_sheet = wb.sheets.add("结果")
result_sheet.range("A1").value = summary
然后在 Excel 里绑一个按钮,点按钮就触发 process_excel()。
这个方案的好处很直接:
-
用户还在 Excel 里操作 -
可以点按钮执行 -
处理结果能直接回写到当前工作簿
但我得提前说一句,这种方式环境问题会多一点。 比如 Office 位数、Python 环境、加载项配置、权限问题,哪个地方不对都可能起不来。
所以这方案适合对交互有要求的内部工具,不太适合第一次上来就硬怼。
方式三:Office 365 里的 Python in Excel
这个名字听着最诱人,因为它看起来像“Excel 原生支持 Python”。
确实是这么个方向,但它更偏向在单元格中跑 Python 分析,而不是你本地随便写个脚本直接全接管 Excel 流程。
这一类方案更适合:
-
数据分析 -
画图 -
临时计算 -
在工作表中直接写 Python 表达式
但你要说做一套本地自动化脚本、批量导入导出、接业务流程,很多时候还是传统 Python 脚本更顺手。
所以别一上来就觉得“官方支持的肯定最适合我”。 真做自动化,还是先看你要解决的是分析问题,还是流程问题。
只是想把重复劳动自动化
直接用 pandas + openpyxl
够了,真的够了。 别还没跑起来,就先把自己埋进插件、按钮、加载项里。
想让业务同学在 Excel 里点按钮
用 xlwings
这个更像一个桌面小工具,交互感更强,但环境也更挑。
你本来就在做分析建模
可以再看 Python in Excel
但这条路别和“本地自动化处理报表”混在一起。
再往前走一步,可以把“脚本”做成“工具”
很多人写 Python 处理 Excel,第一版都能跑。 第二版就开始出问题了:
-
表头改了一个字,脚本挂了 -
多了一个空行,结果错了 -
金额列混进字符串,求和炸了 -
输出文件被别人开着,保存失败
所以这类脚本,最好从一开始就加点最基本的校验。
我一般至少会补这几样。
-
先校验列名
别上来就处理,先确认表结构对不对。
required_columns = {"订单号", "用户名", "手机号", "金额", "状态"}
actual_columns = set(df.columns)
missing_columns = required_columns - actual_columns
if missing_columns:
raise ValueError(f"缺少必要列: {missing_columns}")
-
金额列先转数值
这地方很容易混进空字符串、中文、破折号。
df["金额"] = pd.to_numeric(df["金额"], errors="coerce")
df = df[df["金额"].notna()]
-
输出前别直接覆盖原文件
原始数据最好别动,永远输出新文件。
这点我很在意。 线上排障有个习惯,原始现场尽量别破坏。处理 Excel 也一样。
下面这个脚本,比前面那版更像平时真会落地的东西:有校验,有异常处理,有时间戳输出。
import os
from datetime import datetime
import pandas as pd
INPUT_FILE = "订单数据.xlsx"
REQUIRED_COLUMNS = {"订单号", "用户名", "手机号", "金额", "状态"}
defmain():
ifnot os.path.exists(INPUT_FILE):
raise FileNotFoundError(f"找不到文件: {INPUT_FILE}")
df = pd.read_excel(INPUT_FILE)
missing_columns = REQUIRED_COLUMNS - set(df.columns)
if missing_columns:
raise ValueError(f"Excel 缺少必要列: {', '.join(missing_columns)}")
# 清洗字段
df["手机号"] = df["手机号"].astype(str).str.strip()
df["金额"] = pd.to_numeric(df["金额"], errors="coerce")
# 过滤无效数据
df = df[df["手机号"].notna()]
df = df[df["手机号"] != ""]
df = df[df["金额"].notna()]
# 标记重复手机号
df["手机号是否重复"] = df["手机号"].duplicated(keep=False).map({True: "是", False: "否"})
# 已支付订单
paid_df = df[df["状态"].astype(str).str.lower() == "paid"].copy()
# 汇总
summary_df = (
paid_df.groupby("用户名", as_index=False)
.agg(
支付订单数=("订单号", "count"),
支付总金额=("金额", "sum")
)
)
# 生成输出文件名
now = datetime.now().strftime("%Y%m%d_%H%M%S")
output_file = f"处理结果_{now}.xlsx"
with pd.ExcelWriter(output_file, engine="openpyxl") as writer:
df.to_excel(writer, sheet_name="清洗后明细", index=False)
paid_df.to_excel(writer, sheet_name="已支付订单", index=False)
summary_df.to_excel(writer, sheet_name="汇总结果", index=False)
print(f"处理完成,输出文件:{output_file}")
if __name__ == "__main__":
try:
main()
except Exception as e:
print(f"执行失败:{e}")
这版你拿去改改列名,基本就能直接干活。
这套东西值钱的地方,不在“会写代码”
而在于你把 Excel 这类零碎活,变成了一个可重复执行的流程。
第一次做,可能只是“自动清洗一张表”。 第二次你就会想:
-
能不能一次处理一个目录下所有 Excel? -
能不能处理完发邮件? -
能不能定时每天 8 点跑? -
能不能加个简单界面给同事用?
这时候你就会发现,Excel 只是入口。 真正的核心,是 Python 把这件重复劳动接管了。
我见过不少人,一提 Excel 自动化,第一反应就是研究 VBA。
也不是不行。 但如果你本来就学 Python,后面还想顺手接数据清洗、接口调用、数据库处理、报表生成,那继续在 VBA 里拧,性价比真不高。
Python 这条路更顺。
因为你今天是在处理 Excel,明天很可能就是:
读取 Excel -> 清洗数据 -> 调接口补字段 -> 写回 Excel -> 发给业务群
这一串活,Python 干起来是一条线。 Excel 公式和 VBA,很多时候干到后面就开始发闷了。
能让表格继续当表格,让脚本去干脚本该干的事,事情反而简单。参考气质校准见
夜雨聆风
