Makzan

我管理世界職業技能競賽之網站技術項目、舉辦本地設計與開發賽事、開課分享技術心得。一個用網頁來表達自己的作家。

使用 Python 列出 DOCX 文檔中所有粗體字

發布於
歡迎來到第一個星期的 #編程星期三 ,今個星期我示範一下如何使用 Python 讀取一個 DOCX 文件內的所有粗體字。

歡迎來到第一個星期的 #編程星期三 ,今個星期我示範一下如何使用 Python 讀取一個 DOCX 文件內的所有粗體字。

首先,若果未安裝 python-docx,可以通過 pip install python-docx 安裝處理 docx 的工具。

安裝後,我們可以通過 import docx 來匯入使用。

打開文件

使用 doc = Document("Sample Document.docx") 可以打開現有的一個檔案。例如,我準備了一個包括不同粗體字的 Word DOCX 檔案。

範例 Word DOCX 文檔

列出所有段落(包括標題)

打開檔案後,首先通常是列出一些內容來確認我們成功打開了正確的檔案。例如先列出所有段落。

for p in doc.paragraphs:
    print(p)

運行結果是一堆段落的物件:

列出所有段落物件

對於每個段落,我們可以做甚麼?

首先,我通常會先看一看段落的文字。

for p in doc.paragraphs:
    print(p.text)
列出所有段落文字

在每個段落中找出不同樣式段

下一步,我們需要在每個段落中,找出粗體字的部份,在每個段落中,不同的樣式會以不同的 run 來儲存。所以如果整段文字都是一種樣式或預設樣式,則那段文字只會有一個 run,但如果當中有不同樣式混合的,例如當中有粗體字等。所以通過對段落中的所有 runs 進行檢查,就可以找出 run.bold == True 的那些為粗體字。

for p in doc.paragraphs:
     for run in p.runs:
        print(run.bold, run.text)
找出粗體的文字部份

放到一起

將我們所嘗握的放到一起,就能得出以下代碼及運行結果。

import docx
print("Printing all bold text from Sample Document.docx:")

doc = docx.Document("Sample Document.docx")

for p in doc.paragraphs:    
    for run in p.runs:
        if run.bold:
            print(run.text)
只列出精體文字

這個例子只列出一個特定的檔案,如果配合 glob,我們可以將上述代碼擴展至支援現有資料夾內的所有 DOCX 文件。

import docx
import glob

files = glob.glob("*.docx")

for file in files:
    print(f"Printing all bold text from {file}:")

    doc = docx.Document(file)

    for p in doc.paragraphs:    
        for run in p.runs:
            if run.bold:
                print(run.text)

列出所有表格(Table)

剛剛的例子還有個粗體其實是遺漏了的。就是表格中所包含的粗體字。這些表格是不包括在 paragraphs 物件列表的,所以我們需要進一步從表格中取得這些文字樣式。而表格中的欄與列分別以 cols 和 rows 來存取,當中每一格都會有各自的 paragraphs 列表。

所以,針對這些表格,我們可以擴展代碼並加入表格的循環:

import docx
import glob

files = glob.glob("*.docx")

for file in files:
    print(f"Printing all bold text from {file}:")

    doc = docx.Document(file)

    for p in doc.paragraphs:    
        for run in p.runs:
            if run.bold:
                print(run.text)

    
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                for p in cell.paragraphs:
                    for run in p.runs:
                        if run.bold:
                            print(run.text)
            
        

但上述這段代碼入太多層了,對將來維護會有難度。這樣寫的原因是因為文件中的表格內的每格儲存格(Cell)都有其自己的段落列表。

其中一個優化方案,可以將從段落尋找粗體字的部份抽取出來造成函數。

def print_bold_text_in_paragraphs(paragraphs):
    for p in paragraphs:    
        for run in p.runs:
            if run.bold:
                print(run.text)

然後我們便只需要在每格調用函數

import docx
import glob

files = glob.glob("*.docx")

for file in files:
    print(f"Printing all bold text from {file}:")

    doc = docx.Document(file)

    print_bold_text_in_paragraphs(doc.paragraphs)

    # Iterate all cells in all tables
    for table in doc.tables:        
        for row in table.rows:
            for cell in row.cells:
                print_bold_text_in_paragraphs(cell.paragraphs)
最終效果

以下是最終的完整代碼:

https://gist.github.com/makzan/4fb414934f2ddb8c17e81a3c5737ac35

及可以線上執行試運行的版本。

https://replit.com/@makzan/example-reading-bold-text-from-docx


— 麥誠 Makzan,2021-11-17。


我是麥誠軒(Makzan),除了正職外,平常我要麼辦本地賽與辦世界賽,要麼任教編程與網站開發的在職培訓。現正轉型將面授培訓內容寫成電子書、網上教材等,至今撰寫了 7 本書, 2 個視頻教學課程。

我逢星期三會不定期推出 #編程星期三,介紹 Python 或不同的編程技巧,包括自動化辦公文件處理、及網絡爬蟲等。

如果我的文章有價值,請訂閱贊助我持續創作分享。

訂閱贊助:https://liker.land/thomasmak/civic


喜歡我的文章嗎?
別忘了給點支持與讚賞,讓我知道創作的路上有你陪伴。

CC BY-NC-ND 2.0 版權聲明

教學文系列

1

看不過癮?

一鍵登入,即可加入全球最優質中文創作社區