DOCXの作成、編集、解析
.docx ファイルはXMLファイルのZIPアーカイブです。タスクに応じて適切なアプローチを選択してください:
| タスク | アプローチ |
|---|---|
| 新規文書の作成 | docx(npm)スクリプトを作成 — 以下の注意点を参照 |
| 既存文書の編集 | unzip → word/document.xml を編集 → zip(docx-jsは既存ファイルを開けません) |
| 内容の読み取り | pandoc -t markdown file.docx |
以下のスクリプトパスは、このスキルのディレクトリからの相対パスです。
docx-js による作成 — 注意点
docx は事前インストール済みです — npm install を実行せず、スクリプトを書いて直接 require('docx') してください。これが失敗した場合のみ npm install docx を実行します。モデルはAPIを理解していますが、以下の点に注意してください:
- ページサイズのデフォルトはA4です。 USレターの場合は
page: { size: { width: 12240, height: 15840 } }を設定します(DXA単位;1440 = 1インチ)。 - 横向き(ランドスケープ): ポートレートの寸法と
orientation: PageOrientation.LANDSCAPEを指定します — docx-js は内部で幅と高さを入れ替えます。 - テーブルには二重の幅設定が必要: テーブルに
columnWidthsを設定し、すべてのセルにwidthを設定します。単位は両方ともWidthType.DXAとします(パーセンテージは Google ドキュメントで壊れます)。列幅の合計はテーブル幅と一致する必要があります。 - テーブルの網掛け:
ShadingType.CLEARを使用し、SOLIDは使用しないでください(黒くレンダリングされます)。 - リスト:
•をリテラルで挿入しないでください。代わりにLevelFormat.BULLETを使用したnumbering設定を使用します。 ImageRunにはtype:が必要です("png"、"jpg"、…)。PageBreakはParagraphの内部に配置する必要があります。\nは絶対に使用しないでください — 代わりに個別のParagraph要素を使用します。- 目次(TOC): 見出しは組み込みの
HeadingLevel.*を使用する必要があります。カスタム見出しスタイルにはoutlineLevelを設定しないと目次に表示されません。 - 表を水平線の代わりに使用しないでください — 代わりに段落の下線ボーダーを使用します。
- ドットリーダー / 同一行右揃え: リテラルの
.やスペースパディングではなく、TextRun内でPositionalTab(alignment: PositionalTabAlignment.RIGHT、leader: PositionalTabLeader.DOT)を使用します。
出力の確認
.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 で一般的な問題を修正
# 変更履歴(redlining)? --author "<redlineを入れた名前>" を追加して、すべての編集が追跡されているか確認します
Wordはテキストを多数の <w:r> ラン(リビジョンID、スペルチェックマーカー)に分割するため、ドキュメント上で見えるフレーズがXML内では連続した文字列として存在しないことがよくあります。merge_runs.py は、word/document.xml 内の隣接する同一フォーマットのランを、内容やレンダリングを変更せずに結合します。また、.docx を直接受け付けることもできます(python scripts/merge_runs.py doc.docx -o merged.docx)。
変更履歴(Tracked changes): redlineを入れる場合、--author "<redlineを入れた名前>" を指定して検証します(--original が必要)。これは、あなたが変更したテキストのうち、その回りに <w:ins> / <w:del> がないものを報告します。これはうっかりやりがちで、承認済みビューでは見えません。ランを <w:ins> / <w:del> で囲み、w:id、w:author、w:date 属性を付けます。<w:del> 内部では、テキスト要素は <w:t> ではなく <w:delText> です。削除された段落マーク(<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で確認してください。
コメント
コメントには6つの相互リンクされたファイルが必要です。ヘルパーを使用してください — document.xml も編集する場合はディレクトリモード(unzip/rezipサイクルを節約)、それ以外は .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)