HN 日本語サマリー

← 一覧へ戻る
プログラミング

Show HN: DOM-docx – HTMLからネイティブで編集可能なWordドキュメントへ (MIT)

Show HN: DOM-docx – HTML to native, editable Word docs (MIT) (github.com)

126 pointsby fishbone30 コメント

要約

DOM-docxは、HTMLフラグメントをネイティブで編集可能なWordドキュメント(OOXML)に変換するライブラリです。段落、テーブル、画像などをサポートし、スクリーンショットやレイアウトハックではなく、構造的な忠実性を重視しています。Node.js環境またはブラウザ内で動作し、インラインスタイルや計算されたスタイル、さらにはCanvasやSVGのラスタライズにも対応しています。

全文翻訳

DOM-docx HTMLフラグメントをネイティブで編集可能なWordドキュメント(OOXML)に変換します:段落、ラン、リスト、テーブル、画像。スクリーンショットやレイアウトハックではありません。ライブデモ:dom-docx.com。コンバーターを試したり、ショーケースを閲覧したり、学習ガイドを読んだりしてください。ビジュアルリグレッションループで構築:HTMLをChromiumでレンダリングし、docxに変換し、LibreOfficeでラスタライズし、人間が検証したメトリックに対してレイアウトと構造の忠実性をスコアリングし、イテレーションします。最新スコア:TEST-SCORES.md · 方法論:SCORING.md。 インストール npm install dom-docx Node.js ≥ 20 が必要です。デフォルトのインラインパスにはブラウザやPlaywrightは必要ありません。Playwrightが必要なのはいつですか? エントリースタイルソース:「inline」スタイルソース:「computed」インプレースラスタライズ Node (dom-docx) 純粋なJS、ブラウザなし Playwright + Chromium Playwright + Chromium (同じヘッドレスページ) ブラウザ (dom-docx/browser) 純粋なJS、ライブDOMなし ライブページ:ネイティブ getComputedStyle ライブページ:canvas/SVG → PNG タブ内の<img> Nodeでは、playwrightはオプションのピア依存関係です。npm install dom-docx は、docx、cheerio、fflateのみをプルし、重いものは何もありません。スタイルソース:「computed」またはインプレースラスタライズを渡すと、遅延ロードされます。これらのパスを使用するには、PlaywrightとChromiumを自分でインストールしてください。一度だけ:npm install playwright npx playwright install chromium Playwrightは開発テストハーネスでも使用されます(ライブラリを使用するために必須ではありません)。コントリビューター:クローン後にnpm run setup を実行してください。LibreOfficeは変換に必要ありません。テストハーネスのビジュアルに使用されるだけです。 CLI コードを書かずにファイルを変換:npx dom-docx input.html -o output.docx npx dom-docx input.html # input.docx を隣に書き込む cat fragment.html | npx dom-docx - -o - # 標準入力 → バイナリ標準出力 (パイプライン) npx dom-docx input.html -s computed # スタイルシート/クラス HTML (playwrightのインストールが必要) npm install -g dom-docx # オプション:グローバルにインストールし、「dom-docx」を実行する npxなし 入力はbodyのHTMLフラグメントで、APIと同じです。--help で全オプションを確認できます。 クイックスタート ブラウザ import { convertHtmlToDocx } from "dom-docx/browser"; const html = ` <h1 style="color:#1a1a2e">四半期レポート</h1> <p>収益は前年比 <strong>12%</strong> 増加しました。</p> <ul> <li>北米</li> <li>EMEA</li> </ul> `; const blob = await convertHtmlToDocx(html); // 例:ブラウザでダウンロードをトリガーする const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = "output.docx"; a.click(); Playwright不要、Node不要。これはユーザーのタブ内で完全に実行されます。ブラウザバンドルを参照してください。 Node import { writeFile } from "node:fs/promises"; import { convertHtmlToDocx } from "dom-docx"; const html = ` <h1 style="color:#1a1a2e">四半期レポート</h1> <p>収益は前年比 <strong>12%</strong> 増加しました。</p> <ul> <li>北米</li> <li>EMEA</li> </ul> `; const docx = await convertHtmlToDocx(html); await writeFile("output.docx", docx); bodyフラグメントのみを渡します(<!DOCTYPE> / <html> / <body> は不要です)。デフォルト:USレター、1インチのマージン、Arial 10.5ptの本文テキスト。 v0.1.x 機能サポート (デフォルトのスタイルソース:「inline」):見出し、段落、リスト (<ul>/<ol>、list-style-type を含む)、テーブル、リンク、インラインフォーマット ブロック背景、ブロッククォート、<hr>、シンプルなフレックス行 (≤4項目) data: 画像;画像リゾルバー経由のリモート画像 ページサイズ/向き/マージン、デフォルトフォント、メタデータ、ヘッダー/フッター HTML、ページ番号、目次、言語/方向 低複雑度インラインSVG (バー + テキスト) テーブルセル内のCSSバーdiv (背景 + 高さ/幅 → ネイティブシェーディングバンド) 高度 (オプションのスタイルソース:「computed」):<style>ブロックとクラス/#idセレクターをgetComputedStyleで解決します。Node:playwright (オプションのピア依存関係、別途インストール) + Chromiumが必要です。ライブラリはヘッドレスChromiumを起動してフラグメントをレンダリングします。ブラウザバンドル:ユーザーのタブ内のライブDOMを使用します。Playwright、追加インストール不要 SPAフラグメントエクスポート:convert element.innerHTML を実行する際にルート (ブラウザ) またはルートセレクター (Node + ライブページ) を渡して、計算スタイルパスをフラグメントツリーに一致させます。インラインはnpmインストールでサポートされるデフォルトです;computedはスタイルシート/クラス用、または既にレンダリングされたページがある場合に使用します。 チャート&複雑なSVG (オプションのインプレースラスタライズ):<canvas>と複雑な<svg> (例:Highcharts) をPNG <img>にラスタライズしてから変換します。チャート推奨:インプレースラスタライズ:{ scale: 2 } — シャープなWord画像のために2倍の密度でスーパーサンプリングします (デフォルトスケール:1;最大4)。ブラウザ:ルートが必要です。オフスクリーンでクローンするため、ライブページは変更されません。Node:computedスタイルと同じPlaywright/Chromiumコンテキストを使用します;一時的なスパンページはデフォルトで変更されます。シンプルなインラインSVG (rect + テキストバーチャート) は、ラスタライズなしでネイティブに変換されます。 v0.1.x でサポートされないもの:インラインパスでの外部スタイルシート (computedまたはすべてのスタイルをインライン化してください) Webフォント、CSSグリッド/フロートレイアウト、フォーム、<pre>ポリッシュ、<dl>、テーブルのrowspan ヘッダー/フッターの最初/偶数ページバリアント;保証された複数ページレイアウトの忠実性 複雑なSVG (パス、グラデーション、<use>) インプレースラスタライズがライブレンダリングページで使用されない場合。 AGENTS.md でHTML作成ティア、API.md で全オプションを参照してください。 API convertHtmlToDocx(html, options?) Promise<Buffer> (Node) を有効な.docxファイルで返します。 import { convertHtmlToDocx, type ConvertOptions } from "dom-docx"; const docx = await convertHtmlToDocx(html, { pageSize: "a4", orientation: "landscape", margins: { top: 0.75, bottom: 0.75 }, // インチ;省略されたサイドはデフォルトで1インチになります defaultFont: { family: "Georgia", sizePt: 11 }, metadata: { title: "Q3 Report", creator: "Finance" }, headerHtml: "<p style='font-size:12px;color:#666'>機密</p>", footerHtml: "<p style='font-size:12px'>© 2026 ACME</p>", pageNumber: true, lang: "en-US", direction: "ltr", coverHtml: "<h1 style='text-align:center'>四半期レビュー</h1>", // ページ1、TOCの前 tocHtml: "<ol><li><a href='#intro'>はじめに</a></li></ol>", // あなたのTOC;リンクはid="intro"にジャンプします }); オプション オプション デフォルト 説明 styleSource "inline" "inline" スタイル=""のみを解析します (純粋なJS、高速)。"computed" はgetComputedStyleを使用します。NodeではPlaywright + Chromiumが必要;ブラウザバンドルではライブDOMから読み取ります (Playwright不要)。 browser / page — Nodeのみ。計算スタイルおよび/またはインプレースラスタライズのために、開いているPlaywrightブラウザまたはページを再利用します。dom-docx/browserでは使用されません。 rootSelector — Nodeのみ。ライブPlaywrightページからelement.innerHTMLを変換する際の、エクスポートルートのCSSセレクター。渡すHTMLのノードに一致する必要があります。 rasterizeInPlace — <canvas> / チャート<svg>をPNG <img>にラスタライズしてから変換します。推奨:チャートエクスポートの場合は{ scale: 2 }。Node:Playwrightページ;ブラウザ:ルートが必要です。API.mdを参照してください。 imageResolver — data: 以外の<img src>を取得するためのフック (ライブラリは自分でフェッチしません)。 pageSize "letter" "letter", "a4" またはインチ単位の{ width, height }。 orientation "portrait" "landscape" は次元を入れ替えます。 margins 各サイド1インチ デフォルトで1インチ。 per-side overrides in inches. defaultFont Arial 10.5pt 明示的なCSSがない本文テキストの{ family, sizePt }。 metadata — title, subject, creator, keywords[], description → docProps/core.xml。 headerHtml / footerHtml — ページヘッダー/フッター用のHTMLフラグメント。 pageNumber false フッターに中央揃えのページ番号フィールドを追加します。 lang / direction — スペルチェックロケール;右から左の場合は"rtl"。 coverHtml — カバーページとしてレンダリングされるHTMLフラグメント — 最初のコンテンツ、TOCの前、その後自動ページブレーク。インラインスタイル+data:画像 (例:ロゴ)。ヘッダー/フッター/ページ番号はカバーページでは抑制されます。 tocHtml — 目次の「スロット」としてレンダリングされるHTMLフラグメント — カバーの後、本文の前に配置されます。マークアップ/スタイリング (番号付き、ボックス付き、列…) を制御します;ページ内リンク (<a href="#id">) は本文の対応するidにジャンプします。それ自身のページに配置するには、末尾に<div style="break-after:page"></div>を追加します。 画像のみ data: URLは自動的に埋め込まれます。http(s): またはファイルパスの場合は、リゾルバーを提供してください。フェッチポリシーとセキュリティを制御します:const docx = await convertHtmlToDocx(html, { imageResolver: async (src) => { const res = await fetch(src); // あなたの許可