如何使用 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 活頁簿的日期系統一段。
內容分類
程式碼
src/zh-hant/openpyxl/cells·codebeatme/office-programming·GitHub