python模塊 openpyxl--操作文件excle


關於python處理excel文件的各種信息:http://www.python-excel.org/
本文使用openpyxl(3.0.7)說明文檔:https://openpyxl.readthedocs.io/en/stable/

1、openpyxl模塊介紹及安裝

1、openpyxl模塊介紹

  • openpyxl是一個Python庫,用於讀取/寫入Excel 2010(xlsx/xlsm/xltx/xltm)文件。
  • 簡單易用,功能廣泛,單元格格式/圖片/表格/公式/篩選/批注/文件保護等等功能應有盡有,圖表功能是其一大亮點,缺點是對 VBA 支持的不夠好。
  • 與其他庫和應用程序相比,內存使用量相當高,大約是原始文件大小的50倍,例如,50MB Excel文件需要2.5GB。

2、openpyxl模塊安裝

pip install openpyxl
  • 為了能夠將圖像(jpeg、png、bmp等)包含到openpyxl文件中,您還需要可以安裝的“pillow”庫:
pip install pillow

2、操作workbook(工作簿)

1、創建工作簿

  • 無需在文件系統上創建文件即可開始使用openpyxl。只需導入Workbook類並開始工作。
  • 一個工作簿總是由至少一個工作表組成,即創建工作簿時會創建一個工作表sheet。
  • 可以通過使用該Workbook.active屬性來獲取它。(獲得工作簿打開時默認的工作表,默認設置為0,即默認獲得第一個工作表。)

示例:

from openpyxl import Workbook    #導入Workbook模塊
wb = Workbook()                  #創建工作簿,同時會創建一個工作表“Sheet”。此時只是在內存中,沒有寫進磁盤中,<openpyxl.workbook.workbook.Workbook object at 0x000001E923621C40>
# print(tuple(wb))                     #結果是:(<Worksheet "Sheet">,)
ws = wb.active                   #獲得第一個工作表對象,<Worksheet "Sheet">

2、保存工作簿

  • Workbook.save()方法:將在沒有警告的情況下覆蓋現有文件。在保存到磁盤之前,所有的操作都是在內存中進行的
  • 文件擴展名不會強制為xlsx或xlsm,但如果不使用官方擴展名,則使用其他應用程序打開它可能會遇到一些問題。

示例:

from openpyxl import Workbook
wb = Workbook()
ws = wb.active
wb.save(r'C:\Users\root\Desktop\empty_book.xlsx')    #寫在磁盤上,並命名為“empty_book.xlsx”

3、讀寫磁盤上的工作簿

  • load_workbook(filename, read_only=False, keep_vba=KEEP_VBA, data_only=False, keep_links=True)
    • 打開給定的文件名並返回工作簿
      • filename:打開文件或文件類對象
      • read_only(bool):為閱讀而優化,內容無法編輯
      • keep_vba(bool):保存vba內容(這並不意味着你可以使用它)
      • data_only(bool):單元格中是公式默認單元格的值是公式(默認),若data_only=True單元格的值是Excel存儲的值(公式得到的值)
      • keep_links(bool):是否應該保留到外部工作簿的鏈接。默認為True

示例:

from openpyxl import load_workbook
wb = load_workbook(r'C:\Users\root\Desktop\empty_book.xlsx')    #加載磁盤上的工作簿 

4、只讀模式、只寫模式

  • 有時需要打開或寫入非常大的XLSX文件,而openpyxl中的常見例程將無法處理該負載。幸運的是,有兩種模式使能夠以(接近)恆定內存消耗讀取和寫入無限量的數據。

1、只讀模式

  • 如果您主要對轉儲工作簿的內容感興趣,那么您可以使用openpyxl的只讀模式並打開工作簿的多個實例並利用多個CPU。
  • openpyxl的只讀模式幾乎立即打開工作簿,使其適用於多個進程,這也顯着減少了內存使用。
  • 與普通工作簿不同,只讀工作簿將使用延遲加載
  • 必須使用該close()方法顯式關閉工作簿。
  • 返回的單元格不是常規的openpyxl.cell.cell.Cell而是openpyxl.cell._read_only.ReadOnlyCell。

示例:

from openpyxl import load_workbook
wb = load_workbook('empty_book.xlsx', read_only=True)    #只讀模式
ws = wb.active
for row in ws.rows:
    for cell in row:
        print(cell.value)
wb.close()    #必須使用close()關閉文件

2、只寫模式

  • 只寫模式使用更快的openpyxl.worksheet._write_only.WriteOnlyWorksheet替代常規的openpyxl.worksheet.worksheet.Worksheet。當您希望轉儲大量數據時,請確保安裝了lxml。
  • 與普通工作簿不同,新創建的只寫工作簿不包含任何工作表必須使用create_sheet()方法專門創建工作表。
  • 在只寫工作簿中,只能使用append()添加行。不能使用cell()或iter_rows()在任意位置寫入(或讀取)單元格。
  • 它能夠導出無限數量的數據(甚至超過Excel實際能夠處理的數量),同時保持內存使用在10Mb以下。
  • 只寫工作簿只能保存一次。在此之后,每次嘗試保存工作簿或將append()添加到現有工作表都會引發openpyxl.utils.exceptions. workbookalreadsaved異常。
  • 在實際單元格數據之前出現在文件中的所有內容都必須在添加單元格之前創建,因為它必須在添加之前寫入文件。例如,在添加單元格之前,應該設置freeze_panes。

示例:

from openpyxl import Workbook
wb = Workbook(write_only=True)   #只寫模式
ws = wb.create_sheet()
for irow in range(100):
    ws.append(['%d' % i for i in range(200)])
wb.save('empty_book.xlsx')
  • 如果你想讓單元格帶有樣式或注釋,那么使用openpyxl.cell.WriteOnlyCell()
    • 這將創建一個只寫的工作簿,只有一個工作表,並添加一行3個單元格:一個文本單元格,帶有自定義字體和注釋,一個浮點數,和一個空單元格

示例:

from openpyxl import Workbook
from openpyxl.cell import WriteOnlyCell
from openpyxl.comments import Comment
from openpyxl.styles import Font

wb = Workbook(write_only=True)
ws = wb.create_sheet()

cell = WriteOnlyCell(ws, value="hello world")
cell.font = Font(name='Courier', size=36)
cell.comment = Comment(text="A comment", author="Author's Name")
ws.append([cell, 3.14, None])
wb.save('empty_book.xlsx')

3、操作sheet(工作表)

1、創建工作表sheet

  • create_sheet(self, title=None, index=None)。title(str):可選參數,工作表的名字;index(int):可選參數,工作表插入的位置(從0開始)。
  • 工作表在創建時會自動命名為“Sheet”。工作表名重復時按順序編號(Sheet、Sheet1、Sheet2、...)。

示例:

from openpyxl import Workbook
wb = Workbook()                         #創建工作簿,同時會創建一個工作表“Sheet”

ws1 = wb.create_sheet()                 #創建一個工作表,默認工作表名“Sheet1”,默認放在當前現有的工作表的最后面
ws2 = wb.create_sheet('Mysheet1', 1)    #創建一個工作表“Mysheet1”,指定放在第一個工作表的后面
ws3 = wb.create_sheet('Mysheet2', 1)    #創建一個工作表“Mysheet2”,指定放在第一個工作表的后面
wb.save('empty_book.xlsx')

2、工作表的其他常用操作

  • 獲取工作表對象的方式
    • 創建工作表時,將工作表對象賦值給一個變量。示例:ws2 = wb.create_sheet('Mysheet1')
    • 將工作簿當作字典,工作表名是字典的鍵。示例:ws2 = wb['Mysheet1'] 
  • 復制工作表的注意事項
    • 僅復制單元格(包括值、樣式、超鏈接和注釋)和某些工作表屬性(包括尺寸、格式和屬性)。不會復制所有其他工作簿/工作表屬性 - 例如圖像、圖表。
    • 也不能在工作簿之間復制工作表。如果工作簿以只讀或只寫模式打開,則無法復制工作表。

示例:

from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws2 = wb.create_sheet('Mysheet1')

wb.copy_worksheet(ws)       #復制工作表
wb.move_sheet('Sheet',1)    #移動工作表
wb.remove(ws2)              #刪除工作表
# del wb['Mysheet1']        #刪除工作表
print(wb.index(ws))         #返回工作表的索引
print(wb.sheetnames)        #返回所有工作表名稱列表,可獲得工作表名稱wb[wb.sheetnames[1]].title
print(wb.worksheets)        #返回所有工作表對象列表,可獲得工作表名稱wb.worksheets[1].title

ws.title = "New Title"                     #修改工作表的名稱
ws.sheet_properties.tabColor = 'FF0000'    #修改工作表的名稱選項卡的背景顏色
wb.save('empty_book.xlsx')

<<<
0
['Sheet', 'Sheet Copy']
[<Worksheet "Sheet">, <Worksheet "Sheet Copy">]

3、循環瀏覽工作表

from openpyxl import Workbook
wb = Workbook()
ws2 = wb.create_sheet('Mysheet')
for sheet in wb:         #循環瀏覽工作表
    print(sheet.title)

<<<
Sheet
Mysheet

4、操作cell(單元格)

  • 在內存中創建工作表時,它不包含任何單元格。它們是在第一次訪問時創建的

1、訪問一個單元格(獲取單元格對象)

  • ws['A4']單元格可以直接作為工作表的鍵進行訪問,這將返回A4處的單元格,如果尚不存在,則創建一個。
  • Worksheet.cell(row, column, value=None)方法

示例:

from openpyxl import Workbook
wb = Workbook()
ws = wb.active

ws['A4'] = 4                             #單元格“A4”賦值為4
ws.cell(row=4, column=2, value=8)        #單元格“B4”賦值為8
print(ws['A4'].value)                    #取出單元格“A4”的值
print(ws.cell(row=4, column=2).value)    #取出單元格“B4”的值
wb.save('empty_book.xlsx')

2、訪問多個單元格(獲取單元格對象)

1、使用切片訪問單元格范圍

  • 可以訪問到范圍內的所有單元格,即在內存中將創建該范圍的所有單元格。

示例:

from openpyxl import Workbook
wb = Workbook()
ws = wb.active

cell_range = ws['A1':'C3']    #在內存中創建出來的這些單元格。返回一個元組,每個元素都是行中的每個單元格對象組成的元組
for row in cell_range:
    print(row)                #行中每個單元格對象組成的元組
    for cell in row:
        print(cell)           #單元格對象

<<<
(<Cell 'Sheet'.A1>, <Cell 'Sheet'.B1>, <Cell 'Sheet'.C1>)
<Cell 'Sheet'.A1>
......
(<Cell 'Sheet'.A2>, <Cell 'Sheet'.B2>, <Cell 'Sheet'.C2>)
......
(<Cell 'Sheet'.A3>, <Cell 'Sheet'.B3>, <Cell 'Sheet'.C3>)
......
<Cell 'Sheet'.C3>

2、切片的方式獲得行或列的范圍

  • 注意,若是才創建的工作表,他們執行后僅僅在內存中創建了部分單元格。若是整列僅創建第一行,若是整行僅創建第一列。

示例:

colC = ws['C']
print(colC)         #(<Cell 'Sheet'.C1>,)
col_range = ws['C:D']
print(col_range)    #((<Cell 'Sheet'.C1>,), (<Cell 'Sheet'.D1>,))
row10 = ws[10]
print(row10)        #(<Cell 'Sheet'.A10>,)
row_range = ws[5:10]
print(row_range)    #((<Cell 'Sheet'.A5>,), (<Cell 'Sheet'.A6>,), (<Cell 'Sheet'.A7>,), (<Cell 'Sheet'.A8>,), (<Cell 'Sheet'.A9>,), (<Cell 'Sheet'.A10>,))

3、Worksheet.iter_rows()方法,以行獲取單元格對象

示例:

from openpyxl import Workbook

wb = Workbook()
ws1 = wb.create_sheet()

for row in ws1.iter_rows(min_row=1, max_col=3, max_row=2):
    for cell in row:
        print(cell)

<<<
<Cell 'Sheet1'.A1>
<Cell 'Sheet1'.B1>
<Cell 'Sheet1'.C1>
<Cell 'Sheet1'.A2>
<Cell 'Sheet1'.B2>
<Cell 'Sheet1'.C2>

4、Worksheet.iter_cols()方法,以列獲取單元格對象只讀模式下不可用

示例:

from openpyxl import Workbook

wb = Workbook()
ws1 = wb.create_sheet()

for col in ws1.iter_cols(min_row=1, max_col=3, max_row=2):
    for cell in col:
        print(cell)

<<<
<Cell 'Sheet1'.A1>
<Cell 'Sheet1'.A2>
<Cell 'Sheet1'.B1>
<Cell 'Sheet1'.B2>
<Cell 'Sheet1'.C1>
<Cell 'Sheet1'.C2>

5、遍歷文件的所有行或列

  • Worksheet.rows屬性,遍歷文件的所有行。
  • Worksheet.columns屬性,遍歷文件的所有列。(在只讀模式下不可用

示例:

from openpyxl import Workbook

wb = Workbook()
ws1 = wb.create_sheet()

ws1['C3'] = 'hello world'
print(tuple(ws1.rows))       #以行遍歷文件
print(tuple(ws1.columns))    #以列遍歷文件

<<<
((<Cell 'Sheet1'.A1>, <Cell 'Sheet1'.B1>, <Cell 'Sheet1'.C1>), (<Cell 'Sheet1'.A2>, <Cell 'Sheet1'.B2>, <Cell 'Sheet1'.C2>), (<Cell 'Sheet1'.A3>, <Cell 'Sheet1'.B3>, <Cell 'Sheet1'.C3>))
((<Cell 'Sheet1'.A1>, <Cell 'Sheet1'.A2>, <Cell 'Sheet1'.A3>), (<Cell 'Sheet1'.B1>, <Cell 'Sheet1'.B2>, <Cell 'Sheet1'.B3>), (<Cell 'Sheet1'.C1>, <Cell 'Sheet1'.C2>, <Cell 'Sheet1'.C3>)) 

3、僅返回單元格的值

  • 如果您只想要工作表中的值,您可以使用該Worksheet.values屬性。這將遍歷工作表中的所有行,但僅返回單元格值。

示例:

for row in ws.values:
   for value in row:
     print(value)
  • Worksheet.iter_rows()和Worksheet.iter_cols()可以采取的values_only參數,只返回單元格的值

示例:

from openpyxl import Workbook
wb = Workbook()
ws = wb.active

for row in ws.iter_rows(min_row=1, max_col=3, max_row=2, values_only=True):
    print('row--', row)
for col in ws.iter_cols(min_row=1, max_col=3, max_row=2, values_only=True):
    print('col--', col)

<<<
row-- (None, None, None)
row-- (None, None, None)
col-- (None, None)
col-- (None, None)
col-- (None, None)

4、單元格的常用操作

1、獲取一個單元格的方法

  • cell(row, column, value=None)
    • 根據給定的坐標返回一個單元格對象。
    • 第一次訪問時,調用cell在內存中創建單元格。
    • 參數
      • row(int):單元格的行索引
      • column(int):單元格的列索引
      • value(numeric或time或string或bool或none):單元格的值

示例:

c3 = ws.cell(3, 3)          #獲取單元格對象    #<Cell 'Sheet1'.C3>
c3 = ws.cell(3, 3, 'c3')    #獲取單元格對象,並將單元格值改為‘c3’
c3.value = 'c3'             #修改單元格的值
c3val = c3.value            #獲取單元格的值

2、獲取多個單元格的對象或值的方法

  • iter_cols( min_col=None , max_col=None , min_row=None , max_row=None , values_only=False )    #(只讀模式下不可用
    • 按列從工作表中生成單元格。使用行和列的索引指定迭代范圍。
    • 如果未指定索引,則范圍從A1開始。
    • 如果工作表中沒有單元格,將返回一個空元組。
    • 參數
      • min_col(int):最小列索引(基於1的索引);
      • min_row(int):最小行索引(基於1的索引);
      • max_col(int):最大列索引(基於1的索引);
      • max_row(int):最大行索引(基於1的索引);
      • values_only(bool):是否只應返回單元格值默認是False返回單元格對象,若為True則返回單元格值
  • iter_rows( min_row=None , max_row=None , min_col=None , max_col=None , values_only=False )
    • 按行從工作表中生成單元格。使用行和列的索引指定迭代范圍。

示例:

icol = ws.iter_cols(min_row=2, max_row=3, min_col=2, max_col=3)                          #返回單元格對象生成器    #<generator object Worksheet._cells_by_col at 0x000001A1CF0DDCF0>
print(tuple(icol))        #結果是:((<Cell 'Sheet1'.B2>, <Cell 'Sheet1'.B3>), (<Cell 'Sheet1'.C2>, <Cell 'Sheet1'.C3>))

icol_val = ws.iter_cols(min_row=2, max_row=3, min_col=2, max_col=3, values_only=True)    #返回單元格值的生成器    #<generator object Worksheet._cells_by_col at 0x000001A1CF0DD0B0>
print(tuple(icol_val))    #結果是:(('B2', 'B3'), ('C2', 'C3'))

3、獲取表中的所有單元格對象

  • rows
    • 以行遍歷文件,返回所有單元格
  • columns    #(在只讀模式下不可用
    • 以列遍歷文件,返回所有單元格

示例:

rs = ws.rows         #返回單元格對象生成器    #<generator object Worksheet._cells_by_row at 0x0000025DF5E1F040>
print(tuple(rs))     #結果是:((<Cell 'Sheet1'.A1>, <Cell 'Sheet1'.B1>, <Cell 'Sheet1'.C1>, <Cell 'Sheet1'.D1>, <Cell 'Sheet1'.E1>), (<Cell 'Sheet1'.A2>, <Cell 'Sheet1'.B2>, <Cell 'Sheet1'.C2>, <Cell 'Sheet1'.D2>, <Cell 'Sheet1'.E2>), (<Cell 'Sheet1'.A3>, <Cell 'Sheet1'.B3>, <Cell 'Sheet1'.C3>, <Cell 'Sheet1'.D3>, <Cell 'Sheet1'.E3>), (<Cell 'Sheet1'.A4>, <Cell 'Sheet1'.B4>, <Cell 'Sheet1'.C4>, <Cell 'Sheet1'.D4>, <Cell 'Sheet1'.E4>), (<Cell 'Sheet1'.A5>, <Cell 'Sheet1'.B5>, <Cell 'Sheet1'.C5>, <Cell 'Sheet1'.D5>, <Cell 'Sheet1'.E5>))

cols = ws.columns    #返回單元格對象生成器    #<generator object Worksheet._cells_by_col at 0x0000025DF5E1FC80>
print(tuple(cols))   #結果是:((<Cell 'Sheet1'.A1>, <Cell 'Sheet1'.A2>, <Cell 'Sheet1'.A3>, <Cell 'Sheet1'.A4>, <Cell 'Sheet1'.A5>), (<Cell 'Sheet1'.B1>, <Cell 'Sheet1'.B2>, <Cell 'Sheet1'.B3>, <Cell 'Sheet1'.B4>, <Cell 'Sheet1'.B5>), (<Cell 'Sheet1'.C1>, <Cell 'Sheet1'.C2>, <Cell 'Sheet1'.C3>, <Cell 'Sheet1'.C4>, <Cell 'Sheet1'.C5>), (<Cell 'Sheet1'.D1>, <Cell 'Sheet1'.D2>, <Cell 'Sheet1'.D3>, <Cell 'Sheet1'.D4>, <Cell 'Sheet1'.D5>), (<Cell 'Sheet1'.E1>, <Cell 'Sheet1'.E2>, <Cell 'Sheet1'.E3>, <Cell 'Sheet1'.E4>, <Cell 'Sheet1'.E5>))

4、獲取表中的所有單元格

  • values
    • 按行生成工作表中的所有單元格值

示例:

vs = ws.values      #返回單元格對象生成器    #<generator object Worksheet.values at 0x000002543827DCF0>
print(tuple(vs))    #結果是:(('A1', 'B1', 'C1', 'D1', 'E1'), ('A2', 'B2', 'C2', 'D2', 'E2'), ('A3', 'B3', 'C3', 'D3', 'E3'), ('A4', 'B4', 'C4', 'D4', 'E4'), ('A5', 'B5', 'C5', 'D5', 'E5'))

5、在表的最后添加一行

  • append(iterable)

    • 在當前工作表的底部附加一組值(在最后添加一行)。
      • 如果是列表:從第一列開始按順序添加所有值
      • 如果是字典:將值分配給鍵(數字或字母)指示的列

示例:

ws.append(['This is A1', 'This is B1', 'This is C1'])    #列表
ws.append({'A': 'This is A1', 'C': 'This is C1'})        #字典
ws.append({1: 'This is A1', 3: 'This is C1'})            #字典

6、刪除、插入列或行

  • delete_cols(idx, amount=1)
    • 刪除一列或多列。從第idx列開始刪除amount列(包含idx)
  • delete_rows(idx, amount=1)
    • 刪除一行或多行,從第idx行開始刪除amount行(包含idx)
  • insert_cols(idx, amount=1)
    • 插入一列或多列,在第idx列插入amount列
  • insert_rows(idx, amount=1)
    • 插入一行或多行,在第idx行前插入amount行

示例:

ws.delete_cols(2, 2)    # 刪除一列或多列,從第2列開始刪除2列(包含第2列)
ws.delete_rows(2, 2)    # 刪除一行或多行,從第2行開始刪除2行
ws.insert_cols(2, 2)    # 插入一列或多列,在第2列前插入2列
ws.insert_rows(2, 2)    # 插入一行或多行,在第2行前插入2行

7、移動單元格

  • move_range( cell_range , rows=0 , cols=0 , translate=False )
    • 按行數或列數移動單元格范圍。
    • 現有單元格將被覆蓋。公式和參考資料將不會更新。
    • 如果rows > 0,則向下移動;如果rows < 0,則向上移動。
    • 如果 cols > 0,則向右移動,如果 cols < 0,則向左移動。
    • 若translate=False移動時單元格中的公式被重新解析到新的單元格。若translate=True只移動單元格中公式的值。

示例:

ws.move_range("A1:C3", rows=3, cols=3)                    #將“A1:C3”范圍的單元格向下移動3行,向右移動3列
ws.move_range("A1:C3", rows=3, cols=3, translate=True)    #將范圍內公式中的相對引用移動3行和3列。

8、合並單元格

  • 當您合並單元格時,除了左上角的所有單元格都將從工作表中刪除。
  • merge_cells(range_string=None, start_row=None, start_column=None, end_row=None, end_column=None)
    • 在單元格范圍上設置合並。Range 是一個單元格區域(例如 A1:E1)
  • unmerge_cells(range_string=None, start_row=None, start_column=None, end_row=None, end_column=None)
    • 取消單元格的合並。Range 是一個單元格區域(例如 A1:E1)

示例:

ws.merge_cells('A2:B4')      #合並單元格
ws.unmerge_cells('A2:B4')    #取消單元格的合並    #注意,范圍要一致
#兩種方式的結果一樣
ws.merge_cells(start_row=2, start_column=1, end_row=4, end_column=2)
ws.unmerge_cells(start_row=2, start_column=1, end_row=4, end_column=2)

9、返回行、列的標識

  • calculate_dimension()
    • 返回包含數據的所有單元格的最小邊界范圍(例如“A1:M24”)
  • dimensions
    • 返回包含數據的所有單元格的最小邊界范圍(例如“A1:M24”)
  • max_column
    • 包含數據的最大列索引(從 1 開始)
  • max_row
    • 包含數據的最大行索引(從 1 開始)
  • min_column
    • 包含數據的最小列索引(從 1 開始)
  • min_row
    • 包含數據的最小行索引(從 1 開始)

示例:

print(ws.calculate_dimension())    #結果是:A1:H5
print(ws.dimensions)               #結果是:A1:H5
print(ws.max_column)               #結果是:8
print(ws.max_row)                  #結果是:5
print(ws.min_column)               #結果是:1
print(ws.min_row)                  #結果是:1

10、插入圖片

  • aadd_image(img, anchor=None)
    • 向工作表添加圖像。可選參數anchor為左上角錨點提供一個單元格

示例:

from openpyxl import Workbook
from openpyxl.drawing.image import Image
wb = Workbook()
ws = wb.active
ws['A1'] = 'You should see three logos below'
img = Image('logo.png')    #創建圖片對象
ws.add_image(img, 'B2')    #將圖片插入工作表
wb.save('empty_book.xlsx')

11、注釋

  • Openpyxl目前只支持讀取和寫入注釋。注釋維度(注釋框的大小)在讀取時丟失,但可以寫入。如果使用read_only=True,則當前不支持(讀寫)注釋。

1、向一個單元格添加注釋

  • 注釋有一個文本屬性和一個作者屬性,這兩個屬性都必須設置
    • def __init__(self, text, author, height=79, width=144)
  • 如果將相同的注釋分配給多個單元格,那么openpyxl將自動創建副本
  • 可以指定注釋維度。注釋維度以像素為單位。

示例:

from openpyxl import load_workbook
from openpyxl.comments import Comment
wb = load_workbook('empty_book.xlsx')
ws = wb.active

comment = Comment('This is the comment text ', 'Comment Author')    #創建一個注釋對象
comment.width = 300
comment.height = 50
ws["A1"].comment = comment                                          #向單元格“A1”添加注釋
ws["B1"].comment = comment

print(ws["A1"].comment is comment)                                  #結果是:True
print(ws["B2"].comment is comment)                                  #結果是:False    #兩個單元格的注釋對象不是同一個
print(ws["A1"].comment.text)                                        #結果是:This is the comment text    #打印單元格“A1”的注釋的text屬性
print(ws["A1"].comment.author)                                      #結果是:Comment Author
wb.save('empty_book.xlsx')
  • 如果需要,openpyxl.utils.units包含幫助函數,用於從其他度量(如mm或點)轉換為像素

示例:

from openpyxl.utils import units
comment.width = units.points_to_pixels(100)
comment.height = units.points_to_pixels(100)

2、加載和保存注釋

  • 加載工作簿時注釋將自動存儲在各自單元格的注釋屬性中。但注釋的格式化信息,如字體大小、粗體和斜體,以及注釋容器框的原始尺寸和位置都將丟失。
  • 保存工作簿時保留在工作簿中的注釋將自動保存到工作簿文件中。

5、使用樣式

  • 樣式用於更改顯示在屏幕上的數據的外觀。它們還用於確定數字的格式。
  • 有兩種樣式:單元格樣式和命名樣式,也稱為樣式模板。
    • 單元格樣式是在對象之間共享的,一旦它們被分配,就不能更改。這就避免了一些不必要的副作用,比如當只有一個單元格發生變化時,就會改變很多單元格的樣式。
    • 與單元格樣式相反,命名樣式可變的。當您想要同時對許多不同的單元格應用格式時,它們是有意義的。注意:將命名樣式分配給單元格后,對樣式的其他更改將不會影響該單元格。
  • 樣式可以應用於以下幾個方面:
    • font 設置字體大小、顏色、下划線等。
    • 填充以設置圖案或顏色漸變
    • 邊框在單元格上設置邊框
    • 單元格對齊
    • 保護

 1、單元格樣式之字體

#字體參數的默認值
from openpyxl.styles import Font
font = Font(name='Calibri',      #字體樣式,例如:黑體、宋體
            size=11,             #字體大小
            bold=False,          #是否加粗
            italic=False,        #是否傾斜
            underline='none',    #下划線。可選的參數有:none無下划線,single單下划線,double雙下划線,singleAccounting滿格單下划線,doubleAccounting滿格雙下划線
            strike=False,        #是否加中橫線
            vertAlign=None,      #縱向對齊方式,superscript在上方, subscript在下方, baseline基線
            color='FF000000')    #字體顏色

示例:

from openpyxl import load_workbook
from openpyxl.styles import Font

wb = load_workbook('empty_book.xlsx')
ws = wb.active
font1 = Font(name='宋體', size=11, bold=True, color='FF000000')      #創建字體樣式對象,宋體、11號、加粗、黑色
font2 = Font(name='宋體', size=16, italic=True, color='00FF0000')    #創建字體樣式對象,宋體、16號、斜體、紅色
a1 = ws['A1']
a2 = ws['A2']
a1.value = 'a1'
a2.value = 'a2'
a1.font = font1    #將字體樣式對象賦給單元格的font屬性
a2.font = font2
wb.save('empty_book.xlsx')

2、單元格樣式之(區域)填充

#單元格填充參數的默認值
from openpyxl.styles import PatternFill
fill = PatternFill(fill_type=None,
                   start_color='FFFFFFFF',
                   end_color='FF000000')
  • fill = PatternFill(patternType=None, fgColor=Color(), bgColor=Color(), fill_type=None, start_color=None, end_color=None)
    • patternType、fill_type功能相同,在樣式中的區域填充模式。
      • 注意:如果不指定fill_type,其他屬性將無效!
      • 值必須是'gray0625', 'darkGray', 'darkDown', 'lightVertical', 'lightUp', 'mediumGray', 'darkGrid', 'darkUp', 'solid', 'darkVertical', 'gray125', 'lightGray', 'lightGrid', 'lightHorizontal', 'darkTrellis', 'lightDown', 'darkHorizontal', 'lightTrellis'之一
    • fgColor、start_color作用相同,前景色。示例:fgColor='0000FF00'
    • bgColor、end_color作用相同,背景色。示例:bgColor='0000FF00'
  •  填充模式和前景色、背景色
    • 前景色時,顏色是圖案的顏色。背景色時,顏色是背景的顏色,圖案顏色是黑色。

 

示例:獲得上面的圖片內容

from openpyxl import load_workbook
from openpyxl.styles import PatternFill
wb = load_workbook('empty_book.xlsx')
ws = wb.active

filltype = ['gray0625', 'darkGray', 'darkDown', 'lightVertical', 'lightUp', 'mediumGray', 'darkGrid', 'darkUp', 'solid',
            'darkVertical', 'gray125', 'lightGray', 'lightGrid', 'lightHorizontal', 'darkTrellis', 'lightDown',
            'darkHorizontal', 'lightTrellis']                                #單元格的18種填充模式
i = 0
for rowi in range(1, 5):
    for coli in range(1, 6):
        try:
            a1 = ws.cell(row=rowi, column=coli, value=filltype[i])           #單元格對象
            fill = PatternFill(fill_type=filltype[i], fgColor='0000FF00')    #創建單元格填充模式對象
            a1.fill = fill                                                   #將單元格填充模式對象賦給單元格fill屬性
            i += 1
        except:
            break
wb.save('empty_book.xlsx')

3、單元格樣式之邊框

#單元格邊框參數的默認值
from openpyxl.styles import Border, Side
border = Border(left=Side(border_style=None, color='FF000000'),
                right=Side(border_style=None, color='FF000000'),
                top=Side(border_style=None, color='FF000000'),
                bottom=Side(border_style=None, color='FF000000'),
                diagonal=Side(border_style=None, color='FF000000'),
                diagonal_direction=0,
                outline=Side(border_style=None, color='FF000000'),
                vertical=Side(border_style=None, color='FF000000'),
                horizontal=Side(border_style=None, color='FF000000')
               )

1、邊框選項

  • 設置單元格邊框的樣子
  • Side(style=None, color=None, border_style=None)
    • 注意:如果不指定border_style,其他屬性將無效!
    • border_style、style功能一樣,值必須是'hair', 'dashDotDot', 'dashDot', 'thin', 'mediumDashed', 'slantDashDot', 'dotted', 'dashed', 'medium', 'thick', 'mediumDashDot', 'double', 'mediumDashDotDot'之一

2、邊框定位 

  • 邊框在單元格的位置(上、下、左、右等)
  • Border(left=None, right=None, top=None, bottom=None, diagonal=None, diagonal_direction=None, vertical=None, horizontal=None, diagonalUp=False, diagonalDown=False, outline=True, start=None, end=None)

示例1:

from openpyxl import load_workbook
from openpyxl.styles import Border, Side
wb = load_workbook('empty_book.xlsx')
ws = wb.active

side_thin = Side(border_style='thin', color="00FF0000")            #創建一個邊框對象(紅色單實線邊框)
side_double = Side(border_style='double', color="00000000")        #創建一個邊框對象(黑色雙實線邊框)
ws['B2'].border = Border(left=side_thin, right=side_thin, top=side_double, bottom=side_double, diagonalUp=True,
                         diagonalDown=True)                        #左右上下(單元格左右紅色單實線邊框,上下黑色雙實線邊框)
ws['C3'].border = Border(diagonal=side_thin, diagonalDown=True)    #斜杠
ws['D4'].border = Border(diagonal=side_double, diagonalUp=True)    #反斜杠
ws['E5'].border = Border(start=side_thin, end=side_double)         #左右
wb.save('empty_book.xlsx')

示例2:獲得上面的圖片內容

from openpyxl import load_workbook
from openpyxl.styles import Border, Side
wb = load_workbook('empty_book.xlsx')
ws = wb.active

borderstyle = ['hair', 'dashDotDot', 'dashDot', 'thin', 'mediumDashed', 'slantDashDot', 'dotted', 'dashed', 'medium',
               'thick', 'mediumDashDot', 'double', 'mediumDashDotDot']
i = 0
for rowi in range(1, 5):
    for coli in range(1, 5):
        try:
            cell = ws.cell(row=rowi, column=coli, value=borderstyle[i])    #單元格對象
            side = Side(border_style=borderstyle[i], color="00FF0000")     #邊框對象
            cell.border = Border(bottom=side)                              #將邊框放在單元格下面
            i += 1
        except:
            break
wb.save('empty_book.xlsx')

4、單元格樣式之對齊

#單元格對齊參數的默認值
from openpyxl.styles import Alignment
alignment=Alignment(horizontal='general',
                    vertical='bottom',
                    text_rotation=0,
                    wrap_text=False,
                    shrink_to_fit=False,
                    indent=0)
  • Alignment(horizontal=None, vertical=None, textRotation=0, wrapText=None, shrinkToFit=None, indent=0, relativeIndent=0, justifyLastLine=None, readingOrder=0, text_rotation=None, wrap_text=None, shrink_to_fit=None, mergeCell=None)
    • horizontal(水平)的值必須是general(常規),center(居中),left(居左),right(居右),distributed(分布整個單元格),fill(充滿單元格,內容重復),justify,centerContinuous之一

    • vertical(垂直)的值必須是top,center,bottom,justify,distributed。

    • textRotation(旋轉文本)的范圍是[0-180]
    • wrapText(文本換行),若為True則換行,若為False則不換行。(其他的參數可能會影響它)
    • shrinkToFit(壓縮至適當尺寸),將文本縮小至單元格可以顯示全部
    • indent=0,單元格的左邊將留出空白

 示例:獲得下面的圖片內容

from openpyxl import load_workbook
from openpyxl.styles import Alignment
wb = load_workbook('empty_book.xlsx')
ws = wb.active

ws.cell(1, 1, value='A').alignment = Alignment(horizontal='center')
ws.cell(1, 2, value='B').alignment = Alignment(vertical='top')
ws.cell(1, 3, value='C').alignment = Alignment(textRotation=30)
ws.cell(1, 4, value='DDDDDDDDDDDDDDDDDDDDD').alignment = Alignment(shrinkToFit=True)
wb.save('empty_book.xlsx')

5、漸變填充區域

  • GradientFill(type="linear", degree=0, left=0, right=0, top=0, bottom=0, stop=())
  • 兩種漸變填充類型:
    • type='linear'漸變是stop指定的一組顏色,橫跨一個區域的長度。可以提供一個顏色列表,它們之間的距離相等。
      • 默認情況下漸變是從左到右的,但是這個方向可以通過degree屬性進行修改。
    • type='path'漸變從區域的每個邊緣應用一個線性漸變。
      • 屬性top, right, bottom, left指定從各自邊界填充的范圍。因此top="0.2"將填充單元格頂部的20%。

示例:

from openpyxl import load_workbook
from openpyxl.styles import GradientFill
wb = load_workbook('empty_book.xlsx')
ws = wb.active

filla = GradientFill(type="linear", degree=0, stop=("000000", "00FF00", "FF0000"))
fillb = GradientFill(type="path", left=0.2, right=0.2, top=0.4, bottom=0.2, stop=("000000", "00FF00", "FF0000"))
ws['A1'].fill = filla
ws['B1'].fill = fillb
wb.save('empty_book.xlsx')

6、應用單元格樣式

1、樣式應用於單元格

from openpyxl.workbook import Workbook
from openpyxl.styles import Font, Fill
wb = Workbook()
ws = wb.active
c = ws['A1']
c.font = Font(size=12)

2、 樣式應用於列和行

  • 請注意,這僅適用於文件關閉后(在Excel中)創建的單元格。如果要將樣式應用於整個行和列,則必須自己將樣式應用於每個單元格
col = ws.column_dimensions['A']
col.font = Font(bold=True)

row = ws.row_dimensions[1]
row.font = Font(underline="single")

3、樣式應用於合並單元格

  • 合並單元格的行為與其他單元格對象類似。它的值和格式在其左上角的單元格中定義。要更改整個合並單元格的邊框,請更改其左上角單元格的邊框。格式化是為了寫作而生成的。
  • 問題:要執行兩次才將邊框作用於整個合並單元格上。

示例:

from openpyxl import load_workbook
from openpyxl.styles import Border, Side, PatternFill, Font, GradientFill, Alignment
wb = load_workbook('empty_book.xlsx')
ws = wb.active
cells = ws.merge_cells('B2:F4')
cell = ws['B2']

thin = Side(border_style="thin", color="000000")
double = Side(border_style="double", color="ff0000")

cell.value = "My Cell"
cell.font = Font(b=True, color="FF0000")
cell.border = Border(top=double, left=thin, right=thin, bottom=double)
cell.fill = PatternFill("solid", fgColor="FFFFFF")
# cell.fill = GradientFill(stop=("00FF00", "000000"))
cell.alignment = Alignment(horizontal="center", vertical="center")
wb.save('empty_book.xlsx')

7、創建命名樣式

  • 在工作簿中注冊了命名樣式后,只需通過名稱就可以引用它。
#創建命名樣式
from openpyxl.styles import NamedStyle, Font, Border, Side
highlight = NamedStyle(name="highlight")                           #創建命名樣式對象
highlight.font = Font(bold=True, size=20)                          #將字體樣式添加到命名樣式中
bd = Side(style='thick', color="000000")
highlight.border = Border(left=bd, top=bd, right=bd, bottom=bd)    #將邊框樣式添加到命名樣式中
#將其注冊到工作簿中
wb.add_named_style(highlight)
#注冊后,僅使用名稱分配樣式
ws['D5'].style = 'highlight'

#命名樣式也可以在第一次分配給單元格時自動注冊
ws['A1'].style = highlight

8、使用內置樣式

  • 該規范包括一些也可以使用的內置樣式。不幸的是,這些樣式的名稱是以本地化的形式存儲的。openpyxl只會識別英文名稱,並且只能和這里寫的完全一樣。(https://openpyxl.readthedocs.io/en/stable/styles.html#using-builtin-styles)

示例:

from openpyxl import load_workbook
wb = load_workbook('empty_book.xlsx')
ws = wb.active
ws['A1'].style = 'Percent'
ws['B2'].style = 'Title'
ws['C3'].style = 'Headline 1'
wb.save('empty_book.xlsx')

6、條件格式

  • Excel支持三種不同類型的條件格式:內置、標准和自定義。
  • 內置樣式將特定的規則與預定義的樣式結合起來。
  • 標准條件格式將特定的規則與自定義格式結合起來。
  • 此外,還可以定義使用差異樣式應用自定義格式的自定義公式。
  • 內置條件格式有三種:
    • ColorScale(色階)
    • IconSet(圖標集)
    • DataBar(數據條)
      • DataBarRule(start_type=None, start_value=None, end_type=None, end_value=None, color=None, showValue=None, minLength=None, maxLength=None)
  • 內置格式包含格式化設置序列,將類型與整數組合起來進行比較。可能的類型是:'num', 'percent', 'max', 'min', 'formula', 'percentile'

1、色階

  • ColorScaleRule(start_type=None, start_value=None, start_color=None, mid_type=None, mid_value=None, mid_color=None, end_type=None, end_value=None, end_color=None)
    • XXX_type可能是:'num', 'percent', 'max', 'min', 'formula', 'percentile'

示例:

from openpyxl import load_workbook
from openpyxl.styles import PatternFill
from openpyxl.formatting.rule import ColorScaleRule
wb = load_workbook('empty_book.xlsx')
ws = wb.active

#使用2種色階
ws.conditional_formatting.add('A1:A100',
                              ColorScaleRule(start_type='max', start_color='FF0000',
                                             end_type='min', end_color='0000FF')
                              )

#使用3種色階
ws.conditional_formatting.add('B1:B100',
                              ColorScaleRule(start_type='percentile', start_value=10, start_color='FF0000',
                                             mid_type='percentile', mid_value=60, mid_color='0000FF',
                                             end_type='percentile', end_value=90, end_color='FFFF00')
                              )

for coli in range(1,3):
    for rowi in range(1,100):
        ws.cell(row=rowi,column=coli,value=rowi)
wb.save('empty_book.xlsx')

2、圖標集

  • 方便創建圖標集規則功能
  • IconSetRule(icon_style=None, type=None, values=None, showValue=None, percent=None, reverse=None)
    • icon_style的值是:'3Flags', '3Signs', '3Arrows', '3TrafficLights2', '3TrafficLights1', '3ArrowsGray', '3Symbols', '3Symbols2', '4TrafficLights', '4Rating', '4Arrows', '4ArrowsGray', '4RedToBlack','5Arrows', '5Rating', '5ArrowsGray', '5Quarters'
    • type可能是:'num', 'percent', 'max', 'min', 'formula', 'percentile'

示例1:

from openpyxl import Workbook
from openpyxl.formatting.rule import IconSetRule
wb = Workbook()
ws = wb.active

ws.conditional_formatting.add('A1:A100',
                              IconSetRule(icon_style='5Rating', type='percent', values=[0, 20, 40, 60, 80], showValue=None, percent=None, reverse=None)
                              )
wb.save('empty_book.xlsx')

示例2:獲得上面的圖片內容

from openpyxl import Workbook
from openpyxl.formatting.rule import IconSetRule
from openpyxl.utils import get_column_letter
wb = Workbook()
ws = wb.active

image = ['3Flags', '3Signs', '3Arrows', '3TrafficLights2', '3TrafficLights1', '3ArrowsGray', '3Symbols', '3Symbols2',
         '4TrafficLights', '4Rating', '4Arrows', '4ArrowsGray', '4RedToBlack', '5Arrows', '5Rating', '5ArrowsGray',
         '5Quarters']
i = 0
for coli in range(1, 18):
    col = get_column_letter(coli)            #將列索引由數字轉換為字母,例如1-->A
    rangestring = '{0}2:{0}6'.format(col)    #獲得單元格范圍,例如A1:A6
    ws.conditional_formatting.add(rangestring,
                                  IconSetRule(image[i], 'formula', [2, 3, 4, 5, 6], showValue=None, percent=None, reverse=None)
                                  )
    for rowi in range(1, 7):
        if rowi == 1:                        #每列的第一行打印icon_style的值
            ws.cell(row=rowi, column=coli, value=image[i])
        else:
            ws.cell(row=rowi, column=coli, value=rowi)
    i += 1
wb.save('empty_book.xlsx')

3、數據條

  • DataBarRule(start_type=None, start_value=None, end_type=None, end_value=None, color=None, showValue=None, minLength=None, maxLength=None)
    • XXX_type可能是:'num', 'percent', 'max', 'min', 'formula', 'percentile'

示例:

from openpyxl import Workbook
from openpyxl.formatting.rule import DataBarRule
wb = Workbook()
ws = wb.active

ws.conditional_formatting.add('A1:D100',
                              DataBarRule(start_type='percentile', start_value=60, end_type='percentile',
                                          end_value='90', color="FF638EC6", showValue="None", minLength=None,
                                          maxLength=None)
                              )
wb.save('empty_book.xlsx')

4、基於單元格比較

  • 添加基於單元格比較的條件格式
  • CellIsRule(operator=None, formula=None, stopIfTrue=None, font=None, border=None, fill=None)    #字體、邊框、填充
    • operator的值是字典的值:{">": "greaterThan", ">=": "greaterThanOrEqual", "<": "lessThan", "<=": "lessThanOrEqual", "=": "equal", "==": "equal", "!=": "notEqual"}
    • formula的值也可以是個序列。例如:formula = [44]

示例:

from openpyxl import load_workbook
from openpyxl.styles import PatternFill
from openpyxl.formatting.rule import CellIsRule
wb = load_workbook('empty_book.xlsx')
ws = wb.active

redFill = PatternFill(start_color='EE1111', end_color='EE1111', fill_type='solid')
#每列大於第一個單元格的標紅
ws.conditional_formatting.add('A2:B100',
                              CellIsRule(operator='greaterThan', formula=['A$1'], stopIfTrue=True, fill=redFill))
#在[1,5]之內的標紅
ws.conditional_formatting.add('C1:F100',
                              CellIsRule(operator='between', formula=['1', '5'], stopIfTrue=True, fill=redFill))
ws['A1'] = 10
ws['B1'] = 10
for coli in range(1, 7):
    for rowi in range(1, 101):
        ws.cell(row=rowi, column=coli, value=rowi)
wb.save('empty_book.xlsx')

5、使用公式格式化

  • FormulaRule(formula=None, stopIfTrue=None, font=None, border=None, fill=None)    #字體、邊框、填充

示例:

from openpyxl import load_workbook
from openpyxl.styles import PatternFill, Font, Border
from openpyxl.formatting.rule import FormulaRule
wb = load_workbook('empty_book.xlsx')
ws = wb.active

redFill = PatternFill(start_color='EE1111', end_color='EE1111', fill_type='solid')
#若單元格是空,顏色為紅
ws.conditional_formatting.add('A1:B100',
                              FormulaRule(formula=['ISBLANK(A1)'], stopIfTrue=True, fill=redFill))
myFont = Font()
myBorder = Border()
#若單元格是3,顏色為紅(若formula=['A1=0']時,比較特殊,注意為空的情況)
ws.conditional_formatting.add('A1:C100',
            FormulaRule(formula=['A1=3'], font=myFont, border=myBorder, fill=redFill))
for coli in range(1, 2):
    for rowi in range(1, 101):
        ws.cell(row=rowi, column=coli, value=rowi)
wb.save('empty_book.xlsx')

圖表

  • https://openpyxl.readthedocs.io/en/stable/charts/introduction.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM