讓Excel飛起來——xlwings


最近工作需要整理將近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腳本,自動整理並且發送郵件給負責人。
搞定 。。。。。。




 

 

 

 

  1. xlwings基本對象

    xlwings基本對象

App相當於Excel程序,Book相當於工作簿。N個Excel程序則由apps表示,N個工作簿由books表示。

  1. 對工作簿的操作
    #導入xlwings模塊
    import xlwings as xw
    #新建工作簿,這里默認為新建了一個App,即打開Excel程序,並新建一個工作簿
    xw.Book()
    #引用工作簿
    xw.Book('工作簿3')
    # 引用工作簿也可以用books
    xw.books['工作簿3’]
    #打開已有工作簿
    xw.Book(r'e:\myworkbook.xlsx')
  2. 對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

數據結構

  1. 一維數據
    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
  2. 二維數據
    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
  3. 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)

 


免責聲明!

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



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