最近在嘗試用Python操作Excel,接觸到了xlwings這個(gè)庫,在我查閱關(guān)于這個(gè)庫的介紹文章時(shí),發(fā)現(xiàn)絕大多數(shù)的教程都寫得很含糊,要么“點(diǎn)到為止”,只介紹了幾種常用的操作,要么就是將一堆代碼羅列出來,沒有進(jìn)行解釋說明,還有一些文章里的解釋壓根就是錯(cuò)誤的??傊?,我還沒有發(fā)現(xiàn)一篇讓我滿意的系統(tǒng)全面的教程。后來我直接去看了官方文檔,認(rèn)識(shí)到這個(gè)庫遠(yuǎn)比網(wǎng)上文章里介紹的強(qiáng)大得多,所以決定自己來寫,既可以當(dāng)做筆記,也能幫助大家更全面地了解這個(gè)庫的用法。
關(guān)于Python編譯器和xlwings庫的安裝和配置可以看下面篇文章,這里就不做說明了。
辦公自動(dòng)化系列(1) | Python與Excel交互教程 - 環(huán)境搭建
在正式介紹xlwings的用法之前,我們先明確幾個(gè)概念:
- 新建:創(chuàng)建一個(gè)不存在的工作薄或者工作表
- 打開:打開一個(gè)已經(jīng)存在的工作薄
- 引用:就是告訴程序,你要操作哪個(gè)對(duì)象。比如你打開了A、B、C三個(gè)工作薄,現(xiàn)在你想操作B工作薄,就要先引用B
- 激活:我們可以同時(shí)打開多個(gè)工作薄,但是一次只能操作一個(gè)工作簿,我們正在操作的這個(gè)工作薄稱為當(dāng)前活動(dòng)工作薄,激活的意思就是將某一個(gè)對(duì)象(工作薄或工作表等)變成當(dāng)前活動(dòng)對(duì)象
這里重點(diǎn)要理解引用和激活的區(qū)別,當(dāng)我們希望操作一個(gè)對(duì)象的時(shí)候,首先要引用這個(gè)對(duì)象,但引用工作薄并不會(huì)激活這個(gè)工作薄,比如我們先打開A工作薄,再打開B工作薄,那么當(dāng)前活動(dòng)工作薄是B,當(dāng)我們對(duì)A進(jìn)行引用之后,活動(dòng)工作薄仍然是B,只有當(dāng)我們對(duì)A進(jìn)行操作之后,A才會(huì)變成活動(dòng)工作薄。
啰嗦了這么多,就是希望大家先把這幾個(gè)概念理解清楚,因?yàn)樵趚lwings中,很多操作都有多種實(shí)現(xiàn)方式,表面上看沒有區(qū)別,但“內(nèi)藏玄機(jī)”,概念理解不清晰,編寫代碼時(shí)就容易產(chǎn)生混亂。
在xlwings中
- Excel程序用App來表示,多個(gè)Excel程序集合用Apps表示;
- 單個(gè)工作簿用Book表示,工作簿集合用Books表示;
- 單個(gè)工作表用Sheet表示,工作表集合用Sheets表示;
- 區(qū)域用Range表示,既可以是一個(gè)單元格,也可以是一片單元格區(qū)域。
注意,在xlwings中是不區(qū)分大小寫的,SHEET1和sheet1的含義一樣。
我們這系列教程首先會(huì)按照「Apps - App - Books - Book - Sheets - Sheet - Range 」的順序來介紹xlwings的相關(guān)用法,然后介紹xlwings和其他Python庫的配合使用,最后再練習(xí)用xlwings來解決實(shí)際問題。
Apps
關(guān)于Apps這個(gè)概念,很多教程里提到過,但是都沒有解釋清楚。要理解Apps,首先要理解App,一個(gè)App對(duì)應(yīng)一個(gè)Excel實(shí)例,注意,是Excel實(shí)例,不是工作簿。我們要?jiǎng)?chuàng)建工作簿,首先要?jiǎng)?chuàng)建App。一個(gè)App可以創(chuàng)建多個(gè)工作簿。也就是說,我們可以通過xlwings創(chuàng)建多個(gè)App,每個(gè)App又可以創(chuàng)建多個(gè)工作薄,這些App是相互獨(dú)立的,只能管理它自己創(chuàng)建的工作簿。需要注意的是,當(dāng)我們手動(dòng)打開一個(gè)工作簿的時(shí)候,系統(tǒng)也會(huì)自動(dòng)幫我們創(chuàng)建一個(gè)App。
不慌,關(guān)于Apps的理解,通過后面的實(shí)例大家會(huì)認(rèn)識(shí)得更透徹。??
1. 引用xlwings庫
import xlwings as xw
2. 查看Apps包含的所有App
Apps = xw.apps
3. 返回App總數(shù)
count = xw.apps.count
4. 查看所有的PID:
keys = xw.apps.keys()
每個(gè)App對(duì)應(yīng)一個(gè)PID值,可以看作是數(shù)字編號(hào),用來識(shí)別不同的App
App
1. 創(chuàng)建App
app=xw.App()
這行代碼默認(rèn)打開Excel程序并且自動(dòng)創(chuàng)建一個(gè)工作薄
我們可以傳入?yún)?shù)對(duì)其進(jìn)行自定義設(shè)置:
app=xw.App(visible=True,add_book=False)
visible用來設(shè)置程序是否可見,True表示可見(默認(rèn)),F(xiàn)lase不可見。
add_book用來設(shè)置是否自動(dòng)創(chuàng)建工作簿,True表示自動(dòng)創(chuàng)建(默認(rèn)),F(xiàn)alse不創(chuàng)建
當(dāng)設(shè)置成add_book=False時(shí),可以創(chuàng)建App,但是還未生成PID,只有當(dāng)這個(gè)App創(chuàng)建了工作簿后,才會(huì)生成自己的PID
2. 查看PID
pid = app.pid
3. 引用App
app = xw.apps[1668]
[1668]就是這個(gè)App的PID
返回當(dāng)前活動(dòng)App
app = xw.apps.active
4. 激活A(yù)pp
app.activate()
'傳入?yún)?shù)'
app.activate(steal_focus=True)
當(dāng)steal_focus=True時(shí), Excel程序變?yōu)樽钋芭_(tái)的應(yīng)用,并且把焦點(diǎn)從Python切換到Excel
5. 退出App
app.kill():通過殺掉進(jìn)程強(qiáng)制Excel app退出
app.quit():退出excel程序,不保存任何工作簿
通常情況下,推薦用app.quit()
6. 重新計(jì)算一遍所有工作簿里的公式
app.calculate()
7. 設(shè)置屏幕更新
打開屏幕更新,我們可以看到xlwings對(duì)Excel進(jìn)行操作的過程,關(guān)閉更新可以加速腳本運(yùn)行。默認(rèn)是打開的。
'返回屏幕更新狀態(tài)'
app.screen_updating
'關(guān)閉屏幕更新'
app.screen_updating = False
腳本運(yùn)行完畢之后,記住把screen_updating屬性值改回 True
8. App是否可見設(shè)置
'返回App可見性'
app.visible
'設(shè)置App為可見'
app.visible = True
9. 設(shè)置提醒信息是否顯示
在使用Excel的過程中,經(jīng)常會(huì)遇到一些提醒信息,比如關(guān)閉前的保存提示、數(shù)據(jù)有效性的警告窗口,若想隱藏這些窗口,可進(jìn)行如下設(shè)置
app.display_alerts=False
如果提醒信息是需要反饋的,Excel會(huì)選擇默認(rèn)的方式
Books
1. App包含的所有的Book
'當(dāng)前活動(dòng)App的工作簿集合'
books = xw.books
'指定App的所有工作簿的集合'
books = app.books
Book
操作
1. 新建
wb = app.books.add()
'或者'
wb = xw.Book()
很多教程在提到新建App時(shí)都說這兩種方式是一樣的,實(shí)際上是有區(qū)別的,方式1是在當(dāng)前App下新建一個(gè)Book,方式2是創(chuàng)建一個(gè)新的App,并在新App中新建一個(gè)Book
2. 打開
打開代碼所在路徑下的文件
wb = app.books.open('test.xlsx')
'或者'
wb = xw.Book('test.xlsx')
打開絕對(duì)路徑下的文件
wb = app.books.open(r'C:\Users\zhoux\Desktop\test.xlsx')
'或者'
wb = xw.Book(r'C:\Users\zhoux\Desktop\test.xlsx')
為了避免路徑被轉(zhuǎn)義,在 Windows 上指定文件路徑時(shí),您應(yīng)該通過將 r 放在字符串前面來使用原始字符串,或者使用像這樣的雙反斜杠:
C:\\path\\to\\file.xlsx
參數(shù) 打開文件時(shí)除了傳入路徑,還有多種參數(shù)可設(shè)置
Book(fullname=None, update_links=None, read_only=None, format=None,
password=None, write_res_password=None, ignore_read_only_recommended=None,
origin=None, delimiter=None, editable=None, notify=None, converter=None,
add_to_mru=None, local=None, corrupt_load=None, impl=None)
關(guān)于參數(shù)的具體用法,請(qǐng)參考此處
3. 引用
wb = app.books('test.xlsx')
'或者'
wb = xw.Book('test.xlsx')
也可以用數(shù)字來代替文件名,比如wb = app.books(1)表示當(dāng)前app打開的第一個(gè)工作簿,可能有人也看到過使用中括號(hào)的引用方式,那么中括號(hào)和小括號(hào)有什么區(qū)別呢?
小括號(hào)的序號(hào)是從1開始的,中括號(hào)(切片)是從0開始計(jì)數(shù),也就是說,app.books(1) 等同于 app.books[0],后面在工作表和區(qū)域引用的時(shí)候會(huì)經(jīng)常遇到這種方式,大家不要混淆了。
大家可能發(fā)現(xiàn)了,xw.Book('test.xlsx')既可以打開工作薄也可以引用工作簿。也就是說,當(dāng)工作簿未打開時(shí),它可以打開工作薄,當(dāng)工作簿處于打開狀態(tài)時(shí),它可以引用工作簿。而app.books('test1.xlsx')只可以引用工作簿。
xw.Book 提供了連接到工作簿的最簡(jiǎn)單的方法: 它在所有的app實(shí)例中查找指定的工作簿,如果同一個(gè)工作簿在多個(gè)app實(shí)例中存在,就會(huì)返回一個(gè)錯(cuò)誤信息。
以上為官方的一段說明,我這里稍微解釋一下。我們前面講到了,每個(gè)App都可以打開屬于自己的工作簿,兩個(gè)不同的App可以打開同一個(gè)工作簿。當(dāng)我們使用App1和App2都打開了test.xlsx工作簿時(shí),使用app.books('test1.xlsx')的方式引用test1.xlsx當(dāng)然沒有問題,因?yàn)槊總€(gè)App都知道哪個(gè)test1是屬于自己的,但是當(dāng)我們使用xw.Book('test1.xlsx')的方式引用工作簿就會(huì)產(chǎn)生問題,因?yàn)檫@種方式會(huì)從App1和App2中找到兩個(gè)test1,然而它并不知道我們想要引用的是哪一個(gè),此時(shí)就會(huì)報(bào)錯(cuò)。
引用活動(dòng)工作薄
wb = app.books.active
4. 激活
wb.activate()
wb.activate(steal_focus=True)
如果steal_focus=True, 則把窗口顯示到最上層,并且把焦點(diǎn)從Python切換到Excel
5. 保存
wb.save()
默認(rèn)保存在工作薄所在的路徑
另存為
wb.save(r'D:\test.csv')
另存為時(shí),我們不僅能夠指定保存的位置,還可以指定保存的格式
同名文件會(huì)在沒有提示的情況下被直接覆蓋
6. 關(guān)閉
wb.close()
這種方式會(huì)直接關(guān)閉工作簿,不會(huì)進(jìn)行保存。 關(guān)閉所有的工作薄后,記得執(zhí)行一遍 app.quit() 清理一下Excel程序
屬性
1. 獲取工作簿的絕度路徑
wb.fullname
2. 獲取工作薄名稱(帶擴(kuò)展名)
wb.name
3. 獲取創(chuàng)建工作簿的App
wb.app
4. 返回工作薄中定義過的所有命名區(qū)域
wb.names
命名區(qū)域可在公式 - 名稱管理器中查看
5. 更改計(jì)算模式
wb.app.calculation = 'manual'
calculation的值表示了工作簿的計(jì)算模式,有: manual(手動(dòng)) , automatic(自動(dòng)) , semiautomatic(半自動(dòng))三種方式
Sheets
1. 工作簿包含的所有Sheet
'當(dāng)前活動(dòng)工作薄'
sheets = xw.sheets
'指定工作薄'
sheets = wb.sheets
包括隱藏工作表及深度隱藏工作表
Sheet
操作
1. 新建
sht = wb.sheets.add('test',after='sheet2')
參數(shù)1為工作表名稱,省略的話為Excel默認(rèn)名稱
參數(shù)2為插入位置,可選before或者after,示例中的代碼表示插入到sheet2之后,省略的話插入到當(dāng)前活動(dòng)工作表之前
工作表名稱重復(fù)的話會(huì)報(bào)錯(cuò)
2. 引用
sht = wb.sheets('sheet1')
'或者'
sht = wb.sheets(1)
當(dāng)前活動(dòng)工作表
sht = xw.sheets.active
3. 激活
sht.activate()
4.清除
'清除工作表所有內(nèi)容和格式'
sht.clear()
'清除工作表的所有內(nèi)容但是保留原有格式'
sht.clear_contents()
clear()不僅可以清除背景色等格式,還可以清除數(shù)據(jù)有效性和條件格式等
特別提醒:可以清除受保護(hù)的工作表的內(nèi)容
5.刪除
sht.delete()
可以刪除隱藏的工作表,但是不能刪除深度隱藏的工作表
6. 自動(dòng)調(diào)整行高列寬
sht.autofit('c')
- 要做行自適應(yīng),用 rows 或 r;
- 要做列自適應(yīng),用 columns 或 c;
- 同時(shí)做行和列的自適應(yīng),不需要參數(shù)。
7. 選定工作表
sht.select()
只能在活動(dòng)工作簿中選擇
屬性
1. 工作表名稱
'返回工作表名稱'
sht.name
'重命名工作表名稱'
sht.name = 'rename'
2. 返回指定工作表所屬的工作簿
sht.book
3. 工作表上所有單元格的區(qū)域?qū)ο?/h4>
sht.cells
sht.cells
包括所有的單元格,不僅僅是那些正在使用中的單元格
4. 返回工作表的索引值
sht.index
按照Excel的方式,從1開始的
5. 返回所有與本工作表有關(guān)的命名區(qū)域
sht.names
6. 工作表中用過的區(qū)域
sht.used_range
如果整張表為空,則返回A1單元格
關(guān)于used_range的范圍判定,我截取了網(wǎng)上的一段解釋:
UsedRange屬性返回工作表中所有已使用范圍的單元格區(qū)域,而不管該區(qū)域數(shù)據(jù)間是否有空行或空格。特別注意:UsedRange屬性返回工作表中所有已使用范圍的單元格區(qū)域是指:?jiǎn)卧裰杏袛?shù)值、公式、單元格格式化設(shè)置(例如:?jiǎn)卧褡煮w設(shè)置、邊框設(shè)置等等)
OK,第一篇文章到此為止,下一篇我們將繼續(xù)介紹Range及其他對(duì)象的使用。