如何使用 openpyxl 处理 Excel 单元格?Cell 对象介绍
关注 1800
本节并不包含 Microsoft Excel 单元格的格式,以及单元格的获取,遍历,移动,合并等操作,如果你想了解相关内容,可以查看如何使用 openpyxl 获取和设置 Excel 单元格格式,如何使用 openpyxl 处理 Excel 工作表?Worksheet 对象介绍两节。与 Excel 单元格链接,批注相关的内容,请查看内容分类一段列出的章节。
openpyxl Excel 单元格对象 Cell
openpyxl包中的Cell类,属于模块openpyxl.cell.cell,可用于获取和设置 Excel 单元格的值或其他相关信息。通常情况下,你可以通过Worksheet和ReadOnlyWorksheet对象的[]运算符来快速的获取单元格对应的Cell对象。
只读工作表对象ReadOnlyWorksheet会返回ReadOnlyCell或EmptyCell来表示一个非空单元格或空单元格,他们属于模块openpyxl.cell.read_only,不支持对单元格的写入操作。
创建 Excel 单元格
你可以使用Cell对象的构造器,创建新的 Excel 单元格,这些新的单元格需要工作表对象通过append方法进行添加,否则他们不会真正的存在于工作表对象。
Cell(worksheet, row=None, column=None, value=None, style_array=None)
- worksheet 参数
worksheet参数为被创建的单元格所隶属的工作表对象。- row 参数
row参数用于说明被创建的单元格将位于工作表的第几行,指定该参数通常没有意义,因为Cell对象的位置会被工作表对象修改。- column 参数
column参数用于说明被创建的单元格将位于工作表的第几列,指定该参数通常没有意义,因为Cell对象的位置会被工作表对象修改。- value 参数
value参数为被创建的单元格的值。- style_array 参数
style_array参数是一个包含了单元格格式信息的 Python 数组。
此外,WriteOnlyCell函数(属于模块openpyxl.cell.cell),可用于创建只写的 Excel 单元格对象,不要被他的名字迷惑,WriteOnlyCell函数的返回值依然是一个Cell对象,该函数只是简化了创建Cell对象的参数。
WriteOnlyCell(ws=None, value=None)
- ws 参数
ws参数为被创建的单元格所隶属的工作表对象。- value 参数
value参数为被创建的单元格的值。
不能直接用已经创建的 Cell 对象替代工作表对象中的 Cell 对象
你可以将Cell对象添加至工作表对象,但不能使用类似于worksheet['A1']=cell这样的表达式,将工作表对象中的Cell对象替换为新建的Cell对象。
工作表
关于如何为 Excel 工作表添加数据,你可以查看为 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')获取和设置 Excel 单元格的值
Cell对象的value属性,可用于获取或设置 Excel 单元格的值,这些值的类型可以是 Python 字符串,数字或日期时间等,对于空单元格,他们对应空值None。Cell对象的internal_value属性与value属性没有本质区别,但internal_value不支持写入操作。
ReadOnlyCell对象同样拥有value和internal_value属性,他们均只支持读取操作。EmptyCell对象(没有internal_value属性),其value属性会返回空值None。
cell|readonlycell.value|internal_value
emptycell.value
cell.value = value
- value 值
value是需要为单元格设置的值,如果希望目标成为一个空单元格,那么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获取 Excel 单元格的数据类型
虽然,你可以通过 Python 的type类获得Cell,ReadOnlyCell对象的value属性的具体类型,但Cell和ReadOnlyCell对象的data_type变量,可以更方便的粗略的得知 Excel 单元格对应的数据类型,该变量是一个 Python 字符串,可能为以下的某个值。
- 'n' 值
'n'表示单元格中的数据是数字,这包括整数,小数或使用科学计数法表示的数,其对应Cell对象的value属性的 Python 类型可能是int,float。此外,'n'也可以表示空单元格,其对应Cell对象的value属性返回 Python 空值None。- 's' 值
's'表示单元格中的数据是字符串,其对应Cell对象的value属性的 Python 类型是str。- 'b' 值
'b'表示单元格中的数据表示的是真(TRUE)或假(FALSE),其对应Cell对象的value属性的 Python 类型是bool。- 'd' 值
'd'表示单元格中的数据是日期时间,其对应Cell对象的value属性的 Python 类型可能是datetime.datetime,datetime.date,datetime.time。- 'f' 值
'f'表示单元格中的数据是公式,其对应Cell对象的value属性的 Python 类型是str。'f'可能出现在将load_workbook函数的data_only参数设置为False的情况下,也就是在打开 Excel 文件时,openpyxl包读取单元格公式,而不是公式的计算结果。- 'e' 值
'e'表示单元格中的数据是错误信息,该值可能出现在将load_workbook函数的data_only参数设置为True的情况下,也就是在打开 Excel 文件时,openpyxl包读取单元格公式的计算结果,而不是公式。如果data_only参数为False,那么openpyxl包不会判断公式是否存在错误,Cell对象的data_type变量也就不会为'e',除非单元格的值被设置为某种表示错误的字符串,比如'#NULL!'。
至于EmptyCell对象,也就是以只读方式打开的空单元格,其data_type变量的值为'n'。
cell|readonlycell|emptycell.data_type
Cell 对象的 value 属性所接受的数据类型
以上说明的仅是读取 Excel 文件之后,Cell对象的data_type变量与value属性之间的某种关系。在openpyxl包中,你可以将某种其他 Python 类型的数据赋值给Cell对象的value属性,比如,bytes,当然,这不表示value属性会接受任意类型的数据,如果给出的值的类型不被接受,异常Cannot convert … to Excel将被抛出。
读写 Excel 文件
想要了解load_workbook函数,你可以查看使用 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'>将值转换为 Excel 单元格的有效文本内容
虽然一些值在 Python 中不会被视为错误,但在 Excel 中他们可能并不适合成为单元格中的文本,Cell对象的check_string方法,可用于将一个值转换为单元格中的有效文本内容并返回。如果给出的值在转换为字符串后,包含一些不被允许的字符,比如退格符,那么将导致异常… cannot be used in worksheets。
cell.check_string(value)
- value 参数
value参数包含了需要被转换为有效文本内容的值。
另外,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.获取 Excel 单元格位于第几行或第几列
Cell,ReadOnlyCell对象的row,column变量,可用于获取 Excel 单元格位于第几行或第几列(1表示第一行或第一列),其中Cell对象还拥有额外的col_idx属性,其返回值与column相同。
cell|readonlycell.row
cell|readonlycell.column
cell.col_idx
不要尝试通过 Cell 对象的 row,column 变量移动单元格
你无法通过修改Cell对象的row或column变量来移动其对应的单元格,这不会改变Cell对象在工作表对象中的位置。在将Workbook对象保存为 Microsoft Excel 文件之后,文件中的单元格可能会出现在新的位置或消失不见,这取决于新的位置是否已经存在单元格,以及被移动单元格与已存在单元格之间的关系。
总之,要正确移动单元格,应使用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获取 Excel 单元格的列索引和地址
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使用相对位置获取 Excel 单元格
Cell对象的offset方法,可以通过相对位置获取一个 Excel 单元格,该相对位置相对于Cell对象对应的单元格。如果计算出的目标单元格的位置无效,比如行索引为0,那么将导致异常。
cell.offset(row=0, column=0)
- row 参数
row参数是需要获取的目标单元格与Cell对象对应的单元格之间的行偏移值。- column 参数
column参数是需要获取的目标单元格与Cell对象对应的单元格之间的列偏移值。
# 打开 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>获取 Excel 单元格所隶属的工作表
Cell,ReadOnlyCell对象的parent变量,表示了 Excel 单元格所隶属的工作表对象。
cell|readonlycell.parent
openpyxl Excel 单元格保护对象 Protection
openpyxl包中的Protection类,属于模块openpyxl.styles.protection,用于表示 Excel 单元格的保护信息,其构造器如下。
Protection(locked=True, hidden=False)
- locked 参数
locked参数是一个布尔值,如果为True则表示当工作表被保护时,单元格将被锁定(无法被编辑)。- hidden 参数
hidden参数是一个布尔值,如果为True则表示当工作表被保护时,单元格中的公式将被隐藏。
Protection 对象的变量
Protection对象拥有变量locked,hidden,在未作出修改时,他们的值与传递给Protection构造器的实参的值相同。
获取和设置 Excel 单元格的保护信息
Cell对象拥有名称为protection的变量,可将其类型视为Protection类,他被用于获取和设置 Excel 单元格的保护信息。
ReadOnlyCell对象拥有名称为protection的只读属性,其类型为Protection类,可用于设置 Excel 单元格的保护信息。
cell|readonlycell.protection
cell.protection = protection
- protection 值
protection为表示单元格保护信息的Protection对象。
工作表
关于 Excel 工作表的保护信息,你可以查看openpyxl Excel 工作表保护对象 SheetProtection,获取和设置 Excel 工作表的保护信息两段。
# 打开 Data.xlsx 中的工作表 Types
import openpyxl
workbook = openpyxl.load_workbook('Data.xlsx')
worksheet = workbook['Types']
from openpyxl.styles.protection import Protection
g1 = worksheet['G1']
# 显示单元格 G1 的保护信息
print(g1.protection)
# 当工作表被保护时,将隐藏 G1 单元格的公式
g1.protection = Protection(False, True)
workbook.save('P.xlsx')<openpyxl.styles.protection.Protection object>
Parameters:
locked=True, hidden=FalseCell 对象的其他特性
以下是Cell对象的其他相关特性。
- encoding 属性
Cell对象的encoding属性,用于表示单元格所属工作表的编码,他被指定为'utf-8'。- base_date 属性
Cell对象的base_date属性,用于表示单元格所属工作簿的日期系统的开始日期,其返回值等同于对应Workbook对象的epoch属性。
工作簿
关于Workbook对象的epoch属性,你可以查看获取 Excel 工作簿的日期系统一段。