添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

如何使用 Python openpyxl 包操作 Excel 区域?openpyxl CellRange 对象介绍

我被代码海扁
阅读 18:47 · 字数 5637 · 发布

Python openpyxl 包中的 Excel 区域对象 CellRange

Python openpyxl 包中的 CellRange 类,属于模块 openpyxl.worksheet.cell_range ,表示 Excel 工作表中的区域,可以在移动区域的操作中指定需要移动的区域。 openpyxl 包中的 MultiCellRange 类,同样属于模块 openpyxl.worksheet.cell_range ,可表示 Excel 工作表中的多个区域。

Python openpyxl 包中的 MergedCellRange 类,属于模块 openpyxl.worksheet.merge ,继承自 CellRange ,可用于表示 Excel 工作表中被合并的单元格区域,他拥有本文讲述的 CellRange 对象的所有特性。

使用 Python openpyxl 包的 CellRange 对象创建 Excel 区域

你并不需要主动创建 openpyxl 包的 CellRange 对象,大多数情况下,使用 Excel 区域的地址可以达成相同的目标,比如,在移动某个区域时,将字符串 'A1:C3' 作为参数。如果确实需要 Python openpyxl 包的 CellRange 类的实例,那么其构造器如下。

CellRange ( range_string=None, min_col=None, min_row=None, max_col=None, max_row=None, title=None )

range_string 参数

range_string 参数为 Excel 区域的地址(表达式),如果该参数被省略或为 None ,那么需要提供参数 min_col min_row max_col max_row

min_col 参数

min_col 参数是一个整数,用于说明 Excel 区域开始于第几列, 1 表示第一列。

min_row 参数

min_row 参数是一个整数,用于说明 Excel 区域开始于第几行, 1 表示第一行。

max_col 参数

max_col 参数是一个整数,用于说明 Excel 区域结束于第几列, 1 表示第一列。

max_row 参数

max_row 参数是一个整数,用于说明 Excel 区域结束于第几行, 1 表示第一行。

title 参数

title 参数用于指定 Excel 区域所在的工作表,如果该参数被省略或为 None ,那么 Excel 区域属于当前工作表。

Python openpyxl 包的 CellRange 对象的变量

Python openpyxl 包的 CellRange 对象拥有变量 min_col min_row max_col max_row title ,在未作出修改时,他们的值与传递给 CellRange 构造器的实参的值相同。

openpyxl 包的 CellRange 对象所表示的 Excel 区域的最大行和最大列不能小于最小行和最小列

无论你是否为 Python openpyxl 包的 CellRange 对象指定了参数 range_string CellRange 对象的 max_row max_col 变量都不应该小于 min_row min_col 变量,否则可能会引发异常 ValueError: … must be greater than …

openpyxl 包的 Worksheet 对象的 move_range 方法将忽略 CellRange 对象的 title 变量

Python openpyxl 包的 CellRange 对象的 title 变量,会被 Worksheet 对象的 move_range 方法忽视,这表示通过某个 Worksheet 对象来移动另一个 Excel 工作表中的区域是不可行的。

Excel 文件 Data.xlsx 包含了两个工作表 Fruit Trees ,虽然在创建 CellRange 对象时,我们指定了参数 title ,但 move_range 方法并不会移动工作表 Trees 中的区域。

move.py
# 读取 Excel 文件 Data.xlsx 中的工作表 Fruit
from openpyxl import load_workbook
wb = load_workbook('Data.xlsx')
ws = wb['Fruit']
from openpyxl.worksheet.cell_range import CellRange
# 创建区域 Trees!A1:B2,其中 Trees 不会发挥作用
range = CellRange(min_col=1, min_row=1, max_col=2, max_row=2, title='Trees')
# 移动工作表 Fruit 的区域 A1:B2,而不是工作表 Trees
ws.move_range(range, 1, 1)
wb.save('Move.xlsx')

获取 Python openpyxl 包的 CellRange 对象所表示的 Excel 区域的边界和地址

Python openpyxl 包的 CellRange 对象的 bounds 属性,可以获取 CellRange 对象所表示的 Excel 区域的边界,其返回值是一个依次包含变量 min_col min_row max_col max_row 的 Python 元组,即区域的最小列,最小行,最大列,最大行。

Python openpyxl 包的 CellRange 对象的 top bottom left right 属性,可以获取 CellRange 对象所表示的 Excel 区域的最上方的一行,最下方的一行,最左边的一列,最右边的一列的单元格的位置信息。他们的返回值是一个 Python 列表,列表中包含了一系列格式为 (x,y) 的元组,其中 x 表示单元格位于哪一行, y 表示单元格位于哪一列。

cellrange . bounds
cellrange . top
cellrange . bottom
cellrange . left
cellrange . right

Python openpyxl 包的 CellRange 对象的 coord 属性,可以获取 CellRange 对象所表示的 Excel 区域的地址(比如, A1:C3 ),该地址不包含 title 变量所表示的 Excel 工作表名称。

cellrange . coord

range.py
from openpyxl.worksheet.cell_range import CellRange
# 创建区域 B2:D4
range = CellRange('B2:D4')
# 显示区域的边界
print(range.bounds)
print(f'最上方一行的单元格的位置信息 {range.top}')
print(f'最下方一行的单元格的位置信息 {range.bottom}')
print(f'最左边一行的单元格的位置信息 {range.left}')
print(f'最右边一行的单元格的位置信息 {range.right}')
# 创建区域 C2:J4,工作表名称为 SheetA
range = CellRange(min_col=3, min_row=2, max_col=10, max_row=4, title='SheetA')
# 显示区域的地址
print(range.coord)
(2, 2, 4, 4)
最上方一行的单元格的位置信息 [(2, 2), (2, 3), (2, 4)]
最下方一行的单元格的位置信息 [(4, 2), (4, 3), (4, 4)]
最左边一行的单元格的位置信息 [(2, 2), (3, 2), (4, 2)]
最右边一行的单元格的位置信息 [(2, 4), (3, 4), (4, 4)]
C2:J4

获取和设置 Python openpyxl 包的 CellRange 对象所表示的 Excel 区域的大小

你可以简单的通过 CellRange 对象的变量 min_col min_row max_col max_row ,来获取或设置 CellRange 对象所表示的 Excel 区域的大小,不过, CellRange 的以下特性可实现相同的效果。

Python openpyxl 包的 CellRange 对象的 size 属性,可以获取 CellRange 对象所表示的 Excel 区域的大小(区域包含的行和列的个数),其返回值是一个格式为 {'columns':cs,'rows':rs} 的 Python 字典对象,其中 cs 为 Excel 区域包含的列的数量, rs 为 Excel 区域包含的行的数量。

cellrange . size

Python openpyxl 包的 CellRange 对象的 expand shrink 方法,可用于改变 CellRange 对象所表示的 Excel 区域的大小,其中 expand 方法可以扩展 Excel 区域, shrink 方法可以缩小 Excel 区域。

cellrange . expand ( right=0, down=0, left=0, up=0 )
cellrange . shrink ( right=0, bottom=0, left=0, top=0 )

right 参数

right 参数为 Excel 区域最右边一列向外或向内移动的列数,设置为负数表示反向操作。

down,bottom 参数

down bottom 参数为 Excel 区域最下方一行向外或向内移动的行数,设置为负数表示反向操作。

left 参数

left 参数为 Excel 区域最左边一列向外或向内移动的列数,设置为负数表示反向操作。

up,top 参数

up top 参数为 Excel 区域最上方一行向外或向内移动的行数,设置为负数表示反向操作。

size.py
from openpyxl.worksheet.cell_range import CellRange
# 创建区域 B2:D4
range = CellRange('B2:D4')
# 显示区域大小
print(range.size)
# 最右边列向内移动 1 列,最下边行向外移动 1 行,最左边列向外移动 1 列,最上边行向内移动 1 行
range.expand(-1, 1, 1, -1)
print(range.coord)
# 最右边列向外移动 1 列,最下边行向内移动 1 行,最左边列向内移动 1 列,最上边行向外移动 1 行
range.shrink(-1, 1, 1, -1)
print(range.coord)
{'columns': 3, 'rows': 3}
A3:C5
B2:D4

遍历 Python openpyxl 包的 CellRange 对象所表示的 Excel 区域中的单元格

当然,要遍历 Excel 工作表中的单元格,最好最简便的方法是使用 openpyxl 包的 Worksheet 对象的 [] 运算符,不过,你依然可以借助 Python openpyxl 包的 CellRange 对象的 rows cols cells 属性来完成相同的任务。

不同于 Worksheet 对象的 [] 运算符, CellRange 对象的 rows cols 属性返回的是一个可按照行或列遍历单元格位置的 Python 生成器对象,每一行或每一列将作为一个 Python 列表存在,每个列表都包含一系列格式为 (x,y) 的元组,其中 x 表示单元格位于哪一行, y 表示单元格位于哪一列。

openpyxl 包的 CellRange 对象的 cells 属性的返回值是一个 itertools.product 对象,该对象包含了 Excel 区域内所有单元格的位置信息,这些位置信息的顺序与 rows 属性相同,只不过他们不再按照行来进行划分(每一行作为一个 Python 列表)。

cellrange . rows
cellrange . cols
cellrange . cells

工作表

关于如何获取 Excel 单元格,你可以查看 使用 Python openpyxl 包的 Worksheet 对象获取 Excel 单元格 一段。

在下面的代码中,我们通过 CellRange 对象的 rows cells 属性遍历了区域内的 Excel 单元格,其中 cells 不需要再次使用 for 语句。

iterate.py
# 读取 Excel 文件 Data.xlsx 中的工作表 Trees
from openpyxl import load_workbook
wb = load_workbook('Data.xlsx')
ws = wb['Trees']
from openpyxl.worksheet.cell_range import CellRange
# 创建区域 A1:B2
range = CellRange('A1:B2')
# 借助 CellRange 的 row 属性遍历单元格
for row in range.rows:
	# x 和 y 分别表示单元格位于哪一行和哪一列
	for x, y in row:
		c = ws.cell(x, y)
		print(f'{c.coordinate}={c.value}')
# 借助 CellRange 的 cells 属性遍历单元格
for x, y in range.cells:
	c = ws.cell(x, y)
	print(f'({x}, {y})={c.value}')
A1=苹果树
B1=10
A2=梨树
B2=20
(1, 1)=苹果树
(1, 2)=10
(2, 1)=梨树
(2, 2)=20

移动 Python openpyxl 包的 CellRange 对象所表示的 Excel 区域的位置

Python openpyxl 包的 CellRange 对象的 shift 方法,可用于移动 CellRange 对象所表示的 Excel 区域。

cellrange . shift ( col_shift=0, row_shift=0 )

col_shift 参数

col_shift 参数为 Excel 区域移动的列数, 1 表示向右移动一列, -1 表示向左移动一列。

row_shift 参数

row_shift 参数为 Excel 区域移动的行数, 1 表示向下移动一行, -1 表示向上移动一行。

不能将 openpyxl 包的 CellRange 对象所表示的 Excel 区域移动到工作表之外

如果给出的 col_shift row_shift 参数会导致 CellRange 对象所表示的 Excel 区域被移动到工作表之外,那么 shift 方法将引发异常 ValueError: Invalid shift value: col_shift=…, row_shift=… ,Excel 区域不会被移动。

Python openpyxl 包的 CellRange 对象的 shift 方法不会移动 Excel 区域内的单元格

很明显的, CellRange 对象的 shift 方法不会移动 Excel 区域内的单元格,他只是改变了区域的位置,如果你希望移动单元格,那么可以使用 Worksheet 对象的 move_range 方法。

工作表

关于如何移动 Excel 单元格,你可以查看 使用 Python openpyxl 包的 Worksheet 对象移动 Excel 单元格 一段。

在下面的代码中,第一次调用 shift 方法,区域 B2:D4 被移动至 C3:E5 ,第二次调用 shift 方法,区域 C3:E5 会被移动到工作表之外,因此引发了异常。

shift.py
from openpyxl.worksheet.cell_range import CellRange
# 创建区域 B2:D4
range = CellRange('B2:D4')
# 向右下方移动区域
range.shift(1, 1)
print(range.coord)
# ERROR 移动后区域将超出工作表的范围
range.shift(row_shift=-3)
C3:E5

ValueError: Invalid shift value: col_shift=0, row_shift=-3

判断 Python openpyxl 包的 CellRange 对象所表示的 Excel 区域之间的关系

Python openpyxl 包的 CellRange 对象的 isdisjoint 方法,可用于判断 CellRange 对象所表示的 Excel 区域与其他 Excel 区域的交集是否为空,即是否两个 Excel 区域没有相同地址的单元格。

Python openpyxl 包的 CellRange 对象的 issubset 方法,可用于判断 CellRange 对象所表示的 Excel 区域是否为其他 Excel 区域的子集,即是否等于或包含在其他 Excel 区域中。

Python openpyxl 包的 CellRange 对象的 issuperset 方法,可用于判断 CellRange 对象所表示的 Excel 区域是否为其他 Excel 区域的超集,即是否等于或包含了其他 Excel 区域。

cellrange . isdisjoint ( other )
cellrange . issubset ( other )
cellrange . issuperset ( other )

other 参数

other 参数为参与关系判断的其他 Excel 区域对应的 CellRange 对象。如果 other 对应的 CellRange 对象拥有有效的 title 变量,并且其值与原区域对应的 CellRange 对象的 title 变量的值不同,那么将引发异常 ValueError: Cannot work with ranges from different worksheets

在下面的示例中,区域 B2:D4 是区域 B2:D4 的子集和超集,因为两个区域相同。

relationship.py
from openpyxl.worksheet.cell_range import CellRange
# 创建区域 B2:D4,然后判断他与其他区域的关系
range = CellRange('B2:D4')
print(f'B2:D4 与 A1:B2 的交集为空?{range.isdisjoint(CellRange("A1:B2"))}')
print(f'B2:D4 与 F4:H5 的交集为空?{range.isdisjoint(CellRange("F4:H5"))}')
print(f'B2:D4 是否为 A1:D4 的子集?{range.issubset(CellRange("A1:D4"))}')
print(f'B2:D4 是否为 B2:D4 的子集?{range.issubset(CellRange("B2:D4"))}')
print(f'B2:D4 是否为 C3:C3 的超集?{range.issuperset(CellRange("C3:C3"))}')
print(f'B2:D4 是否为 B2:D4 的超集?{range.issuperset(CellRange("B2:D4"))}')
B2:D4 与 A1:B2 的交集为空?False
B2:D4 与 F4:H5 的交集为空?True
B2:D4 是否为 A1:D4 的子集?True
B2:D4 是否为 B2:D4 的子集?True
B2:D4 是否为 A1:D4 的超集?True
B2:D4 是否为 C3:C3 的超集?True

计算 Python openpyxl 包的 CellRange 对象所表示的 Excel 区域

Python openpyxl 包的 CellRange 对象的 intersection 方法,可用于计算并返回一个新的 CellRange 对象,该对象表示的 Excel 区域为原区域与目标区域的交集。如果原区域与目标区域的交集为空,那么将引发异常 ValueError: Range … doesn't intersect …

Python openpyxl 包的 CellRange 对象的 union 方法,可用于计算并返回一个新的 CellRange 对象(其 title 变量的值与原 CellRange 对象的 title 变量的值相同),该对象表示的 Excel 区域为原区域与目标区域的并集。

cellrange . intersection ( other )
cellrange . union ( other )

other 参数

other 参数为参与计算的目标 Excel 区域对应的 CellRange 对象。对于 union 方法,如果 other 对应的 CellRange 对象拥有有效的 title 变量,并且其值与原区域对应的 CellRange 对象的 title 变量的值不同,那么将引发异常 ValueError: Cannot work with ranges from different worksheets

calculate.py
from openpyxl.worksheet.cell_range import CellRange
# 创建区域 B2:D4,然后与其他区域进行计算
range = CellRange('B2:D4')
print(f'B2:D4 与 A1:B2 的交集:{range.intersection(CellRange("A1:B2"))}')
print(f'B2:D4 与 A1:D4 的并集:{range.union(CellRange("A1:D4"))}')
print(f'B2:D4 与 A1:A1 的并集:{range.union(CellRange("A1:A1"))}')
try:
	# ERROR 两个区域没有交集
	range.intersection(CellRange('A1:A1'))
except Exception as err:
	print(err)
try:
	# ERROR 目标区域的 title 有效并且与原区域不同