如何使用 openpyxl 處理 Excel 儲存格?Cell 物件介紹
訂閱 480
本節並不包含 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 活頁簿的日期系統一段。
內容分類
原始碼
src/zh-hant/openpyxl/cells·codebeatme/office-programming·GitHub