文檔結構與樣式初步—— 使用Python讀寫Office文檔之二

本文介紹利用Python創建有結構的Word文檔

=========================================================================================================================================================================================================

Word的一個特點,或者說,一個非常不像話的地方是,將文檔結構(Document Structure)和樣式 (Styling)混為一談。這樣一來,本文就不能像介紹LaTeX一樣單純的介紹文檔結構,而必須加一個『樣式初步』。關於樣式的更深入介紹,將放在後面的文章里進行。

Word文檔的主要結構單位是『段落』(Paragraph)。標題也好,目錄也好,正文也好,都是段落。通過賦予段落不同的樣式,形成不同功能的文檔結構。這種做法一直可以追溯到Word 6.0時代,猜測是當時為了節省緊俏的存儲資源而設定的。

比段落更小的單位是『遊程』(Run)。比方說,你想在一個段落里加重某幾個字,那麼加重的字就形成一個遊程。一個段落至少包含一個遊程。

1. 創建結構文檔

前面已經提到了,創建結構文檔,就是創建具有不同樣式的段落

在上篇文章中已經介紹了Document類型的add_paragraph函數。add_paragraph 方法的第一個參數是段落的文字,第二個可選參數就是段落的樣式。通過這個樣式參數即可設置所添加段落的樣式。如果不指定這個參數,則默認樣式為『正文』

add_paragraph的返回值是一個段落對象,可以通過這個對象的style屬性得到該段落的樣式,也可以寫這個屬性以設置該段落的樣式。

例如

# -*- coding: utf-8 -*-nfrom docx import Documentnndoc = Document()ndoc.add_paragraph(u對中國能源問題的思考,Title)ndoc.add_paragraph(u作者,Subtitle)ndoc.add_paragraph(u摘要:本文闡明了能源問題的重要性...,Body Text 2)ndoc.add_paragraph(u能源問題的重要性,Heading 1)ndoc.add_paragraph(u人類的能源利用經歷了從薪柴時代到煤炭時代...)ndoc.add_paragraph(u能源是現代經濟社會發展的基礎,Heading 2)ndoc.add_paragraph(u現代經濟社會發展建立在高水平物質文明)np = doc.add_paragraph(u能源是經濟社會發展的重要制約因素)np.style = Heading 2ndoc.save(demo.docx)n

注意,這段代碼中使用了中文字元,需要設置utf-8聲明、Unicode聲明以及將代碼保存為無DOM的utf-8格式。詳見Python 中文處理系列之源代碼與文件IO。

代碼中的Title、Heading x之類,都是Word的內建樣式。啟動Word,在『樣式』窗格看到的樣式圖標即是Word的內建樣式。

對於英文版的Word,在樣式圖標下標註的樣式名稱,就是在Python代碼可以使用的樣式名稱,然而對於中文版Word,內建樣式仍然使用英文名稱。所以你若沒有安裝英文版的Word,可以用下面的代碼得到英文的樣式名稱:

from docx import Documentnfrom docx.enum.style import WD_STYLE_TYPEndoc = Document()nstyles = doc.stylesnprint "n".join([s.name for s in styles if s.type == WD_STYLE_TYPE.PARAGRAPH])n

至於樣式名稱對應了什麼樣式,可顧名思義。對於文檔結構而言,常用的樣式有

  • Title:文檔的標題,樣式窗格里顯示『標題』
  • Subtitle:副標題
  • Heading n:n級標題,樣式窗格里顯示『標題 n』
  • Normal:正文

等等。

對於文檔標題以及n級標題, 可以使用Document對象的『便捷函數』add_heading。這個函數的第一個參數是文本內容,第二個參數若設為0,則等價於add_paragraph(text,Title);若設為大於0的整數n,則等價於add_paragraph(text,Heading %d % n)

2 讀取Word文檔

讀取一篇文檔也非常簡單。下面一份代碼將打開命令行參數指定的文檔,按順序輸出每一段的長度和樣式名稱:

from docx import Documentnimport sysndocument = Document(sys.argv[1])nfor p in document.paragraphs:n print len(p.text)n print p.style.namen

對於中文文本,len得到的是漢字個數,這個和Python默認的多語言處理方法是一致的。

各位讀者可以拿手裡的現成Word文檔試試(需要docx格式),如果文檔是使用Word默認的樣式創建的,則會輸出Title、Normal、Heading x之類的樣式名稱。如果文檔對默認樣式進行了修改,那麼依然會輸出原有樣式名稱,不受影響。如果文檔創建了新樣式,則使用新樣式的段落會顯示新樣式的名稱。

對於段落中的遊程,可以利用Paragraph對象的runs屬性獲得。例如

from docx import Documentnimport sysndocument = Document(sys.argv[1])nfor p in document.paragraphs:n print ====n for r in p.runs:n print len(r.text)n

我們日常工作中遇到的Word文檔可能千奇百怪,不排除胡亂使用樣式導致文檔結構面目全非的情況。 但大體上paragraphs-run的兩級結構是不會變的。


推薦閱讀:

TAG:Python | MicrosoftOffice |