最近工作需要整理將近60位同事的周報合並到一個excel中,每周都會占用的大量的時間。希望把這個工作自動化,網上看了下基本都是用vba編程實現這一功能。由於沒有使用過vba,希望使用自己會的東西去實現。
我們的周報模板大致是這個樣子的:
搜了下python操作excel的包,看到最多的是xlrd和xlwt。我的操作其實很簡單就是拷貝每一個excel中的內容並粘貼到一個匯總的excel,但這兩個包好像並不符合我的要求。
偶然間看到xlwings這個python包,使用這個包基本可以實現你在excel中的操作,如選中B5 到J20 這些單元格中的數據。這正是我想要的,寫了個簡單的腳本實現周報的整理,在這里記錄下。
使用中參考了xlwings官方文檔
我主要使用了WorkBook、Sheet、Range這三個。
self.wb.sheets.add('Shope Info')#這句話是添加一個工作表名哦
import xlwings as xw
#app_visible=False 不打開excel窗口
wb = xw.Workbook(path), app_visible=False)
detail_sheet = xw.Sheet(unicode("任務詳細信息", "utf-8"))
#獲取有數據的最大行數,由於我們單個excel數據不會超過幾十行,我使用的是B4:I40
last_row_index = xw.Range(detail_sheet, "B4").table.last_cell.row
#確定我們選取的數據范圍,如: B4:I20
rg = "B4:I" + str(last_row_index)
#獲取划定范圍單元格中的數據
work_detail = xw.Range(detail_sheet, rg).value
#關閉打開的excel
wb.close()
接下來就是將work_detail 獲取到的數據拷貝到我們匯總的excel中,代碼幾乎一致
target_excel_path = u"F:\經分應用產品線小組周報模板.xlsx"
wb_target = xw.Workbook(target_excel_path, app_visible=False)
cr_sheet = xw.Sheet(u"任務詳細信息")
#清空內容,單不清空格式
xw.Range(cr_sheet, "B4:I200").clear_contents()
xw.Range(cr_sheet, "B4").table.value = work_detail
wb_target.save(u"F:\經分應用產品線小組周報.xlsx")
wb_target.close()
(PS 后面希望加入自動添加數據透視圖的功能,暫時還沒找到這方面的接口)
好了,以后只需要run一下python腳本,自動整理並且發送郵件給負責人。
搞定 。。。。。。
- xlwings基本對象
xlwings基本對象
App相當於Excel程序,Book相當於工作簿。N個Excel程序則由apps表示,N個工作簿由books表示。
- 對工作簿的操作
#導入xlwings模塊 import xlwings as xw #新建工作簿,這里默認為新建了一個App,即打開Excel程序,並新建一個工作簿 xw.Book() #引用工作簿 xw.Book('工作簿3') # 引用工作簿也可以用books xw.books['工作簿3’] #打開已有工作簿 xw.Book(r'e:\myworkbook.xlsx')
- 對sheet以及Range的操作
import xlwings as xw wb=xw.Book() # 引用名字為"sheet2"的sheet sht=wb.sheets['sheet2'] # 引用"sheet2"中的B1單元格 rng=sht.range('B1') # 將B1單元格的值改為666 rng.value=666
數據結構
- 一維數據
python的列表,可以和Excel中的行列進行數據交換,python中的一維列表,在Excel中默認為一行數據import xlwings as xw sht=xw.sheets.active # 將1,2,3分別寫入了A1,B1,C1單元格中 sht.range('A1').value=[1,2,3] # 將A1,B1,C1單元格的值存入list1列表中 list1=sht.range('A1:C1').value # 將1,2,3分別寫入了A1,A2,A3單元格中 sht.range('A1').options(transpose=True).value=[1,2,3] # 將A1,A2,A3單元格中值存入list1列表中 list1=sht.range('A1:A3').value
- 二維數據
python的二維列表,可以轉換為Excel中的行列。二維列表,即列表中的元素還是列表。在Excel中,二維列表中的列表元素,代表Excel表格中的一列。例如:# 將a1,a2,a3輸入第一列,b1,b2,b3輸入第二列 list1=[[‘a1’,'a2','a3'],['b1','b2','b3']] sht.range('A1').value=list1
運行結果# 將A1:B3的值賦給二維列表list1 list1=sht.range('A1:B3‘).value
- Excel中區域的選取表格
# 選取第一列 rng=sht. range('A1').expand('down') rng.value=['a1','a2','a3']
第一列# 選取第一行 rng=sht.range('A1').expand('right') rng=['a1','b1']
第一行# 選取表格 rng.sht.range('A1').expand('table') rng.value=[[‘a1’,'a2','a3'],['b1','b2','b3']]
表格
結束
- 本文首先簡單介紹了,通過Python運用xlwings模塊,對Excel工作簿、工作表和單元格的操作。
- 再介紹了xlwings,如何對Excel表格的行和列寫入和引用數據
- 通過二維或者一維列表對Excel工作表的數據進行寫入或者引用,既簡化了代碼,也提高了程序的效率。因為python讀寫Excel表格的速度,原小於python程序自身的運行速度。
=================================
xlwings如何設置字體、顏色等屬性
最近使用python在寫一個小軟件,中間需要處理excel文件,所以了解了一下,使用python來操作excel文件的模塊有很多,參考了[1]中的模塊對比:



於是果斷選擇了“xlwings”作為我操作excel的模塊。不得不說,xlwings是一個非常好的模塊,根據網上的教程以及官方文檔[2]我很快完成了數據讀寫部分的程序,而且測試了一下,整體讀寫的速度都很快。
但是在測試的過程中,遇到的第一個問題來了。
xlsx文件被鎖定了怎么辦?
下圖就是我在debug完了以后,再次打開我的xlsx文件想去看看效果的時候彈出來的通知

查閱資料后,發現是因為我們在debug過程中結束程序后,沒有執行到app.quit()語句來關閉xlwings創建的app,所以后台這個xlsx進程並沒有關閉。

所以解決這個問題的方法很簡單,打開任務管理器,找到上圖進程,然后結束進程即可。
xlwings如何設置字體、顏色等屬性
這部分是今天主要解決的問題。目前網上我所看到的所有關於xlwings的資料都沒有提到設置字體的方面,甚至我在官方文檔[2]中也沒有看到關於設置字體的函數,在貼吧里還看到有兄弟說xlwings不能修改字體:

正好我的軟件里面需要修改xlsx文件中的字體及其顏色,而且我的軟件已經使用xlwings模塊寫了很大一部分了,再換模塊顯然是不划算的,所以我決定深入研究一下。
我在使用xlwings完成按列降序排列的時候參考了@RobbenEmi 的博文[3],非常感謝@RobbenEmi,雖然他的博文很短,但是他一定是做過深入研究的。
受@RobbenEmi 博文[3]的啟發,我感覺突破口可能在xlwings的api方法上,於是我返回官方文檔[2]重新查找相應的函數方法,如下圖所示。

看到這句話,再結合@RobbenEmi 的博文[3],我去微軟官網查看了一下office VBA參考中的Font.Color方法

再結合xlwings官方文檔中說的使用api()方法返回的是pywin32或appscript對象,我在網上查閱了pywin32如何操作xlsx文件,參考了@帥胡 的博文[4],我實現了使用xlwings模塊設置字體、顏色、加粗等屬性。
如下源碼展示如何獲取相應的屬性。
# coding: utf-8
import xlwings as xw
app=xw.App(visible=False,add_book=False)
filepath = '../data/test.xlsx'
wb=app.books.open(filepath)
sht = wb.sheets('Sheet1')
font_name = sht.range('A1').api.Font.Name # 獲取字體名稱
font_size = sht.range('A1').api.Font.Size # 獲取字體大小
bold = sht.range('A1').api.Font.Bold # 獲取是否加粗,True--加粗,False--未加粗
color = sht.range('A1').api.Font.Color # 獲取字體顏色
print(font_name)
print(font_size)
print(bold)
print(color)
wb.save()
wb.close()
app.quit()
打印的結果如下

相應xlsx文件中的信息如下

xlwings模塊獲取結果與實際xlsx文件字體屬性吻合,因為xlwings模塊相同的語句既可以獲取property又可以set property,所以設置相應屬性的源碼如下。
# coding: utf-8
import xlwings as xw
app=xw.App(visible=False,add_book=False)
filepath = '../data/test.xlsx'
wb=app.books.open(filepath)
sht = wb.sheets('Sheet1')
font_name = sht.range('A1').api.Font.Name # 獲取字體名稱
font_size = sht.range('A1').api.Font.Size # 獲取字號
bold = sht.range('A1').api.Font.Bold # 獲取是否加粗,True--加粗,False--未加粗
color = sht.range('A1').api.Font.Color # 獲取字體顏色
print(font_name)
print(font_size)
print(bold)
print(color)
print('-----設置-----')
sht.range('A1').api.Font.Name = 'Times New Roman' # 設置字體為Times New Roman
sht.range('A1').api.Font.Size = 15 # 設置字號為15
sht.range('A1').api.Font.Bold = True # 加粗
sht.range('A1').api.Font.Color = 0x0000ff # 設置為紅色RGB(255,0,0)
font_name = sht.range('A1').api.Font.Name # 獲取字體名稱
font_size = sht.range('A1').api.Font.Size # 獲取字體大小
bold = sht.range('A1').api.Font.Bold # 獲取是否加粗,True--加粗,False--未加粗
color = sht.range('A1').api.Font.Color # 獲取字體顏色
print(font_name)
print(font_size)
print(bold)
print(color)
wb.save()
wb.close()
app.quit()
打印的結果如下

相應xlsx文件中的信息如下

現在你可以使用xlwings自由地設置你想要的任何字體屬性了!
細心的你一定會觀察到,我這段設置字體屬性的源碼中,設置字體顏色的那句代碼的賦值,並不是紅色RGB(255,0,0)的十六進制6位顏色碼,這是怎么回事呢?
在下一篇博文(關於顏色碼的幾種常用表示及其相互轉換)中,我會討論RGB顏色碼的一些問題,相信你會在下篇博文找到答案。
補充資料
獲取工作表的總行數和總列數
workbook=xw.Book(r'path) workbook.sheets[1].range(1, 1).expand().shape 返回:(25087, 3)