首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python 处理 Excel 终极对比:openpyxl vs pandas vs xlwings

Python 处理 Excel 终极对比:openpyxl vs pandas vs xlwings

作者头像
用户11081884
发布2026-07-20 20:28:12
发布2026-07-20 20:28:12
290
举报

处理Excel这件事我踩过的坑加起来能写一本书。

最早用VBA,后来学了Python觉得自己升华了,结果发现Python生态里处理Excel的库有好几个,每次选错就是半天白费。

今天把三个最常用的库彻底对比一遍,openpyxl、pandas、xlwings,每个都说清楚:适合干嘛、不适合干嘛、哪些坑是我替你踩过的。


先说结论

不想看完整文章的,直接看这段:

  • openpyxl:你要操作Excel格式(合并单元格、设置样式、写公式),用这个
  • pandas:你要做数据分析、大批量读写、数据清洗,用这个
  • xlwings:你要跟已经打开的Excel文件交互、执行VBA,用这个

用错了不是不能跑,是你会很痛苦。


openpyxl:格式控的选择

它能干嘛

openpyxl直接操作.xlsx文件,不需要本机装Excel,读写改样式都行。

代码语言:javascript
复制
fromopenpyxlimportWorkbook
fromopenpyxl.stylesimportFont, PatternFill, Alignment
fromopenpyxl.utilsimportget_column_letter

wb = Workbook()
ws = wb.active
ws.title = "月度报表"

# 写标题行
headers = ["姓名", "部门", "销售额", "完成率"]
forcol_num, headerinenumerate(headers, 1):
    cell = ws.cell(row=1, column=col_num, value=header)
    cell.font = Font(bold=True, color="FFFFFF")
    cell.fill = PatternFill(start_color="2F75B6", end_color="2F75B6", fill_type="solid")
    cell.alignment = Alignment(horizontal="center")

# 写数据
data = [
    ("张三", "销售部", 120000, "120%"),
    ("李四", "销售部", 95000, "95%"),
    ("王五", "市场部", 88000, "88%"),
]
forrow_dataindata:
    ws.append(row_data)

# 设置列宽
fori, colinenumerate(ws.columns):
    ws.column_dimensions[get_column_letter(i+1)].width = 15

wb.save("月度报表.xlsx")

踩过的坑

坑一:合并单元格之后写不进去数据

第一次遇到这个坑的时候搞了大半天。合并之后只有左上角的单元格能写值,其他位置写了也是白写。

代码语言:javascript
复制
ws.merge_cells("A1:D1")
ws["A1"] = "Q1季度总结"  # 只能写A1
# ws["B1"] = "什么" 写了也没用,保存之后还是空的

坑二:写公式不等于有计算结果

代码语言:javascript
复制
ws["E2"] = "=SUM(A2:D2)"  # 公式写进去了
# 但用openpyxl读这个文件,读出来是字符串 "=SUM(A2:D2)"
# 不是计算结果

想读公式结果要么打开Excel让它重新计算,要么用xlwings——后面说。

坑三:几万行以上写得很慢

超过几万行的Excel,openpyxl写起来开始掉速,这种情况换pandas。


pandas:数据处理主力

它能干嘛

pandas才不管你单元格什么颜色,它就管数据。读取、过滤、聚合、处理、输出,这套流程用它是最顺的。

代码语言:javascript
复制
importpandasaspd

df = pd.read_excel("销售数据.xlsx", sheet_name="Sheet1")

df_clean = (
    df
    .dropna(subset=["销售额"])
    .query("销售额 > 0")
    .assign(完成率=lambdax: x["销售额"] /x["目标额"])
    .sort_values("销售额", ascending=False)
)

summary = df_clean.groupby("部门").agg(
    总销售额=("销售额", "sum"),
    平均完成率=("完成率", "mean"),
    人数=("姓名", "count")
).reset_index()

print(summary)

同时处理多个sheet

代码语言:javascript
复制
all_sheets = pd.read_excel("数据.xlsx", sheet_name=None)
combined = pd.concat(all_sheets.values(), ignore_index=True)

写出带格式的Excel(搭xlsxwriter)

代码语言:javascript
复制
withpd.ExcelWriter("报告.xlsx", engine="xlsxwriter") aswriter:
    df.to_excel(writer, sheet_name="数据", index=False)

    workbook = writer.book
    worksheet = writer.sheets["数据"]

    header_fmt = workbook.add_format({
        "bold": True,
        "bg_color": "#2F75B6",
        "font_color": "white",
        "align": "center",
    })

    forcol_num, valueinenumerate(df.columns.values):
        worksheet.write(0, col_num, value, header_fmt)

踩过的坑

坑一:日期列变成 Timestamp 了

代码语言:javascript
复制
df = pd.read_excel("数据.xlsx")
print(df["日期"][0])  # 2024-01-15 00:00:00,不是你想要的格式

# 转成字符串
df["日期"] = df["日期"].dt.strftime("%Y-%m-%d")

坑二:金额列浮点精度掉了

钱相关的计算不能直接用float,0.1+0.2不等于0.3,这不是Python的问题,是所有语言的浮点数问题:

代码语言:javascript
复制
fromdecimalimportDecimal
df["金额"] = df["金额"].apply(lambdax: Decimal(str(x)))

坑三:大文件内存不够用

500MB以上的Excel直接read_excel会把整个文件塞进内存,小内存机器很容易OOM。pandas不支持分块读Excel,超大文件建议先转CSV:

代码语言:javascript
复制
chunk_size = 10000
forchunkinpd.read_csv("大文件.csv", chunksize=chunk_size):
    process(chunk)

xlwings:操控Excel本体

它能干嘛

xlwings需要本机装Excel,它直接操控Excel进程。

能做:

  • 读已打开文件的实时数据
  • 读公式计算结果(不是公式字符串)
  • 执行VBA宏
  • 生成图表截图
代码语言:javascript
复制
importxlwingsasxw

wb = xw.Book("报表.xlsx")
ws = wb.sheets["Sheet1"]

# 读取值(公式结果,不是公式本身)
value = ws["B2"].value

# 批量读取
data = ws.range("A1:D10").value  # 返回二维列表

# 调用VBA宏
app = xw.apps.active
app.macro("ThisWorkbook.刷新数据")()

# 把Python处理结果写回
ws["A1"].value = [[1, 2, 3], [4, 5, 6]]

用完自动关闭进程

代码语言:javascript
复制
withxw.App(visible=False) asapp:
    wb = app.books.open("报表.xlsx")
    ws = wb.sheets[0]
    ws["A1"].value = "处理完成"
    wb.save()
    wb.close()
# 出了with块自动关闭Excel进程

踩过的坑

坑一:以为脚本跑完了Excel就关了

没显式关的话Excel进程会一直挂后台,下次再跑同一文件直接报“文件已被占用”。一定要用with语法或者手动close。

坑二:macOS权限问题

macOS用xlwings要给Python授权“辅助功能”权限,不然报:

代码语言:javascript
复制
appscript.reference.CommandError: errAEEventNotPermitted(-1743)

去系统偏好设置 > 隐私与安全性 > 辅助功能,把Terminal或IDE加进去。

坑三:服务器上跑不了

Linux没有Excel,xlwings在上面没法用。定时任务、Docker容器里处理Excel,只能用openpyxl或pandas。


怎么选

场景

用哪个

纯读写,不管格式

pandas

设置样式、合并单元格

openpyxl

数据分析聚合统计

pandas

读公式计算结果

xlwings

执行VBA宏

xlwings

服务器定时任务

openpyxl / pandas

百万行以上超大文件

pandas


真实项目里怎么搭配用

很多项目不是单用一个的。比如每周生成带格式的销售报表这种需求:

代码语言:javascript
复制
importpandasaspd
fromopenpyxlimportload_workbook
fromopenpyxl.stylesimportFont, PatternFill

# pandas 处理数据
df_raw = pd.read_excel("原始数据.xlsx")
df_result = df_raw.groupby("部门").agg({"销售额": "sum"}).reset_index()

# pandas 先写出基础Excel
df_result.to_excel("报表.xlsx", index=False)

# openpyxl 再美化
wb = load_workbook("报表.xlsx")
ws = wb.active

forcellinws[1]:
    cell.font = Font(bold=True, color="FFFFFF")
    cell.fill = PatternFill(start_color="2F75B6", end_color="2F75B6", fill_type="solid")

wb.save("报表_最终.xlsx")

pandas负责数据,openpyxl负责样式。各干各的事,代码也清晰。


最后

三个库不是谁比谁强,就是用途不一样:

openpyxl - 要格式要样式,找它

pandas - 要处理分析数据,找它

xlwings - 要操控Excel本体读公式结果,找它

选错了不是实现不了,是实现起来会很绕。我之前试过用openpyxl读公式结果,搞了两个小时才发现根本就不是这个库该做的事。

你在项目里处理Excel遇到过什么奇葩问题吗?评论区聊聊。

“无他,惟手熟尔”!有需要的用起来!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Nicholas与Pypi 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 先说结论
  • openpyxl:格式控的选择
    • 它能干嘛
    • 踩过的坑
  • pandas:数据处理主力
    • 它能干嘛
    • 踩过的坑
  • xlwings:操控Excel本体
    • 它能干嘛
    • 踩过的坑
  • 怎么选
  • 真实项目里怎么搭配用
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档