如何使用 Python openpyxl 套件操作 Excel 儲存格?openpyxl Cell 物件介紹

閱讀 18:07·字數 5438·發佈 
Youtube 頻道
訂閱 133

本節並不包含 Microsoft Excel 儲存格的取得,周遊,移動,合併等操作,如果你想了解相關內容,可以檢視如何使用 Python openpyxl 套件操作 Excel 工作表?openpyxl Worksheet 物件介紹一節。

此外,本節內容也不涉及與 Excel 樣式,計算,連結,註解相關的內容。

Python openpyxl 套件中的 Excel 儲存格物件 Cell

Pythonopenpyxl套件中的Cell類別,屬於模組openpyxl.cell.cell,可用於取得和設定 Excel 儲存格的值或其他相關資訊。通常情況下,你可以通過openpyxl套件的WorksheetReadOnlyWorksheet物件的[]運算子來快速的取得 Excel 儲存格對應的Cell物件。

唯讀工作表物件ReadOnlyWorksheet會傳回ReadOnlyCellEmptyCell來表示一個非空白儲存格或空白儲存格,他們屬於模組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物件時,為其指定位置,但這不會產生實際的效果。

create.py
# 開啟 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 字串,數值或日期時間等,對於空白儲存格,他們對應空值NoneCell物件的internal_value屬性與value屬性沒有本質區別,但internal_value不支援寫入操作。

Pythonopenpyxl套件的ReadOnlyCell物件同樣擁有valueinternal_value屬性,他們均只支援讀取操作。openpyxl套件的EmptyCell物件(沒有internal_value屬性),其value屬性會傳回空值None

cell|readonlycell.value|internal_value
emptycell.value
cell.value = value

value 值

value是需要為 Excel 儲存格設定的值,如果希望目標成為一個空白儲存格,那麽value應該是 Python 空值None

在下面的範例中,我們嘗試通過CellReadOnlyCellEmptyCell來顯示或設定一些 Excel 儲存格的內容。

value.py
# 開啟 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類別獲得CellReadOnlyCell物件的value屬性的具體型別,但openpyxl套件的CellReadOnlyCell物件的data_type變數,可以更方便的粗略的得知 Excel 儲存格對應的資料型別,該變數是一個 Python 字串,可能為以下的某個值。

'n' 值

'n'表示 Excel 儲存格中的資料是數值,這包括整數,小數或使用科學運算質表示的數,其對應Cell物件的value屬性的 Python 型別可能是intfloat。此外,'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.datetimedatetime.datedatetime.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_type.py
# 開啟 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例外狀況的值。

check.py
# 開啟 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套件的CellReadOnlyCell物件的rowcolumn變數,可用於取得 Excel 儲存格位於第幾列或第幾欄(1表示第一列或第一欄),其中Cell物件還擁有額外的col_idx屬性,其傳回值與column相同。

cell|readonlycell.row
cell|readonlycell.column
cell.col_idx

不要嘗試通過 Python openpyxl 套件的 Cell 物件的 row,column 變數移動 Excel 儲存格

你無法通過修改openpyxl套件的Cell物件的rowcolumn變數來移動其對應的 Excel 儲存格,這不會改變Cell物件在 Excel 工作表物件中的位置。在將Workbook物件儲存為 Microsoft Excel 檔案之後,Excel 檔案中的儲存格可能會出現在新的位置或消失不見,這取決於新的位置是否已經存在儲存格,以及被移動儲存格與已存在儲存格之間的關系。

總之,要正確移動 Excel 儲存格,應使用openpyxl套件的Worksheet物件的move_range方法。

下面,我們嘗試使用rowcolumn移動儲存格,在儲存後的檔案Move.xlsx中,儲存格B2將覆蓋儲存格A1,儲存格A2可以順利的移動至C3,因為C3是一個空白儲存格。

move.py
# 開啟 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套件的CellReadOnlyCell物件的column_lettercoordinate屬性,可用於取得 Excel 儲存格的欄索引(比如,AB)和位址(比如,A1B2)。

cell|readonlycell.column_letter
cell|readonlycell.coordinate

address.py
# 開啟 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 儲存格之間的欄位移值。

offset.py
# 開啟 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套件的CellReadOnlyCell物件的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