如何使用 openpyxl 處理 Excel 活頁簿?Workbook 物件介紹
訂閱 480
本節並不包含 Microsoft Excel 檔案的讀取和寫入,如果你想了解相關內容,可以檢視如何使用 openpyxl 讀取和寫入 Excel 檔案一節。
此外,本節內容也不涉及與 Excel 格式,計算或圖表相關的內容。
openpyxl Excel 活頁簿物件 Workbook
openpyxl套件的Workbook類別,對應了我們通常所說的 Excel 活頁簿,使用Workbook物件可以取得活頁簿的相關資訊,或對其中的內容進行操作。
如果正確呼叫了openpyxl套件的load_workbook函式,那麽其傳回值將是一個Workbook物件。
建立 Excel 活頁簿
當你希望建立一個新的 Excel 活頁簿時,就需要使用Workbook類別的建構子。
Workbook(write_only=False, iso_dates=False)
- write_only 參數
write_only參數表示被建立的活頁簿是否是唯寫的,唯寫活頁簿僅支援整列資料的寫入,不支援對單個儲存格的操作,預設為False(不是唯寫的),如果設定為True,那麽僅能對Workbook物件執行一次儲存操作。- iso_dates 參數
iso_dates參數對應的屬性iso_dates,被官方標記為尚未完成。
使用建構子建立的 Workbook 物件可能不包含工作表 Sheet
在預設情況下,使用建構子建立的Workbook物件將擁有一個名稱為Sheet的 Excel 工作表。當建構子參數write_only為True時,唯寫Workbook物件不會包含任何工作表,如果在Workbook物件執行儲存操作時依然如此,那麽openpyxl將嘗試為其新增一個 Excel 工作表。
from openpyxl import Workbook
# 建立一個新的活頁簿,預設包含 Sheet 工作表
workbook = Workbook()
print(workbook['Sheet'])
# 唯寫活頁簿不包含任何工作表
write_only_workbook = Workbook(True)
print(write_only_workbook.worksheets)<Worksheet "Sheet">
[]取得和設定目前使用中的 Excel 工作表
Workbook物件的active屬性,可用於取得或設定 Excel 活頁簿目前使用中的工作表,在取得目前使用中的工作表時,active屬性的傳回值可能是空值None。
workbook.active
workbook.active = worksheet
- worksheet 值
worksheet是需要設定為使用中的Worksheet物件或工作表的索引(int整數型別),0表示第一個工作表,-1表示倒數第一個工作表。
目前使用中的 Excel 工作表需要存在且可見
如果將Worksheet物件設定為目前使用中的工作表,那麽Worksheet對應的工作表應該存在於活頁簿中,並且是可見的,否則會擲回例外狀況ValueError: Worksheet is not in the workbook或ValueError: Only visible sheets can be made active。如果通過工作表索引設定目前使用中的工作表,則不存在擲回例外狀況的情況,但可能導致Workbook物件的active屬性傳回空值None,因為索引指示的位置沒有工作表。
在 Microsoft Excel 檔案School.xlsx中,工作表ClassA,ClassB,ClassC依次排列。
# 請將命令列跳躍至 School.xlsx 所在的目錄,然後執行此腳本檔案
from openpyxl import load_workbook
workbook = load_workbook('School.xlsx')
print(f'目前使用中 {workbook.active}')
# 將倒數第一個工作表設定為目前使用中的工作表
workbook.active = -1
print(f'目前使用中 {workbook.active}')
# 將 ClassB 設定為目前使用中的工作表
workbook.active = workbook['ClassB']
print(f'目前使用中 {workbook.active}')
# 沒有索引為 100 的工作表
workbook.active = 100
print(f'目前使用中 {workbook.active}')目前使用中 <Worksheet "ClassA">
目前使用中 <Worksheet "ClassC">
目前使用中 <Worksheet "ClassB">
目前使用中 None取得 Excel 工作表
Workbook物件實作了__getitem__方法,你可以方便的使用[]運算子並傳遞工作表的名稱(不支援傳遞工作表索引),來取得 Excel 活頁簿中特定的工作表。如果指定的工作表在活頁簿中不存在,那麽將導致例外狀況KeyError: 'Worksheet … does not exist.'。
如果需要通過索引或配量運算式,來取得活頁簿中的某個或某些工作表,那麽可以使用Workbook物件的worksheets屬性,該屬性傳回一個包含所有工作表物件的 Python 串列。
workbook.worksheets[slice]
- slice 值
slice為需要取得的某個工作表的索引,或表示某些工作表的配量運算式。
由於可以采用[]運算子,因此openpyxl已取代Workbook類別的get_sheet_by_name方法。
# 請將命令列跳躍至 School.xlsx 所在的目錄,然後執行此腳本檔案
import openpyxl
workbook = openpyxl.load_workbook('School.xlsx')
# 取得工作表 ClassA
sheet = workbook['ClassA']
print(sheet)
# 取得第二個和其之後的所有工作表
sheets = workbook.worksheets[1:]
print(sheets)<Worksheet "ClassA">
[<Worksheet "ClassB">, <Worksheet "ClassC">]建立 Excel 工作表
openpyxl 為 Excel 活頁簿新增工作表影片示範 YouTube
Workbook物件的create_sheet方法,可用於為 Excel 活頁簿建立新的工作表,並將其插入到指定位置,原本位於該位置的工作表將向後移動,如果他存在的話。create_sheet方法的傳回值是新工作表對應的Worksheet物件。
workbook.create_sheet(title=None, index=None)
- title 參數
title參數為新工作表的名稱(標題),如果省略或設定為None,則新工作表將被命名為Sheet。需要指出,工作表的名稱可能擁有一個數值後綴,用於確保其不與其他名稱重複。- index 參數
index參數為新工作表在活頁簿的插入位置,0表示插入到目前第一個工作表之前,-1表示插入到目前最後一個工作表之前(新的工作表將位於倒數第二)。如果該參數被省略或設定為None,則新工作表將被放置於末尾,如果該參數表示的插入位置不存在工作表,則新的工作表會出現在開頭(當index參數為負數時),或出現在末尾(當index參數為正數時)。
由於被建立的Workbook物件,預設擁有一個名稱為Sheet的工作表,因此,在未指定名稱的情況下,方法create_sheet建立的新工作表將被命名為Sheet1,Sheet2,Sheet3等。
import openpyxl
workbook = openpyxl.Workbook()
# 由於已經存在 Sheet,因此新工作表名稱為 Sheet1,他將被放置在末尾
new_sheet1 = workbook.create_sheet()
print(f'新工作表名稱 {new_sheet1.title}')
print(f'最後一個工作表的名稱 {workbook.worksheets[-1].title}')
# 新工作表名稱為 Sheet2,他將被放置在開頭
workbook.create_sheet(index=0)
print(f'第一個工作表的名稱 {workbook.worksheets[0].title}')
# 新工作表名稱為 New,他將被放置在目前倒數第二個工作表 Sheet 之前
new = workbook.create_sheet('New', -2)
print(workbook.worksheets)新工作表名稱 Sheet1
最後一個工作表的名稱 Sheet1
第一個工作表的名稱 Sheet2
[<Worksheet "Sheet2">, <Worksheet "New">, <Worksheet "Sheet">, <Worksheet "Sheet1">]複製 Excel 工作表
Workbook物件的copy_worksheet方法,可用於複製 Excel 活頁簿中的工作表,並將得到的工作表複本新增至活頁簿的末尾,複本的名稱通常以Copy結尾。copy_worksheet方法的傳回值是工作表複本對應的Worksheet物件。
workbook.copy_worksheet(from_worksheet)
- from_worksheet 參數
from_worksheet參數為被複製的工作表對應的Worksheet物件。
僅能複製 Workbook 物件自身擁有的 Excel 工作表
copy_worksheet方法僅能複製包含在Workbook物件中的工作表,嘗試將其他活頁簿物件的工作表傳遞給參數from_worksheet,會導致例外狀況ValueError: Cannot copy between worksheets from different workbooks。
# 請將命令列跳躍至 School.xlsx 所在的目錄,然後執行此腳本檔案
import openpyxl
workbook = openpyxl.load_workbook('School.xlsx')
# 複製工作表 ClassA
workbook.copy_worksheet(workbook['ClassA'])
print(f'ClassA 複本的名稱為 {workbook.worksheets[-1].title}')
# 嘗試複製其他活頁簿的工作表
newbook = openpyxl.Workbook()
# ERROR 無法複製自身不擁有的工作表
workbook.copy_worksheet(newbook['Sheet'])ClassA 複本的名稱為 ClassA Copy
…
ValueError: Cannot copy between worksheets from different workbooks移動 Excel 工作表
Workbook物件的move_sheet方法,可用於移動 Excel 活頁簿中的工作表,從而改變工作表之間的順序。事實上,openpyxl通過先刪除後插入來完成工作表的移動,他會計算被移動的工作表的插入位置,並將其放置在插入位置對應的工作表之前。
workbook.move_sheet(sheet, offset=0)
- sheet 參數
sheet參數為需要移動的工作表的名稱或其對應的Worksheet物件。- offset 參數
offset參數為工作表插入位置與原索引之間的位移值,1表示插入位置為原索引加1,-1表示插入位置為原索引減1,使用0的效果相當於不移動。如果插入位置最終為負數,那麽移動的效果可能並非你的預期,比如,當 Excel 活頁簿擁有多個工作表時,對索引為0的第一個工作表使用-1,他會被放置在倒數第二的位置,而不是倒數第一,這與使用create_sheet方法所產生的效果類似。
在移動工作表ClassA之後,工作表ClassB將位於開頭,此時指定參數offset為-1,會使ClassB被移動至倒數第二的位置,因為計算的插入位置為-1,即倒數第一的ClassA之前。
# 請將命令列跳躍至 School.xlsx 所在的目錄,然後執行此腳本檔案
from openpyxl import open
workbook = open('School.xlsx')
print(workbook.worksheets)
# 工作表 ClassA 將位於末尾
workbook.move_sheet('ClassA', 100)
print(workbook.worksheets)
# 目前第一個工作表 ClassB 將被移動至倒數第二的位置
b = workbook['ClassB']
workbook.move_sheet(b, -1)
print(workbook.worksheets)[<Worksheet "ClassA">, <Worksheet "ClassB">, <Worksheet "ClassC">]
[<Worksheet "ClassB">, <Worksheet "ClassC">, <Worksheet "ClassA">]
[<Worksheet "ClassC">, <Worksheet "ClassB">, <Worksheet "ClassA">]移除 Excel 工作表
使用Workbook物件的remove方法,或使用del關鍵字和[]運算子,並給出工作表的名稱,可移除 Excel 活頁簿中的工作表。
workbook.remove(worksheet)
del workbook[name]
- worksheet 參數
worksheet參數為需要移除的工作表對應的Worksheet物件。- name 值
name為需要移除的工作表的名稱。
openpyxl已取代Workbook類別的remove_sheet方法。
# 請將命令列跳躍至 School.xlsx 所在的目錄,然後執行此腳本檔案
from openpyxl import open
workbook = open('School.xlsx')
# 刪除工作表 ClassA,ClassB
del workbook['ClassA']
workbook.remove(workbook['ClassB'])
print(workbook.worksheets)[<Worksheet "ClassC">]取得 Excel 工作表的名稱和索引
Workbook物件的sheetnames屬性,傳回一個包含所有 Excel 工作表名稱的 Python 串列。
workbook.sheetnames[slice]
- slice 值
slice為需要取得名稱的某個或某些工作表的索引或配量運算式。
openpyxl已取代Workbook類別的get_sheet_names方法。
Workbook物件的index方法,可用於取得指定 Excel 工作表在活頁簿中的索引,第一個工作表的索引為0。
workbook.index(worksheet)
- worksheet 參數
worksheet參數為需要取得索引的工作表對應的Worksheet物件。
openpyxl已取代Workbook類別的get_index方法。
# 請將命令列跳躍至 School.xlsx 所在的目錄,然後執行此腳本檔案
from openpyxl import load_workbook
workbook = load_workbook('School.xlsx')
# 取得工作表的名稱和索引
print(f'第二個工作表的名稱 {workbook.sheetnames[1]}')
print(f'工作表 ClassC 的索引 {workbook.index(workbook["ClassC"])}')第二個工作表的名稱 ClassB
工作表 ClassC 的索引 2取得 Excel 活頁簿的日期系統
Workbook物件的excel_base_date屬性或epoch屬性,可用於取得 Excel 活頁簿日期系統的開始日期。
workbook.excel_base_date
什麽是 Excel 活頁簿的日期系統?
每一個活頁簿都指定了自己的日期系統,不同的日期系統具有不同的開始日期,Excel 會將日期計算為相對於開始日期的位移值,因此,同一日期在不同日期系統中儲存的資料並不相同。
# 請將命令列跳躍至 1904.xlsx 所在的目錄,然後執行此腳本檔案
from openpyxl import load_workbook
workbook = load_workbook('1904.xlsx')
# 取得活頁簿的日期系統
print(workbook.excel_base_date)1904-01-01 00:00:00判斷 Excel 活頁簿是否為範本
Workbook擁有類別變數template和執行個體變數is_template,他們的值始終為True,官方似乎沒有闡明其具體作用,因此template和is_template不能用於判斷 Excel 活頁簿是否是一個範本,你需要使用Workbook物件的mime_type屬性來完成此目標,該屬性用來說明活頁簿的 MIME 類型,當其包含template時,可將活頁簿視為範本。
workbook.mime_type
# 請將命令列跳躍至 Hello.xltx 所在的目錄,然後執行此腳本檔案
from openpyxl import load_workbook
workbook = load_workbook('Hello.xltx')
# 活頁簿是否為範本?
print('template' in workbook.mime_type)TrueWorkbook 物件的其他特性
以下是與Workbook物件相關,但不太重要的一些特性,這些特性可能並非從 Microsoft Excel 檔案取得,只是由openpyxl套件給出了固定值。
- encoding 變數
encoding變數用於表示活頁簿的編碼,他被指定為'utf-8'。- path 變數
Excel 檔案本身是一個壓縮檔案,
Workbook物件的path變數表示其在壓縮檔案中的路徑,他被指定為'/xl/workbook.xml'。- vba_archive 變數
vba_archive變數是一個ZipFile物件,表示與 VBA 相關的壓縮檔案,該壓縮檔案包含在 Excel 檔案中,通常的名稱為vbaProject.bin。- data_only,read_only,write_only 屬性
data_only,read_only,write_only屬性是唯讀的,他們由讀取 Excel 檔案或建立Workbook物件時給出的引數來決定,由於相關文章已經進行了講解,這裏不再累述。
原始碼
src/zh-hant/openpyxl/workbooks·codebeatme/office-programming·GitHub