Docx 技能
使用 python-docx 透過小型 CLI 建立、讀取、編輯和套用範本至 Microsoft Word .docx 檔案。它能處理文字、樣式、清單、表格、圖片、頁首/頁尾、{{token}} 範本、追蹤修訂(列出/接受/拒絕)、註解(列出/新增/刪除)、目錄和頁碼欄位,以及套件健康檢查。它本身不會渲染文件(PDF 需要 LibreOffice — 請參閱「轉換為 PDF」),也無法編輯舊版 .doc。
使用時機
- 使用者要求產生 Word 文件(報告、信件、合約)。
- 您需要
.docx的文字、大綱、樣式或嵌入圖片。 - 您必須修改現有的
.docx:取代文字、編輯表格儲存格、插入/刪除段落、套用樣式、合併分散的執行緒。 - 您有一個包含
{{placeholders}}的.docx範本,需填入資料。 - 文件有需要檢閱、接受或拒絕的追蹤修訂。
- 您需要讀取審閱者的註解,或新增/刪除註解。
- 某個
.docx無法開啟或行為異常,您需要進行損毀排查。 - 文件需要目錄或「第 X 頁,共 Y 頁」的頁尾。
- 不適用於:
.doc(舊版)、.odt或所見即所得的版面配置工作。
先決條件
- 已安裝 Python 3.10+ 和
python-docx:pip install python-docx(匯入名稱為docx;lxml 會一併安裝)。 - 註解
add在 python-docx >= 1.2 使用原生 API,在較舊版本使用 XML 回退 — 兩者皆自動處理。 - 對於圖片區塊:圖片檔案必須存在於本機(PNG/JPEG)。
如何執行
所有輔助工具都位於此檔案旁的 scripts/ 目錄。使用 terminal 工具執行;每個工具都支援 --help 並將 JSON 輸出到標準輸出。
python scripts/docx_create.py spec.json out.docx
python scripts/docx_read.py out.docx --text
python scripts/docx_edit.py replace out.docx --find old --replace new
python scripts/docx_template.py tpl.docx values.json filled.docx
python scripts/docx_revisions.py list out.docx
python scripts/docx_comments.py list out.docx
python scripts/docx_validate.py out.docx
快速參考
| 任務 | 指令 |
|---|---|
| 從 JSON 規格建立 | docx_create.py spec.json out.docx |
| 完整文字(本文+表格+頁首/頁尾) | docx_read.py f.docx --text |
| 標題大綱 + 表格形狀 | docx_read.py f.docx --structure |
| 實際使用的樣式 | docx_read.py f.docx --styles |
| 提取嵌入圖片 | docx_read.py f.docx --images outdir/ |
| 偵測追蹤修訂/註解 | docx_read.py f.docx --revisions |
| 尋找/取代(保留格式) | docx_edit.py replace f.docx --find A --replace B -o out.docx |
| 設定表格儲存格 | docx_edit.py set-cell f.docx --table 0 --row 1 --col 2 --text X |
| 在索引 N 前插入段落 | docx_edit.py insert f.docx --index N --text X --style Normal |
| 刪除段落 N | docx_edit.py delete f.docx --index N |
| 對段落 N 套用樣式 | docx_edit.py style f.docx --index N --style "Heading 1" |
| 合併格式相鄰的執行緒 | docx_edit.py normalize f.docx -o out.docx |
| 在段落 N 前插入 TOC 欄位 | docx_edit.py toc f.docx --index N -o out.docx |
| 「第 X 頁,共 Y 頁」頁尾欄位 | docx_edit.py page-numbers f.docx |
填入 {{tokens}} | docx_template.py tpl.docx values.json out.docx --strict |
| 列出修訂(id/作者/日期/文字) | docx_revisions.py list f.docx |
| 接受 / 拒絕所有修訂 | docx_revisions.py accept-all f.docx -o out.docx(或 reject-all) |
| 接受 / 拒絕單一修訂 | docx_revisions.py accept f.docx --id 3 -o out.docx |
| 列出註解(+錨點文字) | docx_comments.py list f.docx |
| 新增錨點於文字的註解 | docx_comments.py add f.docx --target "phrase" --text "note" --author You |
| 依 ID 刪除註解 | docx_comments.py delete f.docx --id 0 |
| 套件健康檢查 | docx_validate.py f.docx(出錯時回傳 1) |
程序
- 建立。 使用
write_file編寫 JSON 規格,然後執行scripts/docx_create.py。規格支援:page(尺寸 + 邊距,單位 mm)、header/footer字串、footer_page_numbers(加入「第 X 頁,共 Y 頁」欄位頁尾)、styles(自訂段落樣式,含字型、大小、粗體/斜體、十六進位color)以及blocks—heading(層級 1-9)、paragraph(可為text或runs清單,每個 run 可設定bold/italic/underline)、bullet_list、numbered_list、table(header列以粗體呈現,rows,可選的內建表格style,如Table Grid)、image(path,可選的width_mm)、toc(目錄欄位)以及page_break。完整的規格格式記錄在scripts/docx_create.py的頂端。 - 讀取。 使用
scripts/docx_read.py並搭配恰好一個模式旗標。--text以 JSON 回傳主體段落、所有表格儲存格文字以及頁首/頁尾文字。--structure回傳標題大綱以及段落/表格/區段計數。--images DIR將word/media/下的每個檔案複製到套件外。 - 編輯。 使用
scripts/docx_edit.py。replace會遍歷主體、表格(含巢狀表格)、頁首和頁尾,並保留執行緒格式;加上--body-only可略過頁首/頁尾。傳入-o out.docx可保留原始檔案;省略則直接原地編輯。insert/delete/style/toc的段落索引參照--structure/--text的主體順序。先對來自大量 Word 編輯的文件執行normalize— 它會合併格式相同的相鄰執行緒,以便後續的尋找/取代能可靠匹配。 - 檢閱修訂。
docx_revisions.py list會報告主體、表格、頁首或頁尾中任何位置的每個w:ins和w:del(包含 ID、作者、日期、受影響文字)。accept-all/reject-all可大量處理;accept/reject --id N則處理單一修訂。接受會保留插入內容並刪除刪除文字;拒絕則相反。 - 註解。
docx_comments.py list會回傳每個註解的 ID、作者、日期、內文,以及其錨點所在的文件文字。add --target "some phrase"會將新註解錨定到該片語的第一次出現處(執行緒會視需要分割;格式會保留)。delete --id N會移除註解及其標記,但不會碰觸文件文字。 - 範本。 在文件中放置
{{name}}等記號。使用scripts/docx_template.py並搭配一個 JSON 物件作為值。使用--strict可在有未填入的記號時失敗;無論如何,JSON 輸出都會列出filled計數和unfilled_tokens。 - 驗證(務必執行):使用
--text或--structure重新讀取輸出,並對任何透過修訂/註解手術產生的檔案執行docx_validate.py。
轉換為 PDF
無需腳本。當安裝了 LibreOffice 時,可無頭模式轉換:
soffice --headless --convert-to pdf --outdir outdir/ file.docx
先檢查是否存在(command -v soffice || command -v libreoffice)。如果兩者都不存在,請告知使用者此環境不提供 PDF 轉換功能,而非自行湊合 — python-docx 無法渲染 PDF,版面配置的保真度需要真正的渲染器。
陷阱
- 記號分散於多個執行緒。 Word 經常將文字分割成多個執行緒。取代輔助工具會合併匹配的執行緒(取代內容會繼承第一個執行緒的格式);先執行
docx_edit.py normalize可減少後續所有編輯的碎片化問題。 - 修訂涵蓋範圍。
docx_revisions.py可處理執行緒層級的插入和刪除(絕大多數情況)。段落標記和表格列修訂、格式變更記錄以及移動,會被--revisions偵測到,但不會自動處理 — 請參閱references/revisions-and-comments.md並將這些情況交由 Word 處理。 - 註解執行緒。 回覆和「已解決」狀態位於
commentsExtended.xml,此技能會忽略此檔案;它新增的註解是單純的頂層註解。 - 欄位結果由 Word 計算。
toc、page-numbers以及toc/footer_page_numbers規格選項僅會寫入功能變數代碼。Word/LibreOffice 會在檔案開啟時填入實際條目和數字(Word 可能會提示更新欄位);python-docx 永遠不會計算它們,因此在打開前會顯示佔位文字。 - 驗證是健康檢查,而非結構描述驗證。
docx_validate.py會驗證 zip、必要零件、關聯目標、圖片魔術位元組以及參照的樣式。這並非 XSD 驗證 — 一個檔案可能通過驗證但仍包含 Word 不喜歡的 XML。 - 樣式名稱必須存在。 套用文件中未定義的樣式會引發
KeyError。像Heading 1、List Bullet、List Number、Table Grid等內建樣式存在於預設範本中;自訂樣式必須先在建立規格中宣告。 - 編號清單會重新編號。
List Number依賴 Word 的預設編號;同一文件中的不同清單可能會繼續編號而非重新開始。若使用者需要精確的多清單編號,請提醒他們。 - 儲存格寫入會取代格式。
set-cell使用cell.text = ...,這會將該儲存格中的執行緒重設為純文字格式。 - 編碼。 所有 JSON 規格/值檔案都以 UTF-8 明確讀取;在自行編寫膠水程式碼時,絕不要依賴地區設定預設值。
- 切勿解壓縮後直接 sed XML。 透過腳本(或 python-docx)進行編輯;在
document.xml中直接取代文字很容易損壞檔案。patch/write_file僅用於 JSON 輸入,絕不要用於.docx本身。
驗證
- 在建立/編輯/套用範本後,執行
docx_read.py out.docx --text並檢查預期的字串是否出現(以及舊字串是否消失)。 - 在接受/拒絕後,
docx_revisions.py list應回傳[](或僅回傳您刻意保留的 ID);在註解手術後,docx_comments.py list應反映變更,且--text輸出必須保持不變。 docx_validate.py out.docx在套件健康時應以狀態碼 0 退出並顯示"ok": true— 在任何修訂/註解/欄位操作後執行。- 對於使用
--strict執行的範本,請檢查unfilled_tokens == []。 - 結構檢查:
--structure應顯示預期的標題大綱和表格形狀;--styles可確認自訂樣式已套用。