如何使用 openpyxl 处理 Excel 工作簿?Workbook 对象介绍
关注 1800
本节并不包含 Microsoft Excel 文件的读取和写入,如果你想了解相关内容,可以查看如何使用 openpyxl 读取和写入 Excel 文件一节。
此外,本节内容也不涉及与 Excel 格式,计算或图表相关的内容。
openpyxl Excel 工作簿对象 Workbook
openpyxl包的Workbook类,对应了我们通常所说的 Excel 工作簿,使用Workbook对象可以获取工作簿的相关信息,或对其中的内容进行操作。
如果正确调用了openpyxl包的load_workbook函数,那么其返回值将是一个Workbook对象。
创建 Excel 工作簿
当你希望创建一个新的 Excel 工作簿时,就需要使用Workbook类的构造器。
Workbook(write_only=False, iso_dates=False)
- write_only 参数
write_only参数表示被创建的工作簿是否是只写的,只写工作簿仅支持整行数据的写入,不支持对单个单元格的操作,默认为False(不是只写的),如果设置为True,那么仅能对Workbook对象执行一次保存操作。- iso_dates 参数
iso_dates参数对应的属性iso_dates,被官方标记为尚未完成。
使用构造器创建的 Workbook 对象可能不包含工作表 Sheet
在默认情况下,使用构造器创建的Workbook对象将拥有一个名称为Sheet的 Excel 工作表。当构造器参数write_only为True时,只写Workbook对象不会包含任何工作表,如果在Workbook对象执行保存操作时依然如此,那么openpyxl将尝试为其添加一个 Excel 工作表。
from openpyxl import Workbook
# 创建一个新的工作簿,默认包含 Sheet 工作表
workbook = Workbook()
print(workbook['Sheet'])
# 只写工作簿不包含任何工作表
write_only_workbook = Workbook(True)
print(write_only_workbook.worksheets)<Worksheet "Sheet">
[]获取和设置当前活动的 Excel 工作表
Workbook对象的active属性,可用于获取或设置 Excel 工作簿当前活动的工作表,在获取当前活动的工作表时,active属性的返回值可能是空值None。
workbook.active
workbook.active = worksheet
- worksheet 值
worksheet是需要设置为活动的Worksheet对象或工作表的索引(int整数类型),0表示第一个工作表,-1表示倒数第一个工作表。
当前活动的 Excel 工作表需要存在且可见
如果将Worksheet对象设置为当前活动的工作表,那么Worksheet对应的工作表应该存在于工作簿中,并且是可见的,否则会抛出异常ValueError: Worksheet is not in the workbook或ValueError: Only visible sheets can be made active。如果通过工作表索引设置当前活动的工作表,则不存在抛出异常的情况,但可能导致Workbook对象的active属性返回空值None,因为索引指示的位置没有工作表。
在 Microsoft Excel 文件School.xlsx中,工作表ClassA,ClassB,ClassC依次排列。
# 请将命令行跳转至 School.xlsx 所在的目录,然后运行此脚本文件
from openpyxl import load_workbook
workbook = load_workbook('School.xlsx')
print(f'当前活动 {workbook.active}')
# 将倒数第一个工作表设置为当前活动的工作表
workbook.active = -1
print(f'当前活动 {workbook.active}')
# 将 ClassB 设置为当前活动的工作表
workbook.active = workbook['ClassB']
print(f'当前活动 {workbook.active}')
# 没有索引为 100 的工作表
workbook.active = 100
print(f'当前活动 {workbook.active}')当前活动 <Worksheet "ClassA">
当前活动 <Worksheet "ClassC">
当前活动 <Worksheet "ClassB">
当前活动 None获取 Excel 工作表
Workbook对象实现了__getitem__方法,你可以方便的使用[]运算符并传递工作表的名称(不支持传递工作表索引),来获取 Excel 工作簿中特定的工作表。如果指定的工作表在工作簿中不存在,那么将导致异常KeyError: 'Worksheet … does not exist.'。
如果需要通过索引或切片表达式,来获取工作簿中的某个或某些工作表,那么可以使用Workbook对象的worksheets属性,该属性返回一个包含所有工作表对象的 Python 列表。
workbook.worksheets[slice]
- slice 值
slice为需要获取的某个工作表的索引,或表示某些工作表的切片表达式。
由于可以采用[]运算符,因此openpyxl已弃用Workbook类的get_sheet_by_name方法。
# 请将命令行跳转至 School.xlsx 所在的目录,然后运行此脚本文件
import openpyxl
workbook = openpyxl.load_workbook('School.xlsx')
# 获取工作表 ClassA
sheet = workbook['ClassA']
print(sheet)
# 获取第二个和其之后的所有工作表
sheets = workbook.worksheets[1:]
print(sheets)<Worksheet "ClassA">
[<Worksheet "ClassB">, <Worksheet "ClassC">]创建 Excel 工作表
如何使用 openpyxl 新建 Excel 工作表视频演示 YouTube如何使用 openpyxl 新建 Excel 工作表视频演示 Bilibili
Workbook对象的create_sheet方法,可用于为 Excel 工作簿创建新的工作表,并将其插入到指定位置,原本位于该位置的工作表将向后移动,如果他存在的话。create_sheet方法的返回值是新工作表对应的Worksheet对象。
workbook.create_sheet(title=None, index=None)
- title 参数
title参数为新工作表的名称(标题),如果省略或设置为None,则新工作表将被命名为Sheet。需要指出,工作表的名称可能拥有一个数字后缀,用于确保其不与其他名称重复。- index 参数
index参数为新工作表在工作簿的插入位置,0表示插入到当前第一个工作表之前,-1表示插入到当前最后一个工作表之前(新的工作表将位于倒数第二)。如果该参数被省略或设置为None,则新工作表将被放置于末尾,如果该参数表示的插入位置不存在工作表,则新的工作表会出现在开头(当index参数为负数时),或出现在末尾(当index参数为正数时)。
由于被创建的Workbook对象,默认拥有一个名称为Sheet的工作表,因此,在未指定名称的情况下,方法create_sheet创建的新工作表将被命名为Sheet1,Sheet2,Sheet3等。
import openpyxl
workbook = openpyxl.Workbook()
# 由于已经存在 Sheet,因此新工作表名称为 Sheet1,他将被放置在末尾
new_sheet1 = workbook.create_sheet()
print(f'新工作表名称 {new_sheet1.title}')
print(f'最后一个工作表的名称 {workbook.worksheets[-1].title}')
# 新工作表名称为 Sheet2,他将被放置在开头
workbook.create_sheet(index=0)
print(f'第一个工作表的名称 {workbook.worksheets[0].title}')
# 新工作表名称为 New,他将被放置在目前倒数第二个工作表 Sheet 之前
new = workbook.create_sheet('New', -2)
print(workbook.worksheets)新工作表名称 Sheet1
最后一个工作表的名称 Sheet1
第一个工作表的名称 Sheet2
[<Worksheet "Sheet2">, <Worksheet "New">, <Worksheet "Sheet">, <Worksheet "Sheet1">]复制 Excel 工作表
Workbook对象的copy_worksheet方法,可用于复制 Excel 工作簿中的工作表,并将得到的工作表副本添加至工作簿的末尾,副本的名称通常以Copy结尾。copy_worksheet方法的返回值是工作表副本对应的Worksheet对象。
workbook.copy_worksheet(from_worksheet)
- from_worksheet 参数
from_worksheet参数为被复制的工作表对应的Worksheet对象。
仅能复制 Workbook 对象自身拥有的 Excel 工作表
copy_worksheet方法仅能复制包含在Workbook对象中的工作表,尝试将其他工作簿对象的工作表传递给参数from_worksheet,会导致异常ValueError: Cannot copy between worksheets from different workbooks。
# 请将命令行跳转至 School.xlsx 所在的目录,然后运行此脚本文件
import openpyxl
workbook = openpyxl.load_workbook('School.xlsx')
# 复制工作表 ClassA
workbook.copy_worksheet(workbook['ClassA'])
print(f'ClassA 副本的名称为 {workbook.worksheets[-1].title}')
# 尝试复制其他工作簿的工作表
newbook = openpyxl.Workbook()
# ERROR 无法复制自身不拥有的工作表
workbook.copy_worksheet(newbook['Sheet'])ClassA 副本的名称为 ClassA Copy
…
ValueError: Cannot copy between worksheets from different workbooks移动 Excel 工作表
Workbook对象的move_sheet方法,可用于移动 Excel 工作簿中的工作表,从而改变工作表之间的顺序。事实上,openpyxl通过先删除后插入来完成工作表的移动,他会计算被移动的工作表的插入位置,并将其放置在插入位置对应的工作表之前。
workbook.move_sheet(sheet, offset=0)
- sheet 参数
sheet参数为需要移动的工作表的名称或其对应的Worksheet对象。- offset 参数
offset参数为工作表插入位置与原索引之间的偏移值,1表示插入位置为原索引加1,-1表示插入位置为原索引减1,使用0的效果相当于不移动。如果插入位置最终为负数,那么移动的效果可能并非你的预期,比如,当 Excel 工作簿拥有多个工作表时,对索引为0的第一个工作表使用-1,他会被放置在倒数第二的位置,而不是倒数第一,这与使用create_sheet方法所产生的效果类似。
在移动工作表ClassA之后,工作表ClassB将位于开头,此时指定参数offset为-1,会使ClassB被移动至倒数第二的位置,因为计算的插入位置为-1,即倒数第一的ClassA之前。
# 请将命令行跳转至 School.xlsx 所在的目录,然后运行此脚本文件
from openpyxl import open
workbook = open('School.xlsx')
print(workbook.worksheets)
# 工作表 ClassA 将位于末尾
workbook.move_sheet('ClassA', 100)
print(workbook.worksheets)
# 当前第一个工作表 ClassB 将被移动至倒数第二的位置
b = workbook['ClassB']
workbook.move_sheet(b, -1)
print(workbook.worksheets)[<Worksheet "ClassA">, <Worksheet "ClassB">, <Worksheet "ClassC">]
[<Worksheet "ClassB">, <Worksheet "ClassC">, <Worksheet "ClassA">]
[<Worksheet "ClassC">, <Worksheet "ClassB">, <Worksheet "ClassA">]移除 Excel 工作表
使用Workbook对象的remove方法,或使用del关键字和[]运算符,并给出工作表的名称,可移除 Excel 工作簿中的工作表。
workbook.remove(worksheet)
del workbook[name]
- worksheet 参数
worksheet参数为需要移除的工作表对应的Worksheet对象。- name 值
name为需要移除的工作表的名称。
openpyxl已弃用Workbook类的remove_sheet方法。
# 请将命令行跳转至 School.xlsx 所在的目录,然后运行此脚本文件
from openpyxl import open
workbook = open('School.xlsx')
# 删除工作表 ClassA,ClassB
del workbook['ClassA']
workbook.remove(workbook['ClassB'])
print(workbook.worksheets)[<Worksheet "ClassC">]获取 Excel 工作表的名称和索引
Workbook对象的sheetnames属性,返回一个包含所有 Excel 工作表名称的 Python 列表。
workbook.sheetnames[slice]
- slice 值
slice为需要获取名称的某个或某些工作表的索引或切片表达式。
openpyxl已弃用Workbook类的get_sheet_names方法。
Workbook对象的index方法,可用于获取指定 Excel 工作表在工作簿中的索引,第一个工作表的索引为0。
workbook.index(worksheet)
- worksheet 参数
worksheet参数为需要获取索引的工作表对应的Worksheet对象。
openpyxl已弃用Workbook类的get_index方法。
# 请将命令行跳转至 School.xlsx 所在的目录,然后运行此脚本文件
from openpyxl import load_workbook
workbook = load_workbook('School.xlsx')
# 获取工作表的名称和索引
print(f'第二个工作表的名称 {workbook.sheetnames[1]}')
print(f'工作表 ClassC 的索引 {workbook.index(workbook["ClassC"])}')第二个工作表的名称 ClassB
工作表 ClassC 的索引 2获取 Excel 工作簿的日期系统
Workbook对象的excel_base_date属性或epoch属性,可用于获取 Excel 工作簿日期系统的开始日期。
workbook.excel_base_date
什么是 Excel 工作簿的日期系统?
每一个工作簿都指定了自己的日期系统,不同的日期系统具有不同的开始日期,Excel 会将日期计算为相对于开始日期的偏移值,因此,同一日期在不同日期系统中存储的数据并不相同。
# 请将命令行跳转至 1904.xlsx 所在的目录,然后运行此脚本文件
from openpyxl import load_workbook
workbook = load_workbook('1904.xlsx')
# 获取工作簿的日期系统
print(workbook.excel_base_date)1904-01-01 00:00:00判断 Excel 工作簿是否为模板
Workbook拥有类变量template和实例变量is_template,他们的值始终为True,官方似乎没有阐明其具体作用,因此template和is_template不能用于判断 Excel 工作簿是否是一个模板,你需要使用Workbook对象的mime_type属性来完成此目标,该属性用来说明工作簿的 MIME 类型,当其包含template时,可将工作簿视为模板。
workbook.mime_type
# 请将命令行跳转至 Hello.xltx 所在的目录,然后运行此脚本文件
from openpyxl import load_workbook
workbook = load_workbook('Hello.xltx')
# 工作簿是否为模板?
print('template' in workbook.mime_type)TrueWorkbook 对象的其他特性
以下是与Workbook对象相关,但不太重要的一些特性,这些特性可能并非从 Microsoft Excel 文件获取,只是由openpyxl包给出了固定值。
- encoding 变量
encoding变量用于表示工作簿的编码,他被指定为'utf-8'。- path 变量
Excel 文件本身是一个压缩文件,
Workbook对象的path变量表示其在压缩文件中的路径,他被指定为'/xl/workbook.xml'。- vba_archive 变量
vba_archive变量是一个ZipFile对象,表示与 VBA 相关的压缩文件,该压缩文件包含在 Excel 文件中,通常的名称为vbaProject.bin。- data_only,read_only,write_only 属性
data_only,read_only,write_only属性是只读的,他们由读取 Excel 文件或创建Workbook对象时给出的实参来决定,由于相关文章已经进行了讲解,这里不再累述。
源码
src/zh/openpyxl/workbooks·codebeatme/office-programming·GitHub
讲解视频
如何使用 openpyxl 新建 Excel 工作表·YouTube如何使用 openpyxl 新建 Excel 工作表·Bilibili