用 Python 操作 Word 文檔

圖片來源于網(wǎng)絡(luò)
作者:贠云龍
Blog: zhihu.com/people/yunlongyun
本文主要講解python中操作word的思路。
一、Hello,world!
使用win32com需要安裝pypiwin32
pip install pypiwin32
推薦使用python的IDLE,交互方便
1、如何新建文檔
from win32com.client import Dispatch
app = Dispatch('Word.Application')
# 新建word文檔
doc = app.Documents.Add()
按F5運行,發(fā)現(xiàn)什么效果都沒有, 這是因為Word被隱藏了。
2、如何顯示W(wǎng)ord
app.Visible = 1
運行后,熟悉的Word界面出現(xiàn)?,F(xiàn)在來輸入文字。

3、如何輸入
我們在Word中輸入文字時,一般會先使用鼠標(biāo)點擊需要輸入文字的位置,這個過程是獲得了光標(biāo)焦點。
當(dāng)我們需要替換某些文字時,首先會選中某些文字,然后再輸入、被選擇的文字呈現(xiàn)出灰色的背景,表示被選中了。
光標(biāo)焦點和選擇范圍在Word中,都是Selection。什么都沒選擇的光標(biāo)焦點,和選擇了整片文章的選擇范圍,代表了Selection的最小和最大范圍。
這也是為什么整個Word中只能有一個Selection的原因。因為光標(biāo)或者選擇范圍就只能有一個。
# 運行下句代碼后,s獲得新建文檔的光標(biāo)焦點,也就是圖中的回車符前
s = app.Selection
# 用“Hello, World!“替換s代表的范圍的文本
s.Text = 'Hello, world!'
此時,s的范圍為'Hello, world!'這句話的選擇區(qū)域。

能如此方便的調(diào)用Word,得益于其底層的COM(組件對象模型)可以被任意語言調(diào)用。
Selection是Word對象模型中的類,此處的s是它的對象(實例)。
4、如何查看選擇區(qū)域是什么
s.Text可以查看或者設(shè)置s選擇區(qū)域的文本。Word對象模型中很多對象都有默認(rèn)屬性,Text就是Selection的默認(rèn)屬性,類似python的__str__方法。運行s()調(diào)用s的默認(rèn)屬性,此處等于于運行了s.Text。
s()
控制臺顯示,s的范圍為'Hello, world!'這句話的選擇區(qū)域。

二、對Word對象模型的簡單理解
Word中最重要的類(對象)有以下幾個。
1、Application對象:Word應(yīng)用。Application包含了菜單欄、工具欄、命令以及所有文檔等。
# 如何獲得
app = win32com.client.Dispatch('Word.Application')
2、Document對象:文檔??梢杂卸鄠€Document,就像Word可以打開多個文檔。
使用下列代碼新建文檔或者打開文檔
# 如何獲得
# 新建文檔
doc = app.Documents.Add()
# 打開已有文檔
doc = app.Documents.Open('你的Word文件路徑')
3、Selection對象:選區(qū):代表當(dāng)前窗口的選區(qū)。它可以是文檔中的選擇(高亮)區(qū)域,也可以是插入點(如果沒有什么被選中)。同一時間只能激活一個Selection。
如何獲得
s = app.Selection
在Word中,按下Alt+F11打開宏編輯器

然后按下F2打開對象瀏覽器

輸入selection并回車,發(fā)現(xiàn)成員一列中完全匹配Selection的只有4個類,這表示只有這些類的Selection屬性可以返回Selection對象(如圖)。

Application我們前面介紹過,其它的類可以用同樣的方法查詢?nèi)绾潍@得。
如何使用Selection輸入
# 替換當(dāng)前選擇
s.Text = 'Hello, world!'
# 輸入
s.TypeText('Hello, world!')
# 把當(dāng)前選擇復(fù)制到剪貼板
s.Copy()
# 粘貼剪貼板中的內(nèi)容
s.Paste()
Text和TypeText的不同在于完成后的選區(qū):
Text:輸入的文本(前例中選區(qū)為'Hello, world!');
TypeText:文本后的插入點(前例中選區(qū)為!后的插入點)。
如何變更Selection
# 使用Start,End指定字符范圍
s.Start = 0
s.End = n
# s從第0個字符(第1個字符前的插入點)到第n個字符。
# 漢字是每字為1字符
# 相當(dāng)于按下Delete鍵
s.Delete()
# 相當(dāng)于按下Ctrl+A
s.WholeStory()
# 向左移動
s.MoveLeft()
# 向右移動2個字符,第1個參數(shù)是移動單位WdUnits,見下圖
s.MoveRight(1, 2)


所有能獲得Selection的類
4、Range對象:連續(xù)區(qū)域。Range表示一個連續(xù)區(qū)域。Range由Start和End位置定義,用來區(qū)分文檔的不同部分。Range是獨立于Selection的。不管Selection是否改變,都可以定義和操作Range。文檔中可以定義多個Range。這個連續(xù)區(qū)域同樣可以小到一個插入點,大到整個文檔。Selection有Range屬性,而Range沒有Selection屬性。
當(dāng)使用Range(Start, End)方法來指定文檔的特定范圍時。文檔的第一個字符位置為0,最后一個字符的位置和文檔的字符總數(shù)相等。不提供參數(shù)時代表選擇所有范圍。
如何獲得
r = doc.Range()
# 或
r = s.Range()
Word中有很多對象的Range屬性都能返回Range對象,請在Word-宏編輯器-對象瀏覽器中自己查詢。
如何使用
因為本文僅使用Selection就可以達到效果,Range的很多屬性和方法和Selection是類似的。
5、Font對象:字體。包含對象的字體屬性(字體名稱、字號、顏色等)。
如何獲得
font = s.Font
# 或
font = r.Font
同樣,其余獲得方法可在Word-宏編輯器-對象瀏覽器中查詢。
如何使用
# 字體設(shè)置為仿宋,電腦上必須安裝有該字體
font.Name = '仿宋'
# 字號設(shè)置為三號
font.Size = 16
ParagraphFormat對象:段落格式。用來設(shè)置段落格式,包括對齊、縮進、行距、邊框底紋等。
如何獲得
pf = s.ParagraphFormat
# 或
pf = r.ParagraphFormat
同樣,其余獲得方法可在Word-宏編輯器-對象瀏覽器中查詢。
如何使用
# 左、中、右 對齊分別為0, 1, 2,其他對齊方式見.NET 文檔中的ParagraphFormat
pf.Alignment = 0
# 單倍、1.5倍、雙倍行距分別為0, 1, 2,其他見ParagraphFormat文檔
pf.LineSpacingRule = 0
# 指定段落的左縮進值為21磅。
pf.LeftIndent = 21
7、PageSetup對象:頁面設(shè)置。代表所有的頁面設(shè)置屬性,包括左邊距,底邊距,紙張大小等等。
如何獲得
ps = doc.PageSetup
# 或
ps = s.PageSetup
# 或
ps = r.PageSetup
同樣,其余獲得方法可在Word-宏編輯器-對象瀏覽器中查詢。
如何使用
# 上邊距79磅
ps.TopMargin = 79
# 頁面大小,A3、A4分別為6,7
ps.PageSize = 7
8、Styles對象:樣式集。Styles包含指定文檔中內(nèi)置和用戶定義的所有樣式,它返回一個樣式集。其中的每個樣式的屬性包括字體、 字形、 段落間距等。如常見的正文、頁眉、標(biāo)題1樣式。
如何獲得
# 只能通過文檔獲得
styles = doc.Styles
如何使用
# 返回正文樣式
normal = styles(-1)
# 修改正文樣式的字體字號
normal.Font.Name = '仿宋'
normal.Font.Size = 16
Styles的返回參數(shù),標(biāo)題1、標(biāo)題2、標(biāo)題3分別為-2、-3、-4,頁眉為-32,標(biāo)題為-63,其他見Styles文檔
三、解決問題思路
因為有很多功能,在文檔中難以直接找到,需要使用如下方法。
1、把想實現(xiàn)的功能,使用word的錄制宏,在宏編輯器里查看VBA代碼,從而了解大概使用什么方法。
2、使用在線的 .NET API,從而了解詳細(xì)的語法
3、如果不知道從哪獲得實現(xiàn)該功能的對象,則可以使用word宏編輯器的對象瀏覽器(F2鍵),具體見前文Selection部分
4、使用Python的IDLE進行實時交互
app = win32com.client.Dispatch('word.application')
app.Visible='True'
# 讓word程序可見,這樣在交互命令行做的修改就可以實時顯示
doc = app.Documents.Open('你的桌面路徑/test.docx')
# word文件放在桌面方便手動修改
然后輸入自己想嘗試的對象屬性或方法。
四、實例:格式化word文件為最新的公文國家標(biāo)準(zhǔn)
只進行兩個部分的設(shè)置,一是頁面設(shè)置、二是頁碼設(shè)置
from win32com.client import Dispatch #需要安裝的是pypiwin32模塊
app=Dispatch('Word.Application')
doc = app.Documents.Open('你的word文檔路徑')
# 頁面設(shè)置
cm_to_points = 28.35 # 1厘米為28.35磅
# 國家公文格式標(biāo)準(zhǔn)要求是上邊距版心3.7cm
# 但是如果簡單的把上邊距設(shè)置為3.7cm
# 則因為文本的第一行本身有行距
# 會導(dǎo)致實際版心離上邊緣較遠,上下邊距設(shè)置為3.3cm
# 是經(jīng)過實驗的,可以看看公文標(biāo)準(zhǔn)的圖示
# 版心指的是文字與邊緣距離
doc.PageSetup.TopMargin = 3.3*cm_to_points
# 上邊距3.3厘米
doc.PageSetup.BottomMargin = 3.3*cm_to_points
# 下邊距3.3厘米
doc.PageSetup.LeftMargin = 2.8*cm_to_points
# 左邊距2.8厘米
doc.PageSetup.RightMargin = 2.6*cm_to_points
# 右邊距2.6厘米
# 設(shè)置正常樣式的字體
# 是為了后面指定行和字符網(wǎng)格時
# 按照這個字體標(biāo)準(zhǔn)進行
doc.Styles(-1).Font.Name = '仿宋'
# word中的“正常”樣式字體為仿宋
doc.Styles(-1).Font.NameFarEast = '仿宋'
# word中的“正?!睒邮阶煮w為仿宋
doc.Styles(-1).Font.NameAscii = '仿宋'
# word中的“正常”樣式字體為仿宋
doc.Styles(-1).Font.NameOther = '仿宋'
# word中的“正?!睒邮阶煮w為仿宋
doc.Styles(-1).Font.Size = 16
# word中的“正?!睒邮阶痔枮槿?/span>
doc.PageSetup.LayoutMode = 1
# 指定行和字符網(wǎng)格
doc.PageSetup.CharsLine = 28
# 每行28個字
doc.PageSetup.LinesPage = 22
# 每頁22行,會自動設(shè)置行間距
# 頁碼設(shè)置
doc.PageSetup.FooterDistance = 2.8*cm_to_points
# 頁碼距下邊緣2.8厘米
doc.PageSetup.OddAndEvenPagesHeaderFooter = 0
# 首頁頁碼相同
doc.PageSetup.OddAndEvenPagesHeaderFooter = 0
# 頁腳奇偶頁相同
w = doc.windows(1)
# 獲得文檔的第一個窗口
w.view.seekview = 4
# 獲得頁眉頁腳視圖
s = w.selection
# 獲取窗口的選擇對象
s.headerfooter.pagenumbers.startingnumber = startingnumber
# 設(shè)置起始頁碼
s.headerfooter.pagenumbers.NumberStyle = 0
# 設(shè)置頁碼樣式為單純的阿拉伯?dāng)?shù)字
s.WholeStory()
# 擴選到整個部分(會選中整個頁眉頁腳)
s.Delete()
#按下刪除鍵,這兩句是為了清除原來的頁碼
s.headerfooter.pagenumbers.Add(4)
# 添加頁面外側(cè)頁碼
s.MoveLeft(1, 2)
# 移動到頁碼左邊,移動了兩個字符距離
s.TypeText('— ')
# 給頁碼左邊加上一字線,注意不是減號
s.MoveRight()
#移動到頁碼末尾,移動了一個字符距離
# 默認(rèn)參數(shù)是1(字符)
s.TypeText(' —')
s.WholeStory()
# 擴選到整個頁眉頁腳部分,此處是必要的
# 否則s只是在輸入一字線后的一個光標(biāo),沒有選擇區(qū)域
s.Font.Name = '宋體'
s.Font.Size = 14
#頁碼字號為四號
s.paragraphformat.rightindent = 21
#頁碼向左縮進1字符(21磅)
s.paragraphformat.leftindent = 21
# 頁碼向右縮進1字符(21磅)
doc.Styles('頁眉').ParagraphFormat.Borders(-3).LineStyle = 0
# 頁眉無底邊框橫線
參考文章:
Python通過win32實現(xiàn)office自動化
https://blog.csdn.net/lzl001/article/details/8435048
引用Microsoft Word 對象的技術(shù)及實現(xiàn)
https://www.docin.com/p-1333941826.html
Word組件對象模型
https://blog.csdn.net/wishfly/article/details/39959349- EOF -
回復(fù)關(guān)鍵字“簡明python ”,立即獲取入門必備書籍《簡明python教程》電子版
回復(fù)關(guān)鍵字“爬蟲”,立即獲取爬蟲學(xué)習(xí)資料

點擊關(guān)注【python入門與進階】,閱讀更多精彩內(nèi)容 ??????
推薦
- EOF -
回復(fù)關(guān)鍵字“簡明python ”,立即獲取入門必備書籍《簡明python教程》電子版
回復(fù)關(guān)鍵字“爬蟲”,立即獲取爬蟲學(xué)習(xí)資料

推薦
