openpyxl全面教程:常用 API 串联与实战指南

155 阅读10分钟

大家好,我是jobleap.cn的小九。 openpyxl 是 Python 中处理 Excel 2007+ 格式(.xlsx/.xlsm)的核心库,支持工作簿、工作表、单元格的全维度操作,包括数据读写、样式设置、公式计算、图表生成等,是自动化处理 Excel 的首选工具。本文将系统梳理 openpyxl 所有常用 API,并通过实战案例串联核心用法,帮助你一站式掌握。

一、前置准备:安装与核心概念

1. 安装 openpyxl

pip install openpyxl  # 基础安装
# 如需处理图片(可选),额外安装:pip install openpyxl[image]

2. 核心概念

  • Workbook(工作簿):整个 Excel 文件,一个 Workbook 包含多个 Worksheet。
  • Worksheet(工作表):工作簿中的单个表格(如 Sheet1),是数据操作的核心载体。
  • Cell(单元格):工作表的最小单元,通过行/列索引或坐标(如 A1)定位。

二、核心 API 详解与基础操作

1. 工作簿(Workbook)操作

(1)创建新工作簿

from openpyxl import Workbook

# 创建空白工作簿(默认包含一个名为 Sheet 的工作表)
wb = Workbook()
# 查看所有工作表名称
print(wb.sheetnames)  # 输出: ['Sheet']

(2)打开已有工作簿

from openpyxl import load_workbook

# 打开现有文件(data_only=True 表示读取公式计算后的结果,而非公式本身)
wb = load_workbook("销售报表.xlsx", data_only=True, read_only=False)
# read_only=True:只读模式,适合处理超大文件,内存占用低(但部分写操作不可用)

(3)保存与关闭工作簿

# 保存(新文件直接命名,已有文件覆盖)
wb.save("销售报表.xlsx")
# 关闭工作簿(释放文件锁,避免文件被占用)
wb.close()

2. 工作表(Worksheet)操作

工作表是数据操作的核心,所有单元格操作都基于工作表对象。

(1)选择工作表

# 方式1:通过名称选择(推荐)
ws = wb["Sheet"]
# 方式2:选择当前激活的工作表
ws = wb.active
# 方式3:遍历所有工作表
for sheet in wb.worksheets:
    print(f"工作表名称:{sheet.title}")

(2)新建/重命名/删除工作表

# 新建工作表(参数1:名称;参数2:位置,0 表示第一个)
ws_new = wb.create_sheet("2025年销售数据", 0)
# 重命名工作表
ws_new.title = "2025销售报表"
# 复制工作表(仅复制数据和样式,不复制图表/筛选等)
ws_copy = wb.copy_worksheet(ws_new)
ws_copy.title = "2025销售报表-副本"
# 移动工作表(offset=1 右移1位,负数左移)
wb.move_sheet(ws_new, offset=1)
# 删除工作表
wb.remove(ws_copy)  # 或 del wb[ws_copy.title]

3. 单元格(Cell)操作

单元格是数据存储的最小单元,支持精准定位、赋值、取值等操作。

(1)单元格定位

# 方式1:坐标定位(最常用)
cell_a1 = ws["A1"]
# 方式2:行/列索引定位(row=行号,column=列号,均从1开始)
cell_a1 = ws.cell(row=1, column=1)
# 方式3:批量定位单元格区域
cell_range = ws["A1:C5"]  # A1到C5的所有单元格
row_range = ws[2:5]       # 第2行到第5行的所有单元格
col_range = ws["B:D"]     # B列到D列的所有单元格

(2)单元格赋值与取值

# 直接赋值
ws["A1"] = "2025年销售报表"  # 文本
ws["B2"] = "产品A"           # 文本
ws["C2"] = 15800.5           # 数值
ws["D2"] = "2025-01-01"      # 日期
# 通过 cell 对象赋值
ws.cell(row=1, column=1, value="2025年销售报表")

# 取值
value_a1 = ws["A1"].value
value_c2 = ws.cell(row=2, column=3).value
print(f"A1单元格值:{value_a1},C2单元格值:{value_c2}")

# 批量赋值(按行赋值)
ws["A2:D2"] = ["日期", "产品名称", "销售额(元)", "区域"]
# 批量赋值(循环赋值)
sales_data = [
    ("2025-01-01", "产品A", 15800.5, "华东"),
    ("2025-01-02", "产品B", 23400.8, "华北"),
    ("2025-01-03", "产品C", 18900.0, "华南")
]
for row_idx, row_data in enumerate(sales_data, start=3):  # 从第3行开始
    ws.cell(row=row_idx, column=1, value=row_data[0])
    ws.cell(row=row_idx, column=2, value=row_data[1])
    ws.cell(row=row_idx, column=3, value=row_data[2])
    ws.cell(row=row_idx, column=4, value=row_data[3])

(3)单元格属性

cell = ws["C3"]
print(f"单元格坐标:{cell.coordinate}")  # 输出: C3
print(f"行号:{cell.row}")              # 输出: 3
print(f"列号:{cell.column}")           # 输出: 3
print(f"数据类型:{cell.data_type}")    # 输出: n(数值)/s(文本)/d(日期)

4. 单元格样式设置

样式是 Excel 美化的核心,需导入 openpyxl.styles 中的类。

from openpyxl.styles import Font, Alignment, Border, Side, PatternFill, NamedStyle

# 1. 字体样式(名称、大小、加粗、颜色)
title_font = Font(name="微软雅黑", size=16, bold=True, color="FFFFFF")  # 白色加粗
normal_font = Font(name="微软雅黑", size=12)

# 2. 对齐样式(水平居中、垂直居中、自动换行)
center_align = Alignment(horizontal="center", vertical="center", wrap_text=True)

# 3. 边框样式(细边框、黑色)
thin_side = Side(style="thin", color="000000")  # style可选:thin/thick/dashed/dotted
border = Border(
    left=thin_side, right=thin_side,
    top=thin_side, bottom=thin_side
)

# 4. 填充样式(纯色填充)
title_fill = PatternFill(start_color="2E86AB", end_color="2E86AB", fill_type="solid")  # 蓝色填充
data_fill = PatternFill(start_color="F2F2F2", end_color="F2F2F2", fill_type="solid")   # 浅灰色填充

# 5. 数字格式(销售额保留2位小数,日期格式)
ws["C3"].number_format = "#,##0.00"  # 千分位+2位小数
ws["A3"].number_format = "YYYY-MM-DD"  # 日期格式

# 6. 批量应用样式(表头A1:D1)
ws["A1"].font = title_font
ws["A1"].alignment = center_align
ws["A1"].fill = title_fill
ws["A1:D1"].border = border  # 批量设置边框
# 批量应用样式到数据区域
for row in ws["A2:D5"]:
    for cell in row:
        cell.font = normal_font
        cell.alignment = center_align
        cell.border = border
        if cell.column == 3:  # 销售额列
            cell.number_format = "#,##0.00"

5. 数据进阶操作

(1)行/列插入与删除

# 在第3行前插入1行
ws.insert_rows(3)
# 在第2列前插入2列
ws.insert_cols(2, amount=2)
# 删除第10行
ws.delete_rows(10)
# 删除第4列
ws.delete_cols(4)

(2)合并/取消合并单元格

# 合并A1:D1单元格(表头合并)
ws.merge_cells("A1:D1")
# 取消合并
ws.unmerge_cells("A1:D1")

(3)冻结窗格

冻结指定单元格上方/左侧的区域,方便滚动查看数据:

# 冻结B3单元格上方(第1-2行)和左侧(A列)的区域
ws.freeze_panes = "B3"
# 取消冻结
ws.freeze_panes = None

(4)添加筛选

# 为数据区域(A2:D5)添加自动筛选
ws.auto_filter.ref = "A2:D5"  # 或 ws.dimensions(整个工作表数据区域)

6. 公式与函数操作

openpyxl 支持插入 Excel 原生公式,需注意公式语法与 Excel 一致(英文逗号分隔)。

# 1. 插入求和公式(计算C3:C5的总销售额,写入C6)
ws["C6"] = "=SUM(C3:C5)"
# 2. 插入平均值公式(写入C7)
ws["C7"] = "=AVERAGE(C3:C5)"

# 3. 读取公式计算结果(需打开文件时设置 data_only=True)
wb = load_workbook("销售报表.xlsx", data_only=True)
ws = wb.active
total_sales = ws["C6"].value
print(f"总销售额:{total_sales}")

7. 图表生成

openpyxl 支持插入柱状图、折线图、饼图等,以柱状图为例:

from openpyxl.chart import BarChart, Reference
from openpyxl.chart.label import DataLabelList

# 1. 创建柱状图对象
chart = BarChart()
chart.type = "col"  # 柱形图(bar为条形图)
chart.style = 10    # 内置样式

# 2. 定义数据区域(销售额列:C3:C5)
values = Reference(
    ws,
    min_col=3,    # 起始列
    min_row=2,    # 起始行(包含表头)
    max_col=3,    # 结束列
    max_row=5     # 结束行
)
# 3. 定义分类轴(产品名称列:B3:B5)
categories = Reference(
    ws,
    min_col=2,
    min_row=3,
    max_row=5
)

# 4. 配置图表
chart.add_data(values, titles_from_data=True)  # 从数据表头获取系列名称
chart.set_categories(categories)              # 设置X轴分类
chart.title = "2025年1月产品销售额"           # 图表标题
chart.y_axis.title = "销售额(元)"            # Y轴标题
chart.x_axis.title = "产品名称"                # X轴标题
# 显示数据标签
chart.dataLabels = DataLabelList()
chart.dataLabels.showVal = True

# 5. 将图表插入工作表(位置E3)
ws.add_chart(chart, "E3")

三、实战综合案例:制作完整销售报表

以下案例串联所有常用 API,实现「创建工作簿→写入数据→设置样式→公式计算→生成图表→保存文件」全流程:

from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, Border, Side, PatternFill
from openpyxl.chart import BarChart, Reference
from openpyxl.chart.label import DataLabelList

# 步骤1:创建工作簿并初始化工作表
wb = Workbook()
ws = wb.active
ws.title = "2025年1月销售报表"

# 步骤2:定义样式
# 表头样式
title_font = Font(name="微软雅黑", size=16, bold=True, color="FFFFFF")
title_fill = PatternFill(start_color="2E86AB", end_color="2E86AB", fill_type="solid")
center_align = Alignment(horizontal="center", vertical="center")
thin_side = Side(style="thin", color="000000")
border = Border(left=thin_side, right=thin_side, top=thin_side, bottom=thin_side)
# 数据样式
normal_font = Font(name="微软雅黑", size=12)
data_fill = PatternFill(start_color="F2F2F2", end_color="F2F2F2", fill_type="solid")

# 步骤3:写入表头并合并单元格
ws["A1"] = "2025年1月销售报表"
ws.merge_cells("A1:D1")
ws["A1"].font = title_font
ws["A1"].fill = title_fill
ws["A1"].alignment = center_align
ws["A1"].border = border

# 步骤4:写入二级表头
ws["A2:D2"] = ["日期", "产品名称", "销售额(元)", "区域"]
for cell in ws["A2:D2"]:
    cell.font = normal_font
    cell.alignment = center_align
    cell.border = border
    cell.fill = data_fill

# 步骤5:写入销售数据
sales_data = [
    ("2025-01-01", "产品A", 15800.5, "华东"),
    ("2025-01-02", "产品B", 23400.8, "华北"),
    ("2025-01-03", "产品C", 18900.0, "华南"),
    ("2025-01-04", "产品D", 21500.2, "西南")
]
for row_idx, row_data in enumerate(sales_data, start=3):
    for col_idx, value in enumerate(row_data, start=1):
        cell = ws.cell(row=row_idx, column=col_idx, value=value)
        cell.font = normal_font
        cell.alignment = center_align
        cell.border = border
        # 销售额列设置数值格式
        if col_idx == 3:
            cell.number_format = "#,##0.00"
        # 日期列设置格式
        if col_idx == 1:
            cell.number_format = "YYYY-MM-DD"

# 步骤6:插入求和公式(计算总销售额)
ws["C7"] = "总销售额"
ws["D7"] = "=SUM(C3:C6)"
ws["D7"].number_format = "#,##0.00"
ws["D7"].font = normal_font
ws["D7"].alignment = center_align
ws["D7"].border = border

# 步骤7:设置冻结窗格和筛选
ws.freeze_panes = "B3"  # 冻结表头
ws.auto_filter.ref = "A2:D6"  # 数据区域添加筛选

# 步骤8:生成销售额柱状图
chart = BarChart()
chart.type = "col"
chart.style = 10
# 数据区域
values = Reference(ws, min_col=3, min_row=2, max_col=3, max_row=6)
# 分类轴
categories = Reference(ws, min_col=2, min_row=3, max_row=6)
# 配置图表
chart.add_data(values, titles_from_data=True)
chart.set_categories(categories)
chart.title = "产品销售额对比"
chart.y_axis.title = "销售额(元)"
chart.x_axis.title = "产品名称"
chart.dataLabels = DataLabelList()
chart.dataLabels.showVal = True
# 插入图表
ws.add_chart(chart, "F3")

# 步骤9:保存并关闭工作簿
wb.save("2025年1月销售报表.xlsx")
wb.close()
print("销售报表生成完成!")

四、注意事项与最佳实践

  1. 文件锁问题:操作完成后务必调用 wb.close(),否则Excel文件会被锁定,无法手动编辑。
  2. 超大文件处理:使用 load_workbook(read_only=True) 只读模式,配合逐行遍历(for row in ws.iter_rows()),减少内存占用。
  3. 公式读取:需打开文件时设置 data_only=True,但仅能读取已计算的结果(需先手动打开文件并保存一次)。
  4. 样式批量应用:优先使用循环或 NamedStyle 批量设置样式,避免逐个单元格设置,提升效率。
  5. 兼容性:openpyxl 不支持 .xls 格式(Excel 97-2003),如需处理可使用 xlrd/xlwt 库。

五、总结

openpyxl 覆盖了 Excel 操作的全场景,核心 API 可归纳为「工作簿→工作表→单元格」三层结构,配合样式、公式、图表等进阶功能,能满足自动化生成报表、数据清洗、批量处理等绝大多数业务需求。本文的综合案例串联了所有常用 API,你可基于此案例扩展(如批量导入数据、生成多工作表报表、添加折线图等),快速适配实际业务场景。