URLhttps://learnscript.net/zh-hant/office-programming/openpyxl/workbooks/
    複製連結移至說明  範例

    如何使用 openpyxl 處理 Excel 活頁簿?Workbook 物件介紹

    閱讀 15:59·字數 4797·更新 
    Youtube 頻道
    訂閱 375

    本節並不包含 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_onlyTrue時,唯寫Workbook物件不會包含任何工作表,如果在Workbook物件執行儲存操作時依然如此,那麽openpyxl將嘗試為其新增一個 Excel 工作表。

    create_workbook.py
    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 workbookValueError: Only visible sheets can be made active。如果通過工作表索引設定目前使用中的工作表,則不存在擲回例外狀況的情況,但可能導致Workbook物件的active屬性傳回空值None,因為索引指示的位置沒有工作表。

    在 Microsoft Excel 檔案School.xlsx中,工作表ClassAClassBClassC依次排列。

    active.py
    # 請將命令列跳躍至 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方法。

    get_sheets.py
    # 請將命令列跳躍至 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 工作表

    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建立的新工作表將被命名為Sheet1Sheet2Sheet3等。

    create_sheet.py
    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

    copy_sheet.py
    # 請將命令列跳躍至 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之前。

    move_sheet.py
    # 請將命令列跳躍至 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方法。

    remove_sheet.py
    # 請將命令列跳躍至 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方法。

    name_and_index.py
    # 請將命令列跳躍至 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 會將日期計算為相對於開始日期的位移值,因此,同一日期在不同日期系統中儲存的資料並不相同。

    date_system.py
    # 請將命令列跳躍至 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,官方似乎沒有闡明其具體作用,因此templateis_template不能用於判斷 Excel 活頁簿是否是一個範本,你需要使用Workbook物件的mime_type屬性來完成此目標,該屬性用來說明活頁簿的 MIME 類型,當其包含template時,可將活頁簿視為範本。

    workbook.mime_type

    is_template.py
    # 請將命令列跳躍至 Hello.xltx 所在的目錄,然後執行此腳本檔案
    from openpyxl import load_workbook
    workbook = load_workbook('Hello.xltx')
    
    # 活頁簿是否為範本? print('template' in workbook.mime_type)
    True

    Workbook 物件的其他特性

    以下是與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_onlyread_onlywrite_only屬性是唯讀的,他們由讀取 Excel 檔案或建立Workbook物件時給出的引數來決定,由於相關文章已經進行了講解,這裏不再累述。

    原始碼

    src/zh-hant/openpyxl/workbooks·codebeatme/office-programming·GitHub

    講解影片

    openpyxl 為 Excel 活頁簿新增工作表·YouTube