本課程《win32com操作word API精講&專案實戰》,本公眾號以文字分享為主,B站與視訊號則釋出視訊分享,ID均為:一燈程式設計
本集開始,將會深入Document
介面。開啟或建立一個檔案都會產生一個Document
物件,它代表檔案本身,所以絕大部分檔案的操作都會依賴該介面,它的屬性和方法共計374
個!說不上很多,但它大部分的介面和屬性都是一個個獨立介面封裝而成的。
但不必擔憂,官方的檔案中顯示,有一部分介面是用於使用者端級程式設計的,我們只需要學習部分介面足以滿足各種型別的檔案級開發需求了。
這是本節課要講的介面,它是Document的方法,但其本身也是一個獨立的介面,方法和屬性共計183個。Range
這個介面簡直是word介面中的勞模。它表示資源選中或插入點,可以理解為一個看不見的滑鼠,但它比滑鼠的作用強大多了。官方也提供了Selection
介面,這是正兒八經的滑鼠,它能和滑鼠互動,個人認為Selection
適合用在使用者端級開發
的場景,檔案級開發
的場景還是Range
好用。
操作檔案中的資源,如選中一段文字,在實操中,得先滑鼠選中文字。在word程式設計中,使用Range
就能實現資源的選中,Selection
是單例模式
,Range
可不是,最近的一個Range
範例不會覆蓋前面的範例,每個範例都是獨立存在的。
from win32com.client import Dispatch
client = Dispatch('word.Application')
client.Visible = 1
# 建立一個檔案 返回一個Document物件 操作檔案就必須要操作Document
doc = client.Documents.Add()
此時,使用者端上已經建立了一個新檔案,為了方便演示,先在檔案中貼上一段新聞:
總部大樓內唯一對外開放的部分,是著名的火器博物館。它共有15個展室,收藏著3000件曾經叱吒美國各個歷史時期的著名槍械和部分外國名槍。其中,「前總統收藏專區」更是顯示出這一協會與美國政界的緊密聯絡。在美國曆史上,有九位總統曾是該協會的會員,分別是:格蘭特、西奧多·羅斯福、塔夫脫、艾森豪威爾、肯尼迪、尼克松、里根、老布什。還有一位,就是上任總統特朗普。要讓這麼多總統站臺,背後往來的金錢可不是小數目。資料顯示,美國全國步槍協會在2016年總統選舉中捐出的競選資金高達5440萬美元,其中,他們為特朗普砸下了3000萬美元。
rng1 = doc.Range()
沒什麼可講的,真的太簡單了,如果你剛接觸Python不久且無其他程式語言基礎,只需要記住,Range
介面返回一個Range
物件,表示當前被選中的內容,僅此。
用法 Range(Start: int, End: int) -> Range
Start
和End
表示字元,表示選擇了從Start
開始,截至End
的範圍。
rng2 = doc.Range(0,10)
rng3 = doc.Range(20,20)
當起始位置和結束位置一樣時,Range
中就無內容了,它是一個點,這種插入點通常用來往插入點寫入內容。這樣做很方便,不必擔心因為誤操作而導致範圍中的內容被替換。
Text
屬性內部有__setter__
,可以使用該屬性來獲取或設定範圍中的內容。列印Range
範例時,會返回一個<COMObject Range>
,看不到範例細節,此時可以使用Text
屬性檢視範圍中的文字。
使用Text屬性獲取範圍中的內容
rng2 = doc.Range(0,4)
print(rng2.Text)
>>>
'總部大樓'
兩個屬性分別可以獲取或設定範圍的起始位置和結束位置,在實操中,有時候Range
的範圍並不是通過Range(Start, End)
這種方式來宣告的,而是某種方式,比如使用Document.Paragraphs(1)
獲得文章第一段,而某些操作只能在Range
物件下才能操作,那麼可以使用,Document.Paragraphs(1).Range
將第一段的段落物件
轉換成了Range
物件,此時就可以通過Range.End
來獲得範圍的結束位置啦。
當然,這兩個屬性也是實現了__setter__
方法的,意味著可以通過為屬性賦值來改變Range
的範圍。
在word程式設計中,更改Range
範圍是常規操作,上面的Start
和End
屬性可以實現,但複雜的需求和程式設計環境是不允許我們來數數有幾個字元
的,這不現實。所以,微軟官方提供了非常豐富的介面來實現Range
範圍的更改,比如,下面要講的MoveStart
和MoveEnd
方法。
1、MoveStart(Unit=1, Count=1)
該方法可以改變範圍的起始位置,可以擴大範圍也可以減少範圍,引數說明:
1
表示字元,3
表示句子,4
表示段落,2、MoveEnd(Unit=1, Count=1)
引數和MoveStart
一模一樣。
演示
rng3 = doc.Range(0,4)
rng3.MoveStart(Unit=4, Count=1)
print(rng3.Start, rng2.End)
# 移動後列印起始位置和結束位置
>>>
(262, 262)
明明只移動了起始位置,但為何結束位置從原來的4也變成了262字元位置了呢?請看下方說明:
說明
無論是MoveStart還是MoveEnd,如果一方的位置超越了另一方,兩個點就會重疊並形成插入點,最後一起移動到目標位置,不可能會出現結束位置小於起始位置這種匪夷所思的情況。
這種玩法就很妙,意味著,我們不需要在意到底要數到第幾個字元
就可以輕鬆獲得一個Range
的範圍。
前面所示,可以使用Range.Text屬性重新賦值,這很簡單,就演示個虛擬碼吧。
# 虛擬碼
# 在0,0的位置宣告一個插入點
rng1 = doc.Range(0,0)
# 使用Text屬性插入內容
rng1.Text = '一燈程式設計'
注意:
除非你想替換範圍中的內容,否則不要輕易使用有內容的範圍來執行doc.Range(0,10).Text = '插入的內容'
語句。
InsertBefore:在範圍的起始位置插入內容
InsertAfter:在範圍的結束位置插入內容
這兩個方法是為有內容的範圍
量身訂造的,我想,千言萬語不如一張圖來得直接(懶)。
注意:兩個方法會擴大原來的範圍
另起一段是word編輯中常用的功能,使用回車即可實現,在word程式設計中,有三個方法可以實現的。
使用段落標記\r
替換原來範圍中的內容,並形成新段落。
rng4 = doc.Range(20,20)
rng4.InsertParagraph()
該方法適用於插入點,因為它會使用自動執行以下程式碼:
rng4.Text = '\r'
意味著,\r
會替換原來範圍中的內容,除非有這個必要。執行這個方法後,從字元21
開始,後面的內容都會另起一段。
在範圍起始位置插入一個段落標記\r
,意思是在原來內容的基礎上,在起始位置插入一個\r
,那麼當前範圍會形成一個新段落,假如原來的內容為一燈程式設計
,執行該方法後,內容為\r一燈程式設計
。
rng5 = doc.Range(4,8)
rng5.InsertParagraphBefore()
print(rng5.Text)
>>>
"\r一燈程式設計"
和InsertParagraphBefore相反,它會在結束位置插入\r
,作用完全一樣,不作演示。
Document
需要講的內容很多,僅Range
介面就能講很多集。學習不能急,但也不能懶,程式碼敲起來,沒有學不會的內容。
好啦,我們下節課接著講Range
。