DOCX 建立、編輯與分析
一個 .docx 檔案其實是 ZIP 壓縮檔,內含多個 XML 檔案。請依據任務選擇合適的方式:
| 任務 | 方法 |
|---|---|
| 建立新文件 | 撰寫 docx (npm) 腳本 — 請留意下方的注意事項 |
| 編輯現有文件 | unzip → 編輯 word/document.xml → zip (docx-js 無法開啟現有檔案) |
| 讀取內容 | pandoc -t markdown file.docx |
下方的腳本路徑均相對於此技能目錄。
使用 docx-js 建立文件 — 注意事項
docx 已預先安裝 — 請勿先執行 npm install,直接撰寫腳本並使用 require('docx') 即可。僅在 require 失敗時才執行 npm install docx。模型已了解 API,以下是容易踩雷的地方:
- 頁面大小預設為 A4。 若要使用 US Letter,請設定
page: { size: { width: 12240, height: 15840 } }(單位為 DXA;1440 = 1 英吋)。 - 橫向: 傳入直向尺寸並加上
orientation: PageOrientation.LANDSCAPE— docx-js 內部會交換寬/高。 - 表格需要雙重寬度: 在表格上設定
columnWidths,並在每個儲存格上設定width,兩者都使用WidthType.DXA(在 Google Docs 中使用 PERCENTAGE 會出錯)。欄寬總和必須等於表格寬度。 - 表格背景: 使用
ShadingType.CLEAR,絕對不要使用SOLID(會渲染成黑色)。 - 清單: 絕對不要直接插入
•符號;應使用numbering設定搭配LevelFormat.BULLET。 ImageRun需要type:(例如"png"、"jpg"等)。PageBreak必須放在Paragraph內部。- 絕對不要使用
\n— 請使用獨立的Paragraph元素。 - 目錄: 標題必須使用內建的
HeadingLevel.*;自訂標題樣式需要設定outlineLevel,否則不會出現在目錄中。 - 不要使用表格當作水平線 — 改用段落底部框線。
- 點狀引導 / 同行對齊: 在
TextRun內部使用PositionalTab(alignment: PositionalTabAlignment.RIGHT、leader: PositionalTabLeader.DOT),不要使用 literal.或空格填充。
驗證輸出
寫好 .docx 後,將其轉換並查看:
python scripts/office/soffice.py --headless --convert-to pdf output.docx
pdftoppm -jpeg -r 100 output.pdf page
ls page-*.jpg # 然後讀取這些圖片
pdftoppm 會將頁碼補零至與總頁數位數相同的寬度 (page-01.jpg…page-12.jpg)。
編輯現有文件
舊版的 .doc 檔案必須先轉換:python scripts/office/soffice.py --headless --convert-to docx file.doc。
unzip -q doc.docx -d unpacked/
find unpacked -type l -delete # 移除符號連結項目 — 來自外部的 docx 可能不安全
python scripts/merge_runs.py unpacked/ # 合併分散的文字片段,讓文字可以被搜尋到
# 就地編輯 unpacked/word/document.xml — 不要重新格式化或美化
(cd unpacked && rm -f ../out.docx && zip -Xr ../out.docx .)
python scripts/office/validate.py out.docx --original doc.docx # XSD 檢查;--auto-repair 可修復常見問題
# 使用了修訂標記?加上 --author "<您的修訂者名稱>" 檢查每個編輯是否都有追蹤
Word 會將文字分散在多個 <w:r> 元素中(由於修訂 ID、拼字檢查標記等),因此在文件中看到的某個片語,在 XML 中往往不是連續的字串。merge_runs.py 可合併 word/document.xml 中相鄰且格式相同的元素,不改變內容或呈現效果;它也能直接接受 .docx 檔案 (python scripts/merge_runs.py doc.docx -o merged.docx)。
追蹤修訂: 使用修訂標記時,請以 --author "<您的修訂者名稱>" 進行驗證(需搭配 --original)— 它會報告任何您修改過但未包在 <w:ins>/<w:del> 中的文字,這種情況很容易不小心發生,且在「接受」檢視中不可見。請將元素包在 <w:ins>/<w:del> 中,並加上 w:id、w:author、w:date 屬性。在 <w:del> 內部,文字元素應使用 <w:delText>,而非 <w:t>。已刪除的段落標記(<w:pPr><w:rPr><w:del w:id=".." w:author=".." w:date=".."/></w:rPr></w:pPr>)表示「將此段落合併至下一個段落」— 因此完全刪除一個段落就是這個標記加上每個元素包在 <w:del> 中。<w:del/> 必須出現在 rPr 的其他子元素之前;其順序由結構定義強制規定。
若要產生已接受所有追蹤修訂的乾淨複本:python scripts/accept_changes.py in.docx out.docx。
接受已刪除的段落標記應將該段落與下方的段落合併,因此所有元素都「刪除」的段落會消失。Word 能做到;accept_changes.py 和 pandoc --track-changes=accept 則不一定。兩者失敗的方式相同—它們會移除已刪除的文字,但留下空的段落,這在自動編號時會變成一個多餘的空項目符號:
pandoc --track-changes=accept永遠不會合併段落。accept_changes.py(LibreOffice) 能正確合併,但當已刪除的段落後面跟著一個空的間隔段落時則例外。
在任何檢視中出現的空白項目符號都是該檢視的產物,而不是文件本身的缺陷。請在 XML 中檢查段落刪除。
註解
註解需要六個相互關聯的檔案。使用輔助工具 — 若同時也要編輯 document.xml,建議使用目錄模式(可節省一次解壓/重新壓縮的循環),否則使用 .docx 直接模式:
# 針對已解壓縮的目錄(在同時放置標記時較佳)
python scripts/comment.py unpacked/ "費用與支出上限太低"
python scripts/comment.py unpacked/ "同意" --parent 0
# 直接針對 .docx 檔案
python scripts/comment.py contract.docx "此上限太低" -o annotated.docx
腳本會寫入 comments.xml、commentsExtended.xml、commentsIds.xml、commentsExtensible.xml、關聯檔案以及內容類型覆寫。註解 ID 會自動指派。接著腳本會輸出要加入 word/document.xml 的 <w:commentRangeStart>/<w:commentRangeEnd>/<w:commentReference> 片段,以便將註解錨定到特定文字 — 在放置這些標記之前,註解存在但不可見。
依賴項目
docx (npm,已預先安裝 — 僅在 require('docx') 失敗時才安裝) · pandoc · LibreOffice (soffice) · pdftoppm (Poppler)
此技能由 Anthropic 建立與維護。除前置中繼資料外,在此原封不動提供;使用條款請見 LICENSE.txt。