如何使用 openpyxl 處理 Excel 儲存格?Cell 物件介紹
訂閱 375
本節並不包含 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=False
Cell 物件的其他特性
以下是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