Bokeh是一個Python庫,用于對Excel 2010 xlsx/xlsm/xltx/xltm文件進行讀寫操作。
官網對該工具的介紹為:
openpyxl is a Python library to read/write Excel 2010 xlsx/xlsm/xltx/xltm files.It was born from lack of existing library to read/write natively from Python the Office Open XML format.All kudos to the PHPExcel team as openpyxl was initially based on PHPExcel.
官網地址為:https://foss.heptapod.net/openpyxl/openpyxl
本文檔只說明某些接口的使用,作為對該工具的學習總結。
文件的打開,創建,保存
創建一個工作簿
from openpyxl import Workbookwb = Workbook()
打開一個已經存在的工作簿
from openpyxl import load_workbookwb = load_workbook('sample.xlsx')
在load_workbook()中存在幾個可選參數:
- data_only=True表示只讀取單元格的值,而不是公式
- read_only=True表示以只讀模式打開Excel文件,這樣可以提高讀取速度
- keep_vba=True表示保留Excel文件中的宏代碼
保存為工作薄
wb.save('sample.xlsx')
創建一個工作表
ws = wb.create_sheet("Mysheet") # insert at the end (default)
ws = wb.create_sheet("Mysheet", 0) # insert at first position
ws = wb.create_sheet("Mysheet", -1) # insert at the penultimate position
激活某個工作表
ws = wb.active
該值默認為0,除非手動修改活動工作表,否則通過該方法只會獲取第一個工作表的引用。不然要明確指明激活的工作表,下面代碼就是獲取名字為new_sheet的工作表的引用:
ws = wb["new_sheet"]
重命名工作表
在使用Workbook創建工作簿時,會自動創建一個名為Sheet的工作表。并且在工作薄中創建的工作表會采用自動命名的形式,如Sheet1、Sheet2、Sheet3。如果需要對該名稱進行修改,可以使用title屬性進行修改,如下所示:
ws.title = "New Title"
獲取工作薄中所有工作表的名稱
wb.sheetnames
或者采用遍歷工作薄的形式:
for sheet in wb:print(sheet.title)
復制工作表
new_ws = wb.copy_worksheet(ws)
單元格的操作
獲取單元格的引用
cell = ws["A4"]
cell = ws.cell(row=4, column=1)
但需注意的是,ws["A4"]的引用方式和excel中單元格的表示方式相同,但是使用cell()方法時,row和column的索引都是從1開始的數字,而不是字母,這意味著,需要將A4轉換為(4,1)。
獲取單元格的值
value = ws["A4"].value
value = ws.cell(row=4, column=1).value
單元格賦值
ws["A4"] = 10
ws["A4"].value = 10
ws.cell(row=4, column=1, value=10)
當創建工作薄時,雖然它包含一個工作表,但是該工作表中并不包含任何單元格。只有在訪問單元格時,才會創建它們。因此使用ws.cell(row=4, column=1)雖然沒有賦值,但是也會在內存中創建單元格,因此要盡量避免對空單元格的引用。
插入整行或整列、刪除整行或整列
ws.insert_rows(7, 3) ? ? ? ? ? ?# 表示在原來idx=7的行前插入3行,默認一行
ws.insert_cols(2, 3) ? ? ? ? ? ?# 表示在原來idx=2的列前插入3列,默認一列
ws.append([1, 2, 3]) ? ? ? ? ? ?# 表示在最后一行插入數據,不足的部分用None填充ws.delete_cols(6, 3) ? ? ? ? ? ?# 表示刪除idx=6的列,刪除3列,默認一列
ws.delete_rows(6, 3) ? ? ? ? ? ?# 表示刪除idx=6的行,刪除3行,默認一行
訪問整列或整行
cells = ws["A"] ? ? ? ? ? ? ?# 獲取A列的所有單元格
cells = ws[1] ? ? ? ? ? ? ? ?# 獲取第一行的所有單元格
訪問矩形區域
cells = ws["A:C"] ? ? ? # 獲取A到C列的所有單元格
cells = ws[1:3] ? ? ? ? # 獲取第1到3行的所有單元格
cells = ws["A1:C3"] ? ? # 獲取A1到C3的所有單元格
但需要注意,對于整列或整行的訪問返回的是一維元組,而對于矩形區域的訪問返回的是二維元組。因此,對于矩形區域的訪問,需要使用兩層循環來遍歷。
或者可以通過ws.iter_rows()或ws.iter_cols()來獲取單元格:
for rows in ws.iter_rows():for cell in rows:print(cell.value)for cols in ws.iter_cols(min_row=1, max_col=3, max_row=2):for cell in cols:print(cell.value)for values in ws.iter_cols(min_row=1, max_col=3, max_row=2, values_only=True):for value in values:print(value)
從上面可以看出
- iter_rows()和iter_cols()方法都可以接收min_row、max_row、min_col、max_col、values_only這四個參數
- 這幾個參數都是可選的,如果不指定,則默認為min_row=1、max_row=ws.max_row、min_col=1、max_col=ws.max_column,values_only=False
- iter_rows()方法按行遍歷,iter_cols()方法按列遍歷
- values_only = True表示只迭代值
另外ws.iter_rows()無參數的調用即可遍歷所有行,ws.iter_cols()無參數的調用即可遍歷所有列。等效于下面的用法:
for rows in ws.rows:for cell in rows:print(cell.value)for cols in ws.columns:for cell in cols:print(cell.value)
不過因為性能問題,只讀模式下ws.iter_cols()方法和ws.columns不可用。
而如果只是想要獲取單元格中的內容,則可以使用ws.values:
for values in ws.values:for value in values:print(value)
從結果可以看出,ws.values是按行迭代的。
移動區域
ws.move_range("D4:F10", rows=-1, cols=2) ? ? ? ?# 表示將D4:F10的單元格向上移動一行,向右移動兩列,即移動到E3:G9
合并/拆分單元格
ws.merge_cells('A2:D2')
ws.unmerge_cells('A2:D2')# 與下面的設置等效
ws.merge_cells(start_row=2, start_column=1, end_row=4, end_column=4)
ws.unmerge_cells(start_row=2, start_column=1, end_row=4, end_column=4)
而對比合并后的單元格的格式設置,只需要對合并單元格的左上角單元格進行設置即可。
字體、顏色、樣式
默認設置為:
from openpyxl.styles import PatternFill, Border, Side, Alignment, Protection, Fontfont = Font(name='Calibri',size=11,bold=False,italic=False,vertAlign=None,underline='none',strike=False,color='FF000000')fill = PatternFill(fill_type=None,start_color='FFFFFFFF',end_color='FF000000')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'))alignment=Alignment(horizontal='general',vertical='bottom',text_rotation=0,wrap_text=False,shrink_to_fit=False,indent=0)protection = Protection(locked=True,hidden=False)
設置字體、顏色、大小
from openpyxl.styles import Font# 斜體,紅色,20號,字體為Arial,加粗
ft = Font(name='Arial', size=20, bold=True, italic=True, color='FF0000')ws["A4"].font = ftwb.save('sample.xlsx')
設置單元格填充
from openpyxl.styles import PatternFill# 紅色填充
ft = PatternFill(fill_type='solid', fgColor='FF0000')ws["A3"].fill = ftwb.save('sample.xlsx')
設置對齊方式
from openpyxl.styles import Alignment# 左對齊,上對齊
al = Alignment(horizontal='left', vertical='top')ws["A3"].alignment = alwb.save('sample.xlsx')
在選擇對齊方式中:
- horizontal的參數選擇范圍為:'fill', 'right', 'justify', 'general', 'distributed', 'center', 'centerContinuous', 'left'
- vertical的參數選擇范圍為:'bottom', 'top', 'distributed', 'justify', 'center'
單元格邊框
from openpyxl.styles import Border, Sideleft_side = Side(border_style='thin', color='FF0000')
right_side = Side(border_style='thin', color='00FF00')
top_side = Side(border_style='thin', color='0000FF')
bottom_side = Side(border_style='thin', color='FFFF00')ws["A3"].border = Border(left=left_side, right=right_side, top=top_side, bottom=bottom_side)wb.save('sample.xlsx')
border_style可以為:'dashDot', 'mediumDashDot', 'slantDashDot', 'thick', 'dashed', 'hair', 'mediumDashDotDot', 'medium', 'thin', 'dotted', 'double', 'mediumDashed', 'dashDotDot'
應用到整行或整列
col = ws.column_dimensions['A']
col.font = Font(bold=True)row = ws.row_dimensions[1]
row.font = Font(underline="single")
列寬和行高
在openpyxl中,column_dimensions和rows_dimensions都是一個字典,key為列或行的索引,value為ColumnDimension或RowDimension對象。該對象為表格中每行或每列的信息,主要包括:
- width 屬性:獲取或設置列的寬度。
- hidden 屬性:獲取或設置列的隱藏狀態。
- bestFit 屬性:獲取或設置列的自動調整大小。
- style 屬性:獲取或設置列的樣式。
- number_format 屬性:獲取或設置列的數字格式。
col = ws.column_dimensions['A']
col.width = 20.0
col.hidden = False
col.bestFit = True
col.number_format = "0.00"row = ws.row_dimensions[1]
row.height = 40.0
row.hidden = False
row.bestFit = True
row.number_format = "0.00"
頁面設置
工作表中頁面設置可以通過page_setup屬性進行設置,page_setup屬性是一個PageSetup對象,該對象包含了頁面設置的各種屬性,如紙張大小、方向、頁邊距等。
以下是一些常用的 PageSetup 類的屬性和方法:
- orientation 屬性:設置頁面的方向,可以是 PageSetup.ORIENTATION_PORTRAIT(縱向)或 PageSetup.ORIENTATION_LANDSCAPE(橫向)。
- paperSize 屬性:設置紙張大小,可以是預定義的常量,如 PageSetup.PAPERSIZE_A4。
- leftMargin、rightMargin、topMargin、bottomMargin 屬性:設置工作表的左、右、上、下頁邊距。
- printArea 屬性:設置打印區域。
示例代碼如下:
# 設置頁面方向為橫向
ws.page_setup.orientation = ws.ORIENTATION_LANDSCAPE# 設置紙張大小為A4
ws.page_setup.paperSize = ws.PAPERSIZE_A4# 設置邊距
ws.page_setup.leftMargin = 0.5
ws.page_setup.rightMargin = 0.5
ws.page_setup.topMargin = 0.5
ws.page_setup.bottomMargin = 0.5# 設置打印區域
ws.page_setup.printArea = 'A1:F20'# 保存工作簿
wb.save("sample.xlsx")
樣式保存
上面的格式配置可以保存為NamedStyle對象,然后應用到單元格上:
from openpyxl.styles import NamedStylemy_style = NamedStyle(name='my_style')
my_style.font = Font(bold=True, size=20)
my_style.alignment = Alignment(horizontal='center', vertical='center')wb.add_named_style(my_style) ? ? ? ?# 創建樣式后,可以將該樣式注冊到工作簿中
# ws["A1"].style = my_style ? ? ? ? ? # 將樣式賦值給單元格也可以完成自動注冊# 注冊完成后,就可以通過以下方式直接使用樣式
ws["A1"].style = "my_style"
內建樣式
openpyxl中還存在很多內建樣式,用戶可以直接通過樣式名稱使用,詳情可查看openpyxl.styles.builtins。
‘Normal’:就是無樣式
Number formats:
- ‘Comma’
- ‘Comma [0]’
- ‘Currency’
- ‘Currency [0]’
- ‘Percent’
Informative:
- ‘Calculation’
- ‘Total’
- ‘Note’
- ‘Warning Text’
- ‘Explanatory Text’
Text styles:
- ‘Title’
- ‘Headline 1’
- ‘Headline 2’
- ‘Headline 3’
- ‘Headline 4’
- ‘Hyperlink’
- ‘Followed Hyperlink’
- ‘Linked Cell’
Comparisons:
- ‘Input’
- ‘Output’
- ‘Check Cell’
- ‘Good’
- ‘Bad’
- ‘Neutral’
Highlights:
- ‘Accent1’
- ‘20 % - Accent1’
- ‘40 % - Accent1’
- ‘60 % - Accent1’
- ‘Accent2’
- ‘20 % - Accent2’
- ‘40 % - Accent2’
- ‘60 % - Accent2’
- ‘Accent3’
- ‘20 % - Accent3’
- ‘40 % - Accent3’
- ‘60 % - Accent3’
- ‘Accent4’
- ‘20 % - Accent4’
- ‘40 % - Accent4’
- ‘60 % - Accent4’
- ‘Accent5’
- ‘20 % - Accent5’
- ‘40 % - Accent5’
- ‘60 % - Accent5’
- ‘Accent6’
- ‘20 % - Accent6’
- ‘40 % - Accent6’
- ‘60 % - Accent6’
- ‘Pandas’
圖表
圖表實際使用的并不多,這里只是簡單介紹一下,詳細的可以參考官方文檔。
from openpyxl.chart import BarChart, Series, Reference# 創建一個柱狀圖,指定圖表類型為col,標題為Bar Chart,橫坐標為time,縱坐標為value
chart = BarChart()
chart.type = "col"
chart.title = "Bar Chart"
chart.x_axis.title = 'time'
chart.y_axis.title = 'value'
chart.legend = None# 設置數據來源
data = Reference(ws, min_col=2, min_row=1, max_col=3, max_row=6)
cats = Reference(ws, min_col=1, min_row=2, max_row=6)# 將數據添加到圖表中
chart.add_data(data, titles_from_data=True)
chart.set_categories(cats)# 將圖表添加到E1單元格中
ws.add_chart(chart, "E1")
wb.save('sample.xlsx')
上面內容只是對openpyxl的一些常見的部分進行了簡單的介紹,其他更多內容,如過濾、排序、數據有效性驗證等,可以參考官方文檔。