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

Makzan
·
(修改过)
·
IPFS
·
歡迎來到第一個星期的 #編程星期三 ,今個星期我示範一下如何使用 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 授权

喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!

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

期望與放下

甚麼是世界職業技能競賽

【最後兩天】買《所謂「我不投資」,就是 all in 在法定貨幣》親身體驗擁有 NFT