dom-docx: HTMLからネイティブで編集可能なWordドキュメントへ

dom-docx: HTMLからネイティブで編集可能なWordドキュメントへ

概要

dom-docxは、セマンティックなHTMLフラグメントをネイティブで編集可能なWordドキュメント(OOXML)に変換するために設計されたTypeScriptライブラリです。スクリーンショットやレイアウトのハックを作成するツールとは異なり、dom-docxは段落、ラン、リスト、テーブルといった実際のWord構造を生成するため、生成されたドキュメントはMicrosoft WordやLibreOfficeで完全に編集可能です。

コア機能

サポートされているHTML要素

デフォルトのinlineモードでは、ライブラリは幅広いセマンティックHTMLをサポートしています:

  • テキストと構造: 見出し、段落、リスト(<ul>, <ol>)、および引用(blockquote)。
  • 書式設定: インライン書式(<strong>, <em>)、リンク、および水平線(<hr>)。
  • 引用とレイアウト: データテーブル、網掛けのコールアウト、およびシンプルなフレックス行(最大4項目)。
  • ビジュアル: data: 画像および低複雑度のインラインSVG(特にバーとテキスト)。

高度なレンダリングオプション

スタイルや複雑さの要件に応じて、dom-docxは変換のために3つの異なるパスを提供します:

  1. インラインスタイルの解決 (styleSource: "inline"): デフォルトの純粋なJavaScriptパスです。style=""属性を直接解析し、ブラウザ環境を必要としません。
  2. 計算済みスタイルの解決 (styleSource: "computed"): getComputedStyleを使用して、<style>ブロック、クラス、およびIDセレクタを解決します。
    • Node.jsの場合: ヘッドレスでフラグメントをレンダリングするためにPlaywrightとChromiumが必要です。
    • ブラウザの場合: ユーザーのタブのライブDOMを使用するため、追加のインストールは不要です。
  3. ラスタライズ (rasterizeInPlace): 変換前に<canvas>や複雑な<svg>(Highchartsなど)をPNG画像に変換します。これは複雑なチャートに推奨され、高密度な出力を得るためにscale: 2が推奨されます。

技術アーキテクチャ

変換パイプライン

ライブラリは、3段階のプロセスを通じてHTMLをOOXMLにマッピングします:

  1. スタイル解決: インライン属性またはブラウザの計算済みスタイルを介して最終的なスタイルを決定します。
  2. ビジターパターン: Cheerioのウォークを使用して、HTML要素をdocxの段落、テーブル、番号付け、およびハイパーリンクに変換します。
  3. パック&パッチ: OOXMLを生成し、WordとLibreOfficeのPDFエクスポートにおいて、リストの番号付けや網掛けブロックの配置が一致するようにパッチを適用します。

ビジュアル回帰による品質保証

著者は、忠実度を継続的に改善する自律的なループである「Autoresearch」パターンを使用してdom-docxを開発しました。このプロセスには以下が含まれます:

  • ChromiumでのHTMLのレンダリング。
  • dom-docxによるHTMLから.docxへの変換。
  • LibreOfficeを使用した.docxファイルのラスタライズ。
  • レイアウトの忠実度、編集可能性、および速度をスコア化するために、ブラウザのスクリーンショットとLibreOfficeのスクリーンショットを比較。

このループは、人間の品質評価と高い一致を示すことを確認するために、37の実際のHTMLパターンに対して実行されました。

統合と使用方法

インストール

npm install dom-docx

注: Node.js ≥ 20が必要です。Playwrightは、Nodeにおける計算済みスタイルまたはラスタライズのためにのみ使用されるオプションのピア依存関係です。

クイックスタート例

ブラウザでの使用 (純粋なJS、Playwrightなし):

import { convertHtmlToDocx } from "dom-docx/browser";

const html = `<h1 style="color:#1a1a2e">Quarterly Report</h1><p>Revenue grew <strong>12%</strong> year over year.</p>`;
const blob = await convertHtmlToDocx(html);
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = "output.docx";
a.click();

Node.jsでの使用:

import { writeFile } from "node:fs/promises";
import { convertHtmlToDocx } from "dom-docx";

const html = `<h1 style="color:#1a1a2e">Quarterly Report</h1><p>Revenue grew <strong>12%</strong> year over year`;
const docx = await convertHtmlToDocx(html);
await writeFile("output.docx", docx);

CLIツール

コードを書かずに素早く変換を行うために、ライブラリはCLIを提供しています:

npx dom-docx input.html -o output.docx

制限事項

バージョン 0.1.xにおいて、以下の機能はサポートされていません:

  • inlineパスにおける外部スタイルシート。
  • Webフォント、CSS grid、floatレイアウト、および絶対配置。
  • フォーム、<dl>、およびテーブルのrowspan
  • 複雑なSVGパスおよびグラデーション(rasterizeInPlaceを使用しない場合)。
  • 保証されたマルチページレイアウトの忠実度、または最初のページ/偶数ページ用の特定のヘッダー/フッターのバリエーション。

Sources