
在以前的推文中,我們介紹了操作Excel的模塊Xlwings的知識,相關(guān)推文可以從本公眾號的底部相關(guān)菜單獲取。有小伙伴反映自己在一些文章中看到openpyxl也能對Excel進(jìn)行相關(guān)的操作,于是留言想在本公眾號里也能看到相關(guān)的教程。于是我開始了本專題的寫作。另外,在推文《操作Excel的Xlwings教程(一)》中,我對比了幾種操作Excel的模塊,大家可以去了解一下。
1.openpyxl簡介
openpyxl是用于讀取/寫入Excel 2010 xlsx/xlsm文件的Python庫,也就是說openpyxl這個(gè)Python庫不支持xls文件的讀取和操作,如果在工作中遇到xls文件我們就不能使用這個(gè)庫。官方說它的誕生是因?yàn)槿鄙倏蓮腜ython本地讀取/寫入Office Open XML格式的庫,為了方便大家就開發(fā)了這個(gè)庫,這是非常棒的。
2.文件轉(zhuǎn)換
上述提到openpyxl只能操作xlsx文件,當(dāng)我們遇到xls文件的時(shí)候就需要進(jìn)行轉(zhuǎn)化,轉(zhuǎn)換方式這里提供幾種方案供大家參考:
方法一:手動(dòng)打開xlsx文件,然后另存為xlsx類型的文件。
方法二:使用pywin32模塊進(jìn)行轉(zhuǎn)換,示例代碼如下:
import os
import win32com.client as win32
filename = r'C:\Users\XH\Desktop\1.xls'
Excelapp = win32.gencache.EnsureDispatch('Excel.Application')
workbook = Excelapp.Workbooks.Open(filename)
# 轉(zhuǎn)xlsx時(shí): FileFormat=51,
# 轉(zhuǎn)xls時(shí): FileFormat=56,
workbook.SaveAs(filename.replace('xls', 'xlsx'), FileFormat=51)
workbook.Close()
Excelapp.Application.Quit()
# 刪除源文件
# os.remove(filename)
# 如果想將xlsx的文件轉(zhuǎn)換為xls的話,則可以使用以下的代碼:
# workbook.SaveAs(filename.replace('xlsx', 'xls'), FileFormat=56)
方法三:使用pandas模塊進(jìn)行轉(zhuǎn)換,代碼如下:
import pandas as pd
filename = r'C:\Users\XH\Desktop\1.xls'
filename2 = r'C:\Users\XH\Desktop\1.xlsx'
read_res = pd.read_excel(filename)
read_res.to_excel(filename2, index=False)
方法三在很多情況下出現(xiàn)一定的錯(cuò)誤,比如在很多時(shí)候因?yàn)樵幢砀竦膯栴}會造成數(shù)據(jù)丟失類的錯(cuò)誤。個(gè)人推薦使用第二種方法。
3.基本操作-創(chuàng)建工作簿
安裝openpyxl這個(gè)模塊非常簡單,cmd窗口中輸入: pip install openpyxl。無需在文件系統(tǒng)上創(chuàng)建文件即可開始使用openpyxl。接下來我們來進(jìn)行一個(gè)簡單操作:
1、創(chuàng)建一個(gè)新的名為Mytest.xlsx文件。
2、在工作簿上第一個(gè)位置新建一個(gè)名為“mytest”的sheet頁。
我們可以這樣來實(shí)現(xiàn),代碼中每一個(gè)操作上都有相應(yīng)的注釋:
from openpyxl import Workbook
# 創(chuàng)建一個(gè)工作簿對象
wb = Workbook()
# 在索引為0的位置創(chuàng)建一個(gè)名為mytest的sheet頁
ws = wb.create_sheet('mytest',0)
# 對sheet頁設(shè)置一個(gè)顏色(16位的RGB顏色)
ws.sheet_properties.tabColor = 'ff72BA'
# 將創(chuàng)建的工作簿保存為Mytest.xlsx
wb.save('Mytest.xlsx')
# 最后關(guān)閉文件
wb.close()
最后生成的文件樣式如下:

那么打開已有的文件Mytest.xlsx,讀取一些信息怎么操作呢?我們可以這樣:
from openpyxl import load_workbook
# 加載工作簿
wb2 = load_workbook('Mytest.xlsx')
# 獲取sheet頁
ws2 = wb2['mytest']
ws3 = wb2.get_sheet_by_name('mytest')
# 打印sheet頁的顏色屬性值
print('color:',ws2.sheet_properties.tabColor)
wb2.close()
上述代碼的輸出如下,可以看到一些屬性值或參數(shù):
color: <openpyxl.styles.colors.Color object>
Parameters:
rgb='00ff72BA', indexed=None, auto=None, theme=None, tint=0.0, type='rgb'
另外,有些小伙伴可能看到上述代碼中,ws2和ws3都是獲取sheet頁簽的。的確這兩種方法的效果是一樣的,大家在平時(shí)的工作中都可以使用。
如果想獲取這個(gè)工作簿的所有sheet頁,可以這樣:
print(wb2.sheetnames)
注意sheetnames屬性值是一個(gè)列表,輸出的結(jié)果為一個(gè)列表:['mytest', 'Sheet']使用for循環(huán)也是可以的:
for each_sheet in wb2.sheetnames:
print('each_sheet:',each_sheet)
4.基本操作-訪問單元格
使openpyxl訪問單元格很簡單,分單個(gè)單元格訪問和多個(gè)單元格的訪問。我們接著來學(xué)習(xí):訪問單元格的方式一般也有兩種做法:假設(shè)現(xiàn)在我們要訪問單個(gè)單元格A1,我們可以這樣:
cell_1 = ws2['A1']cell_2 = ws2.cell(row=1, column=1)
如果要取得這個(gè)單元格的內(nèi)容,只需要在結(jié)尾加上value屬性就可以了:
value_1 = ws2['A1'].value
value_2 = ws2.cell(row=1, column=1).value
如果需要給單元格進(jìn)行設(shè)置值,則可以這樣實(shí)現(xiàn),比如給單元格A1設(shè)置內(nèi)容:
ws2['A1'].value = 'python知識學(xué)堂'
ws2.cell(row=1, column=1).value ='python知識學(xué)堂'
對于多個(gè)單元格的設(shè)置就要借助for循環(huán)了。注意,設(shè)置后要保存工作簿,否則沒有效果。
多個(gè)單元格的獲取一般需要用到列表切片的知識或者使用for循環(huán)來進(jìn)行:
# 訪問A1至C3范圍單元格
cell_range = ws2['A1':'C3']
# 訪問A列所有存在數(shù)據(jù)的單元格
colA = ws2['A']
# 訪問A列到C列所有存在數(shù)據(jù)的單元格
col_range = ws2['A:C']
# 訪問第1行所有存在數(shù)據(jù)的單元格
row1 = ws2[1]
# 訪問第1行至第5行所有存在數(shù)據(jù)的單元格
row_range = ws2[1:5]
注意,上述cell_range等對象都是<class 'tuple'>類型的。如果先獲取這些單元格中的值,我們可以這樣:
for each_cell in cell_range:
for each in each_cell:
print(each.value)
for each_cell in colA:
print(each_cell.value)

至于為什么獲取cell_range和colA的for循序的次數(shù)不一樣,這個(gè)問題就留給大家自己了。
for循環(huán)的方式訪問多個(gè)單元格可以這樣:
for row in ws2.iter_rows(min_row=1, max_col=2, max_row=2):
for cell in row:
print(cell)
#輸出:
<Cell 'mytest'.A1>
<Cell 'mytest'.B1>
<Cell 'mytest'.A2>
<Cell 'mytest'.B2>
for col in ws2.iter_cols(min_row=1, max_col=2, max_row=2):
for cell in col:
print(cell)
#輸出:
<Cell 'mytest'.A1>
<Cell 'mytest'.A2>
<Cell 'mytest'.B1>
<Cell 'mytest'.B2>
這兩個(gè)方法是按行優(yōu)先和列優(yōu)先的順序進(jìn)行訪問單元格的。
大家可以新建一個(gè)工作簿,然后在工作簿中寫入一些數(shù)據(jù),之后運(yùn)行以下代碼看看打印一些什么:
print(tuple(ws2.rows))
print(tuple(ws2.columns))
注意:ws2.rows和ws2.columns是generator對象,因此需要使用tuple進(jìn)行“解析”下。
5.最后的注意
使用openpyxl進(jìn)行工作的時(shí)候,當(dāng)一個(gè)工作結(jié)束的時(shí)候我們需要進(jìn)行Excel文件的保存操作:wb.save('Mytest.xlsx')。這個(gè)保存唯一需要注意的是:文件是默認(rèn)替換的。也就是說我們在保存文件的時(shí)候,openpyxl將進(jìn)行替換而不發(fā)出告警。如果大家想保存不同階段的文件,則可以在保存文件的時(shí)候加一個(gè)時(shí)間戳。
6.總結(jié)
以上就是本次的推文,推文介紹的內(nèi)容比較簡單,大家跟著學(xué)習(xí)的時(shí)候最好也跟著實(shí)踐一下。后期我們將繼續(xù)介紹其他方面的知識。比如在Excel中使用公式,合并單元格等操作。大家在學(xué)習(xí)的時(shí)候有什么疑問,也歡迎在評論區(qū)留言。