利用 Python 對 Excel 文件進行操作需要使用第三方庫: openpyxl,可執行 pip install openpyxl 進行安裝
1. 導入 openpyxl 模塊
導入 openpyxl 模塊后,利用它的 load_workbook() 方法可以打開一個 Excel 文件,該方法使用一個文件名稱作為參數,示例如下:
>>> import openpyxl
>>> wb = openpyxl.load_workbook('example.xlsx')
>>> type(wb)
<class 'openpyxl.workbook.workbook.Workbook'>
2. openpyxl 常用方法
可以使用 openpyxl 對象的 get_sheet_names() 方法得到打開的工作薄中存在的所有工作表名稱、用 get_sheet_by_name() 方法獲取工作表對象、用 active 屬性可獲取當前活躍工作表的名稱:
>>> wb.get_sheet_names()
['Sheet1', 'Sheet2', 'Sheet3']
>>> sheet = wb.get_sheet_by_name('Sheet3')
>>> sheet
<Worksheet "Sheet3">
>>> type(sheet)
<class 'openpyxl.worksheet.worksheet.Worksheet'>
>>> sheet.title
'Sheet3'
>>> anotherSheet = wb.active
>>> anotherSheet
<Worksheet "Sheet1">
3. 獲取單元格屬性
可以直接使用單元格名稱獲取指定單元格,同時單元格具有值、行、列、坐標屬性,舉例如下:
>>> sheet = wb.get_sheet_by_name('Sheet1')
>>> sheet['A1']
<Cell Sheet1.A1>
>>> sheet['A1'].value
datetime.datetime(2015, 4, 5, 13, 34, 2)
>>> c = sheet['B1']
>>> c.value
'Apples'
>>> 'Row ' + str(c.row) + ', Column ' + c.column + ' is ' + c.value
'Row 1, Column B is Apples'
>>> 'Cell ' + c.coordinate + ' is ' + c.value
'Cell B1 is Apples'
>>> sheet['C1'].value
73
4. 使用 cell()
同時也可以使用工作表對象的 cell() 方法來直接指定單元格,使用該方法時要注意,工作表中的行、列都是從1而不是0開始的:
>>> sheet.cell(row=1, column=2)
<Cell Sheet1.B1>
>>> sheet.cell(row=1, column=2).value
'Apples'
>>> for i in range(1, 8, 2):
print(i, sheet.cell(row=i, column=2).value)
1 Apples
3 Pears
5 Apples
7 Strawberries
5. 獲取當前工作表中有效數據區域的行數和列數
>>> sheet.max_row
7
>>> sheet.max_column
3
6. 行、列之間的轉換
需要使用 get_column_letter、column_index_from_string 這兩個方法
>>> from openpyxl.utils import get_column_letter, column_index_from_string
>>> get_column_letter(1)
'A'
>>> get_column_letter(2)
'B'
>>> get_column_letter(27)
'AA'
>>> get_column_letter(900)
'AHP'
>>> get_column_letter(sheet.max_column)
'C'
>>> column_index_from_string('A')
1
>>> column_index_from_string('AA')
27
7. 獲取區域數據
>>> tuple(sheet['A1':'C3'])
((<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>))
8. 獲取指定一行或一列數據
>>> sheet.columns[1]
(<Cell Sheet1.B1>, <Cell Sheet1.B2>, <Cell Sheet1.B3>, <Cell Sheet1.B4>, <Cell Sheet1.B5>, <Cell Sheet1.B6>, <Cell Sheet1.B7>)
9. Excel 讀操作總結
利用 openpyxl 對 excel 文件進行讀操作,主要步驟有以下幾點:
- 導入 openpyxl 模塊
- 調用 openpyxl.load_workbook() 函數
- 獲得 Workbook 對象
- 讀取活躍工作表變量或者調用 get_sheet_by_name() 方法
- 獲得 Worksheet 對象
- 使用索引或使用行、列關鍵詞調用工作表的 cell() 方法
- 獲得 Cell 對象
- 讀取 Cell 對象的屬性值
10. 創建與保存 Excel 文件
創建 Excel 文件需要使用 openpyxl 模塊的 Workbook() 方法,對文件進行操作后,需要調用工作薄對象的 save() 方法進行保存方可使操作生效。
>>> import openpyxl
>>> wb = openpyxl.Wrokbook()
>>> wb.get_sheet_names()
['Sheet']
>>> sheet = wb.active
>>> sheet.title
'Sheet'
>>> sheet.title = 'Spam Bacon Eggs Sheet'
>>> wb.get_sheet_names()
['Spam Bacon Eggs Sheet']
>>> wb.save('example_copy.xlsx')
11. 新增或刪除工作表
增加工作表,需要使用工作薄對象的 create_sheet() 方法。對應的,刪除工作表,需要使用 remove_sheet() 方法。
>>> wb.create_sheet()
<Worksheet "Sheet1">
>>> wb.get_sheet_names()
['Sheet', 'Sheet1']
>>> wb.create_sheet(index=0, title='First Sheet')
<Worksheet "First Sheet">
>>> wb.create_sheet(index=2, title='Middle Sheet')
<Worksheet "Middle Sheet">
>>> wb.get_sheet_names()
['First Sheet', 'Sheet', 'Middle Sheet', 'Sheet1']
如上,創建新工作表時,默認按序號順序創建,並在當前已有工作表末尾附加。如果指定索引和標題,則會以給定的標題在指定索引處進行創建,索引從0開始。
刪除工作表則略復雜,不能直接給 remove_sheet() 方法傳遞工作表名或索引進行刪除,而必須傳遞一個工作表對象方可進行刪除。
>>> wb.remove_sheet(wb.get_sheet_by_name('Middle Sheet'))
>>> wb.remove_sheet(wb.get_sheet_by_name('Sheet1'))
>>> wb.get_sheet_names()
['First Sheet', 'Sheet']
最后,記得要進行 save() 操作,方可使增加或刪除操作生效。
12. 向單元格寫入數據
向單元格寫入數據,只需要在工作表對象中,指定單元格坐標,再進行類似於變量賦值的操作即可
>>> sheet['A1'] = 'Hello world!'
>>> sheet['A1'].value
'Hello world!'
13. 使用 cell() 方法
除了使用單元格坐標的方式獲取單元格對象外,還可以使用工作表對象的 cell() 方法,向其傳入整型的行數、列數來進行指定
>>> sheet.cell(row=2, column=2).value = 'Hello'
>>> sheet['B2'].value
'Hello'
14. 設置字體樣式
對 Excel 中的單元格內的字體樣式進行設置,需要使用 Font() 方法,向其傳入指定參數並將其賦值給指定單元格的 font 屬性即可進行相應設置。該方法需要從 openpyxl.styles 中導入
>>> italic24Font = Font(size=24, italic=True)
>>> sheet['A1'].font = italic24Font
>>> sheet['A1'] = 'Hello world!'
>>> wb.save('styled.xlsx')
一些常用的 Font() 對象屬性
name: 字符串類型。字體名稱,如 Calibri、Times New Roman
size: 整型。字號
bold: 布爾型。是否為粗體
italic: 布爾型。是否為斜體
使用示例:
>>> fontObj1 = Font(name='Times New Roman', bold=True)
>>> sheet['A1'].font = fontObj1
>>> sheet['A1'] = 'Bold Times New Roman'
>>> fontObj2 = Font(size=24, italic=True)
>>> sheet['B3'].font = fontObj2
>>> sheet['B3'] = '24 pt Italic'
>>> wb.save('styles.xlsx')
15. 使用公式
使用公式相對簡單,和向單元格寫入數據相同,把公式作為待寫數據寫入到單元格中即可
>>> sheet['B9'] = '=SUM(B1:B8)'
應注意的是,公式總是以等號(=)開頭的
16. 調整行高與列寬
openpyxl 模塊中有專門的工作表對象變量對行高與列寬進行調整。設置行高,可使用 row_dimensions 屬性,設置列寬,可使用 column_dimensions 屬性
>>> sheet['A1'] = 'Tall row'
>>> sheet['B2'] = 'Wide column'
>>> sheet.row_dimensions[1].height = 70
>>> sheet.column_dimensions['B'].width = 20
>>> wb.save('dimensions.xlsx')
應當注意的是,如果把行高或列寬設置為0,則會將該行、列隱藏
17. 合並單元格與拆分單元格
合並單元格使用 merge_cells() 方法,拆分單元格使用 unmerge_cells() 方法,這兩個方法接受一個字符串格式的參數,該參數從左上角至右下角指定一整塊區域用於合並或拆分。舉例如下
>>> sheet.merge_cells('A1:D3')
>>> sheet['A1'] = 'Twelve cells merged together.'
>>> sheet.merge_cells('C5:D5')
>>> sheet['C5'] = 'Two merged cells.'
>>> wb.save('merged.xlsx')
>>> sheet.unmerge_cells('A1:D3')
>>> sheet.unmerge_cells('C5:D5')
>>> wb.save('merged.xlsx')
18. 凍結窗格
要實行凍結窗格操作,需要使用工作表對象的 freeze_panes 屬性,向該屬性指定一個單元格位置,則在該單元格左側與上側的區域將被凍結。但該單元格本身並不在凍結范圍內
>>> sheet.freeze_panes = 'A2'
以上代碼將把工作表中第一行給凍結
19. 創建圖表
創建圖表相對較為復雜,主要有以下5個步驟
- 從一塊矩形區域中創建一個 Reference 對象
- 使用該 Reference 對象創建一個 Series 對象
- 創建 Chart 對象
- 把 Series 對象附加到 Chart 對象中
- 把 Chart 對象添加到工作表對象中。可以選擇指定圖表左上角位置
Reference 對象使用 openpyxl.chart.Reference() 創建,其接收3個參數:
- 包含用於創建圖表的數據的工作表對象
- 由2個整型數據組成的組合。分別代表數據區域的左上角單元格的行數、列數
- 由2個整型數據組成的組合。分別代表數據區域的右下角單元格的行數、列數
(作者此處描述似乎有誤,准確的說應該是5個參數了,第1個是工作表對象,第2個是數據區域左上角單元格所在的行數,第3個是數據區域左上角單元格所在的列數,第4個是數據區域右下角單元格所在的行數,第5個是數據區域右下角單元格所在的列數)
創建圖表示例如下:
>>> refObj = openpyxl.chart.Reference(sheet, min_col=1, min_row=1, max_col=1, max_row=10)
>>> seriesObj = openpyxl.chart.Series(refObj, title='First series')
>>> chartObj = openpyxl.chart.BarChart()
>>> chartObj.title = 'My Chart'
>>> chartObj.append(seriesObj)
>>> sheet.add_chart(chartObj, 'C5')
>>> wb.save('sampleChart.xlsx')
本示例中,數據區域為 A1:A10
結果如下(圖中各個 pixels 參數可忽略):
作者在 sheet.add_chart() 函數中指定了圖表左上角位置為 C5,但在結果中顯示的卻並不是這樣。在下亦不解