如何使用 Python openpyxl 包操作 Excel 单元格?openpyxl Cell 对象介绍
本节并不包含 Microsoft Excel 单元格的获取,遍历,移动,合并等操作,如果你想了解相关内容,可以查看如何使用 Python openpyxl 包操作 Excel 工作表?openpyxl Worksheet 对象介绍一节。
此外,本节内容也不涉及与 Excel 样式,计算,链接,批注相关的内容。
Python openpyxl 包中的 Excel 单元格对象 Cell
Pythonopenpyxl
包中的Cell
类,属于模块openpyxl.cell.cell
,可用于获取和设置 Excel 单元格的值或其他相关信息。通常情况下,你可以通过openpyxl
包的Worksheet
和ReadOnlyWorksheet
对象的[]
运算符来快速的获取 Excel 单元格对应的Cell
对象。
只读工作表对象ReadOnlyWorksheet
会返回ReadOnlyCell
或EmptyCell
来表示一个非空单元格或空单元格,他们属于模块openpyxl.cell.read_only
,不支持对单元格的写入操作。
使用 Python openpyxl 包的 Cell 对象创建 Excel 单元格
你可以使用 Pythonopenpyxl
包的Cell
对象的构造器,创建新的 Excel 单元格,这些新的单元格需要 Excel 工作表对象通过append
方法进行添加,否则他们不会真正的存在于工作表对象。
Cell(worksheet, row=None, column=None, value=None, style_array=None)
- worksheet 参数
worksheet
参数为被创建的 Excel 单元格所隶属的工作表对象。- row 参数
row
参数用于说明被创建的 Excel 单元格将位于工作表的第几行,指定该参数通常没有意义,因为Cell
对象的位置会被工作表对象修改。- column 参数
column
参数用于说明被创建的 Excel 单元格将位于工作表的第几列,指定该参数通常没有意义,因为Cell
对象的位置会被工作表对象修改。- value 参数
value
参数为被创建的 Excel 单元格的值。- style_array 参数
style_array
参数是一个包含了 Excel 单元格样式信息的 Python 数组。
此外,Pythonopenpyxl
包的WriteOnlyCell
函数(属于模块openpyxl.cell.cell
),可用于创建只写的 Excel 单元格对象,不要被他的名字迷惑,WriteOnlyCell
函数的返回值依然是一个Cell
对象,该函数只是简化了创建Cell
对象的参数。
WriteOnlyCell(ws=None, value=None)
- ws 参数
ws
参数为被创建的 Excel 单元格所隶属的工作表对象。- value 参数
value
参数为被创建的 Excel 单元格的值。
不能直接用已经创建的 Cell 对象替代 Excel 工作表对象中的 Cell 对象
你可以将openpyxl
包的Cell
对象添加至 Excel 工作表对象,但不能使用类似于worksheet['A1']=cell
这样的表达式,将 Excel 工作表对象中的Cell
对象替换为新建的Cell
对象。
工作表
关于如何为 Excel 工作表添加数据,你可以查看使用 Python openpyxl 包的 Worksheet 对象为 Excel 工作表添加数据(值)一段。
在下面的示例中,我们尝试在创建Cell
对象时,为其指定位置,但这不会产生实际的效果。
# 打开 Data.xlsx 中的工作表 Values
from openpyxl import load_workbook
wb = load_workbook('Data.xlsx')
ws = wb['Values']
from datetime import date
from openpyxl import Workbook
from openpyxl.cell.cell import Cell, WriteOnlyCell
# 创建 Cell 并添加至工作表对象
ws.append((Cell(ws, 1, 1, '单元格 A1'), 1.23, '2024-11-11'))
ws.append((Cell(ws, value='单元格 B1'), 4.56, date(2024, 1, 1)))
Cell(ws, 5, 5, value='我是不会被添加的')
# 保存至 Excel 文件 Add.xlsx
wb.save('Add.xlsx')
w_ws = Workbook(True).create_sheet()
# 创建 Cell 并添加至只写工作表对象
w_ws.append([Cell(w_ws, 2, 2, '2 2'), Cell(w_ws, 1, 1, '1 1')])
w_ws.append([WriteOnlyCell(w_ws, '只写')])
# 保存至 Excel 文件 New.xlsx
w_ws.parent.save('New.xlsx')
使用 Python openpyxl 包的 Cell 对象获取和设置 Excel 单元格的值
Pythonopenpyxl
包的Cell
对象的value
属性,可用于获取或设置 Excel 单元格的值,这些值的类型可以是 Python 字符串,数字或日期时间等,对于空单元格,他们对应空值None
。Cell
对象的internal_value
属性与value
属性没有本质区别,但internal_value
不支持写入操作。
Pythonopenpyxl
包的ReadOnlyCell
对象同样拥有value
和internal_value
属性,他们均只支持读取操作。openpyxl
包的EmptyCell
对象(没有internal_value
属性),其value
属性会返回空值None
。
cell|readonlycell.value|internal_value
emptycell.value
cell.value = value
- value 值
value
是需要为 Excel 单元格设置的值,如果希望目标成为一个空单元格,那么value
应该是 Python 空值None
。
在下面的示例中,我们尝试通过Cell
,ReadOnlyCell
和EmptyCell
来显示或设置一些 Excel 单元格的内容。
# 打开 Data.xlsx 中的工作表 Values
import openpyxl
workbook = openpyxl.load_workbook('Data.xlsx')
worksheet = workbook['Values']
# 显示一些单元格,A2 将成为一个空单元格
worksheet['A2'].value = None
print(f"A1:{type(worksheet['A1'].value)} {worksheet['A1'].value}")
print(f"B1:{type(worksheet['B1'].value)} {worksheet['B1'].value}")
print(f"C1:{type(worksheet['C1'].value)} {worksheet['C1'].value}")
print(f"D4:{type(worksheet['D4'].internal_value)} {worksheet['D4'].internal_value}")
workbook.save('Value.xlsx')
# 以只读方式打开 Data.xlsx 中的工作表 Values
r_workbook = openpyxl.load_workbook('Data.xlsx', True)
r_worksheet = r_workbook['Values']
# 读取单元格 A1,D4
print(f"A1:{r_worksheet['A1']} {type(r_worksheet['A1'].internal_value)} {r_worksheet['A1'].internal_value}")
print(f"D4:{r_worksheet['D4']} {type(r_worksheet['D4'].value)} {r_worksheet['D4'].value}")
A1:<class 'int'> 1
B1:<class 'str'> 字符串
C1:<class 'datetime.datetime'> 2024-01-01 00:00:00
D4:<class 'NoneType'> None
A1:<ReadOnlyCell 'Values'.A1> <class 'int'> 1
D4:<EmptyCell> <class 'NoneType'> None
使用 Python openpyxl 包的 Cell 对象获取 Excel 单元格的数据类型
虽然,你可以通过 Python 的type
类获得Cell
,ReadOnlyCell
对象的value
属性的具体类型,但openpyxl
包的Cell
和ReadOnlyCell
对象的data_type
变量,可以更方便的粗略的得知 Excel 单元格对应的数据类型,该变量是一个 Python 字符串,可能为以下的某个值。
- 'n' 值
'n'
表示 Excel 单元格中的数据是数字,这包括整数,小数或使用科学计数法表示的数,其对应Cell
对象的value
属性的 Python 类型可能是int
,float
。此外,'n'
也可以表示空 Excel 单元格,其对应Cell
对象的value
属性返回 Python 空值None
。- 's' 值
's'
表示 Excel 单元格中的数据是字符串,其对应Cell
对象的value
属性的 Python 类型是str
。- 'b' 值
'b'
表示 Excel 单元格中的数据表示的是真(TRUE
)或假(FALSE
),其对应Cell
对象的value
属性的 Python 类型是bool
。- 'd' 值
'd'
表示 Excel 单元格中的数据是日期时间,其对应Cell
对象的value
属性的 Python 类型可能是datetime.datetime
,datetime.date
,datetime.time
。- 'f' 值
'f'
表示 Excel 单元格中的数据是公式,其对应Cell
对象的value
属性的 Python 类型是str
。'f'
可能出现在将load_workbook
函数的data_only
参数设置为False
的情况下,也就是在打开 Excel 文件时,Pythonopenpyxl
包读取单元格公式,而不是公式的计算结果。- 'e' 值
'e'
表示 Excel 单元格中的数据是错误信息,该值可能出现在将load_workbook
函数的data_only
参数设置为True
的情况下,也就是在打开 Excel 文件时,Pythonopenpyxl
包读取单元格公式的计算结果,而不是公式。如果data_only
参数为False
,那么openpyxl
包不会判断公式是否存在错误,Cell
对象的data_type
变量也就不会为'e'
,除非单元格的值被设置为某种表示错误的字符串,比如'#NULL!'
。
至于,Pythonopenpyxl
包的EmptyCell
对象,也就是以只读方式打开的空单元格,其data_type
变量的值为'n'
。
cell|readonlycell|emptycell.data_type
Python openpyxl 包的 Cell 对象的 value 属性所接受的数据类型
以上说明的仅是读取 Excel 文件之后,Cell
对象的data_type
变量与value
属性之间的某种关系。在openpyxl
包中,你可以将某种其他 Python 类型的数据赋值给Cell
对象的value
属性,比如,bytes
,当然,这不表示value
属性会接受任意类型的数据,如果给出的值的类型不被接受,异常Cannot convert … to Excel
将被抛出。
读写 Excel 文件
想要了解openpyxl
包的load_workbook
函数,你可以查看使用 Python openpyxl 包读取 Excel 文件一段。
在下面的示例中,由于我们将load_workbook
函数的data_only
参数设置为了True
,因此,Excel 文件中拥有公式的单元格,其对应的Cell
对象的data_type
变量的值不是'f'
。
# 打开 Data.xlsx 中的工作表 Types,并读取公式的计算结果
import openpyxl
workbook = openpyxl.load_workbook('Data.xlsx', data_only=True)
worksheet = workbook['Types']
# 用于显示单元格信息的函数
def show(cell):
print(f'{cell.data_type} {cell.value} {type(cell.value)}')
# 显示区域 A1:L1 中的单元格的信息
for row in worksheet['A1:L1']:
for cell in row:
show(cell)
# 将类型为 bytes 的值,传递给属性 value
worksheet['A2'].value = bytes(b'A good day')
show(worksheet['A2'])
n 1 <class 'int'>
n 1.2 <class 'float'>
n 1.3e-12 <class 'float'>
b True <class 'bool'>
s 你好 <class 'str'>
s 很棒的一天 <class 'str'>
n 2.2 <class 'float'>
d 2024-01-01 00:00:00 <class 'datetime.datetime'>
d 07:30:00 <class 'datetime.time'>
d 2024-01-01 07:30:00 <class 'datetime.datetime'>
e #NAME? <class 'str'>
n None <class 'NoneType'>
s A good day <class 'str'>
使用 Python openpyxl 包的 Cell 对象将值转换为 Excel 单元格的有效文本内容
虽然一些值在 Python 中不会被视为错误,但在 Excel 中他们可能并不适合成为 Excel 单元格中的文本,openpyxl
包的Cell
对象的check_string
方法,可用于将一个值转换为 Excel 单元格中的有效文本内容并返回。如果给出的值在转换为字符串后,包含一些不被允许的字符,比如退格符,那么将导致异常… cannot be used in worksheets.
。
cell.check_string(value)
- value 参数
value
参数包含了需要被转换为有效文本内容的值。
另外,Pythonopenpyxl
包的Cell
对象的check_error
方法,会尝试将给出的值转换为字符串并返回。如果在转换的过程中遇到异常UnicodeDecodeError
,那么check_error
将返回字符串'#N/A'
。
cell.check_error(value)
- value 参数
value
参数包含了需要检测UnicodeDecodeError
异常的值。
# 打开 Data.xlsx 中的工作表 Values
from openpyxl import load_workbook
workbook = load_workbook('Data.xlsx')
worksheet = workbook['Values']
a1 = worksheet['A1']
# 尝试转换为有效的文本内容
a1.check_string(b'\0 is invalid')
openpyxl.utils.exceptions.IllegalCharacterError: is invalid cannot be used in worksheets.
使用 Python openpyxl 包的 Cell 对象获取 Excel 单元格位于第几行或第几列
Pythonopenpyxl
包的Cell
,ReadOnlyCell
对象的row
,column
变量,可用于获取 Excel 单元格位于第几行或第几列(1
表示第一行或第一列),其中Cell
对象还拥有额外的col_idx
属性,其返回值与column
相同。
cell|readonlycell.row
cell|readonlycell.column
cell.col_idx
不要尝试通过 Python openpyxl 包的 Cell 对象的 row,column 变量移动 Excel 单元格
你无法通过修改openpyxl
包的Cell
对象的row
或column
变量来移动其对应的 Excel 单元格,这不会改变Cell
对象在 Excel 工作表对象中的位置。在将Workbook
对象保存为 Microsoft Excel 文件之后,Excel 文件中的单元格可能会出现在新的位置或消失不见,这取决于新的位置是否已经存在单元格,以及被移动单元格与已存在单元格之间的关系。
总之,要正确移动 Excel 单元格,应使用openpyxl
包的Worksheet
对象的move_range
方法。
下面,我们尝试使用row
和column
移动单元格,在保存后的文件Move.xlsx
中,单元格B2
将覆盖单元格A1
,单元格A2
可以顺利的移动至C3
,因为C3
是一个空单元格。
# 打开 Data.xlsx 中的工作表 Values
from openpyxl import load_workbook
workbook = load_workbook('Data.xlsx')
worksheet = workbook['Values']
# B2 将覆盖 A1
b2 = worksheet['B2']
b2.row = 1
b2.column = 1
# A2 可以顺利的移动至 C3
a2 = worksheet['A2']
a2.row = 3
a2.column = 3
workbook.save('Move.xlsx')
# B2 和 A2 在 worksheet 中的位置并没有改变
print(worksheet['B2'] == b2)
print(worksheet['A2'] == a2)
True
True
使用 Python openpyxl 包的 Cell 对象获取 Excel 单元格的列索引和地址
Pythonopenpyxl
包的Cell
,ReadOnlyCell
对象的column_letter
,coordinate
属性,可用于获取 Excel 单元格的列索引(比如,A
,B
)和地址(比如,A1
,B2
)。
cell|readonlycell.column_letter
cell|readonlycell.coordinate
# 打开 Data.xlsx 中的工作表 Values
from openpyxl import load_workbook
workbook = load_workbook('Data.xlsx')
worksheet = workbook['Values']
# 显示 C2 列索引和地址
c2 = worksheet['C2']
print(f'列索引:{c2.column_letter} 地址:{c2.coordinate}')
列索引:C 地址:C2
使用 Python openpyxl 包的 Cell 对象和相对位置获取 Excel 单元格
Pythonopenpyxl
包的Cell
对象的offset
方法,可以通过相对位置获取一个 Excel 单元格,该相对位置相对于Cell
对象对应的 Excel 单元格。如果计算出的目标单元格的位置无效,比如行索引为0
,那么将导致异常。
cell.offset(row=0, column=0)
- row 参数
row
参数是需要获取的目标 Excel 单元格与Cell
对象对应的 Excel 单元格之间的行偏移值。- column 参数
column
参数是需要获取的目标 Excel 单元格与Cell
对象对应的 Excel 单元格之间的列偏移值。
# 打开 Data.xlsx 中的工作表 Values
from openpyxl import load_workbook
workbook = load_workbook('Data.xlsx')
worksheet = workbook['Values']
b1 = worksheet['B1']
# 获取 B1 左边的单元格 A1
print(b1.offset(column=-1))
# 获取 B1 右下角的单元格 C2
print(b1.offset(1, 1))
<Cell 'Values'.A1>
<Cell 'Values'.C2>
使用 Python openpyxl 包的 Cell 对象获取 Excel 单元格所隶属的工作表
Pythonopenpyxl
包的Cell
,ReadOnlyCell
对象的parent
变量,表示了 Excel 单元格所隶属的工作表对象。
cell|readonlycell.parent
Python openpyxl 包的 Cell 对象的其他特性
以下是 Pythonopenpyxl
包的Cell
对象的其他相关特性。
- encoding 属性
Cell
对象的encoding
属性,用于表示 Excel 单元格所属工作表的编码,他由openpyxl
指定为'utf-8'
。- base_date 属性
Cell
对象的base_date
属性,用于表示 Excel 单元格所属工作簿的日期系统的开始日期,其返回值等同于对应Workbook
对象的epoch
属性。
工作簿
关于Workbook
对象的epoch
属性,你可以查看使用 Python openpyxl 包的 Workbook 对象获取 Excel 工作簿的日期系统一段。