如何使用 Python openpyxl 包操作 Excel 区域?openpyxl CellRange 对象介绍
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
中的区域。
# 读取 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
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 区域最上方一行向外或向内移动的行数,设置为负数表示反向操作。
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
语句。
# 读取 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
会被移动到工作表之外,因此引发了异常。
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
的子集和超集,因为两个区域相同。
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
。
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 有效并且与原区域不同