当前位置:首页>python>Python零基础入门(十二):Python操作Excel

Python零基础入门(十二):Python操作Excel

  • 2026-09-08 11:25:51
Python零基础入门(十二):Python操作Excel

‍

上次同事扔给我一个需求:把 200 个 Excel 文件里的销售数据汇总到一张表。

我问他之前怎么做的,他说手动复制粘贴。

200 个文件。手动。

我打开编辑器,写了不到 30 行代码,10 秒跑完。他看我的眼神像看外星人。

今天就把这套方法讲透,你也能做到。

为什么选 openpyxl?

Python 操作 Excel 的库有好几个,我直接说结论:选 openpyxl,别犹豫。

  • • xlrd:只读,而且从 2.0 版本开始不再支持 .xlsx 格式,基本废了
  • • pandas:适合做数据分析,但精细操作单元格格式很别扭
  • • openpyxl:读写都行,支持 .xlsx,能控制样式、公式、图表

安装就一行:

pip install openpyxl

装完就能用,不需要额外配置。

先搞懂 Excel 的"术语"

操作 Excel 之前,得先知道代码里的东西对应表格里的哪个位置。很多人上来就写代码,结果被 Workbook、Worksheet 搞晕了,其实就是这么回事:

代码里的叫法
Excel 里对应什么
一句话解释
Workbook
整个工作簿(一个 .xlsx 文件)
一个文件 = 一个 Workbook
Worksheet
工作表(底部的 Sheet 标签)
Sheet1、Sheet2 那些
Cell
单个单元格
A1、B3 那些格子
Row
一行
横着的那一排
Column
一列
竖着的那一列

记住这个对应关系,后面看代码就不会懵。

读写基础:5 分钟上手

创建并写入一个 Excel

这是最简单的例子——新建一个文件,往里面填点东西:

from openpyxl import Workbookwb = Workbook()                    # 新建工作簿ws = wb.active                     # 拿到默认的 Sheetws['A1'] = '姓名'                  # 直接往单元格里塞值ws['B1'] = '销售额'ws['A2'] = '张三'ws['B2'] = 15000wb.save('demo.xlsx')              # 保存,完事

跑完之后,当前目录下会多一个 demo.xlsx,打开就能看到数据。

读取已有的 Excel

from openpyxl import load_workbookwb = load_workbook('demo.xlsx')    # 打开文件ws = wb.active                     # 拿到当前活动 Sheet# 逐行读取,values_only=True 直接拿值,不加的话拿到的是 Cell 对象for row in ws.iter_rows(min_row=1, max_row=2, values_only=True):    print(row)# 输出:# ('姓名', '销售额')# ('张三', 15000)

values_only=True 这个参数很关键。不加它,你拿到的是一堆 Cell 对象,还得再调 .value 才能拿到值。加了省一半代码。

筛选数据:只拿你要的行

真实场景下,表格里几百上千行数据,你不可能全要。

比如有一张销售表,只要销售额超过 10000 的记录:

from openpyxl import load_workbookwb = load_workbook('sales.xlsx')ws = wb.activeresults = []for row in ws.iter_rows(min_row=2, values_only=True):  # 跳过表头    name, amount = row[0], row[1]    if amount > 10000:              # 条件筛选        results.append((name, amount))print(f'符合条件的记录:{len(results)} 条')for name, amount in results:    print(f'  {name}: {amount}')

注意 min_row=2——跳过第一行表头,不然表头也会被当成数据参与筛选。这个坑我踩过,当时 name 列的值全是 "姓名",查了半天。

如果你想更灵活地筛选,可以封装一个通用函数,以后各种筛选条件都能复用:

def filter_rows(ws, condition, min_row=2):    """传入一个条件函数,返回满足条件的所有行"""    return [row for row in ws.iter_rows(min_row=min_row, values_only=True)            if condition(row)]# 用法:筛选销售额 > 10000 的行high_sales = filter_rows(ws, lambda r: r[1] and r[1] > 10000)

数据批量转换:改完直接写回去

另一个高频需求:批量修改数据。

比如所有销售额要换成美元(假设汇率 7.2),直接在原表上改:

from openpyxl import load_workbookwb = load_workbook('sales.xlsx')ws = wb.activerate = 7.2for row in ws.iter_rows(min_row=2, max_col=2):  # 遍历每行的前两列    cell = row[1]                                 # B 列(销售额)    if cell.value and isinstance(cell.value, (int, float)):        cell.value = round(cell.value / rate, 2)  # 换算并保留两位小数wb.save('sales_usd.xlsx')  # 另存一份,别覆盖原文件

踩坑提醒:iter_rows() 返回的是 Cell 对象,直接改 cell.value 就能修改内容。但一定要先判断 cell.value 不是 None,不然会报 TypeError。

还有个常见场景——日期格式统一。不同人填的日期五花八门,"2024/6/15"、"2024-6-15"、"6月15日" 都有,批量统一一下:

from datetime import datetimefor row in ws.iter_rows(min_row=2, max_col=3):    cell = row[2]  # C 列是日期    if isinstance(cell.value, str):        cell.value = datetime.strptime(cell.value, '%Y/%m/%d')        cell.number_format = 'YYYY-MM-DD'  # 统一显示格式

常用函数与公式

Excel 最强的地方是公式,openpyxl 也能往单元格里写公式,打开文件时 Excel 会自动计算:

ws['C1'] = '合计'ws['C2'] = '=SUM(B2:B100)'         # 求和ws['D1'] = '平均值'ws['D2'] = '=AVERAGE(B2:B100)'     # 平均值ws['E1'] = '最大值'ws['E2'] = '=MAX(B2:B100)'         # 最大值

但有个坑:openpyxl 自己不会算公式。你读取一个带公式的单元格,拿到的是公式字符串,不是计算结果。

解决方案有两种:

# 方法一:用 data_only 模式读取(需要先用 Excel 打开并保存过一次)wb = load_workbook('sales.xlsx', data_only=True)print(wb.active['C2'].value)  # 拿到的是上次保存时的计算结果# 方法二:让 Python 自己算amounts = [row[1] for row in ws.iter_rows(min_row=2, max_col=2, values_only=True)]total = sum(x for x in amounts if isinstance(x, (int, float)))print(f'合计: {total}')

如果公式计算是刚需而且很复杂,别用 openpyxl 硬扛,用 xlwings 调用 Excel 自己的计算引擎更靠谱。

完整实战:汇总多个 Excel 文件

回到开头的需求——200 个文件汇总。核心代码就这些:

from openpyxl import Workbook, load_workbookfrom pathlib import Pathdef merge_excels(folder, output='汇总.xlsx'):    """把文件夹里所有 Excel 的数据汇总到一张表"""    wb_out = Workbook()    ws_out = wb_out.active    ws_out.append(['文件名', '姓名', '销售额', '日期'])  # 写表头    files = list(Path(folder).glob('*.xlsx'))    for f in files:        if f.name == output:        # 跳过输出文件本身            continue        wb = load_workbook(f)        ws = wb.active        for row in ws.iter_rows(min_row=2, values_only=True):            ws_out.append([f.name] + list(row))  # 每行前面加个文件名    wb_out.save(output)    print(f'搞定,共汇总 {len(files)} 个文件')merge_excels('./销售数据/')

扔到文件夹上跑一下,几秒钟的事。

写在最后

Python 操作 Excel 这件事,会了就是生产力翻倍,不会就是加班到头秃。

openpyxl 覆盖了 90% 的日常需求,剩下 10% 的复杂场景(比如需要调用 Excel 宏、处理超大数据量),后面再单独讲。

留个问题给你:如果你要处理的不是.xlsx,而是.xls甚至.csv,该怎么办?  评论区聊聊。

最新文章

随机文章