ReactでJavaScriptを使ってWordをHTMLに変換

Word文書をHTML形式に変換することで、コンテンツクリエイターは、ウェブ展示に適したコンテンツを作成するために、親しみやすいWord文書編集環境を活用できます。また、Word文書の内容をウェブページに埋め込むことで、コンテンツのメンテナンス性と更新効率を向上させることができます。JavaScriptとReactを使用することで、開発者はクライアントブラウザ内で直接Word文書をHTMLに変換する機能を実現でき、開発ワークフローが簡素化され、ロード時間やサーバーコストが削減されます。この記事では、**ReactアプリケーションでJavaScriptを使用してWord文書をHTML形式に変換する方法**について解説します。

- **[JavaScriptでWord文書をHTML形式に変換](#javascriptでword文書をhtml形式に変換)**
- **[Word文書をCSSと画像を埋め込んだHTMLファイルに変換](#word文書をcssと画像を埋め込んだhtmlファイルに変換)**
- **[Word文書をHTML形式に変換し、変換オプションをカスタマイズ](#word文書をhtml形式に変換し変換オプションをカスタマイズ)**

この記事で使用する方法では、[Spire.Doc for JavaScript](https://www.e-iceblue.com/Tutorials/Doc-Javascript/Getting-Started/How-to-Integrate-Spire.Doc-for-JavaScript-in-a-React-Project.html)が必要です。NPMコマンドは以下の通りです：`npm install spire.doc`。

## JavaScriptでWord文書をHTML形式に変換

まず、Spire.Doc.Base.jsファイルを読み込んでWASMモジュールを初期化します。変換の過程では、`Document.LoadFromFile()`メソッドを使用してWord文書をファイルからロードし、その後`Document.SaveToFile()`メソッドでHTML形式に変換してVFSに保存します。以下は詳細な手順です：

- 必要なモジュールをインポートする。
- `Spire.Doc.Base.js`ファイルを読み込んでWebAssemblyモジュールを初期化する。
- `wasmModule.FetchFileToVFS()`メソッドを使用して、Wordファイルを仮想ファイルシステムにロードする。
- `wasmModule.Document.Create()`メソッドを使用して、WASMモジュール内でDocumentインスタンスを作成する。
- `Document.LoadFromFile()`メソッドでWord文書をDocumentインスタンスにロードする。
- `Document.SaveToFile({ fileName: string, fileFormat: wasmModule.FileFormat.Html })`メソッドを使用して、Word文書をHTML形式に変換し保存する。
- 結果のファイルをパッケージしてダウンロードする、または必要に応じて他の操作を行う。
- リソースを解放する。

**コード例**
```js
import React, { useState, useEffect } from 'react';
import JSZip from 'jszip';

function App() {

  // 読み込んだWASMモジュールを保持するステート
  const [wasmModule, setWasmModule] = useState(null);

  // コンポーネントがマウントされたときにWASMモジュールを読み込むuseEffectフック
  useEffect(() => {
    const loadWasm = async () => {
      try {

        // グローバルなwindowオブジェクトからModuleとspiredocを取得
        const { Module, spiredoc } = window;

        // ランタイムが初期化されたときにwasmModuleステートを設定
        Module.onRuntimeInitialized = () => {
          setWasmModule(spiredoc);
        };
      } catch (err) {

        // 読み込み中に発生したエラーをログに記録
        console.error('WASMモジュールの読み込みに失敗しました:', err);
      }
    };

    // WASM JavaScriptファイルを読み込むためのスクリプト要素を作成
    const script = document.createElement('script');
    script.src = `${process.env.PUBLIC_URL}/Spire.Doc.Base.js`;
    script.onload = loadWasm;

    // ドキュメントのbodyにスクリプトを追加
    document.body.appendChild(script);

    // コンポーネントがアンマウントされるときにスクリプトを削除するクリーンアップ関数
    return () => {
      document.body.removeChild(script);
    };
  }, []);

  // WordドキュメントをHTML形式に変換する関数
  const WordToHTMLAndZip = async () => {
    if (wasmModule) {
      // 入力ファイル名と出力フォルダ名を指定
      const inputFileName = 'Sample.docx';
      const outputFolderName = 'WordToHTMLOutput';

      // 入力ファイルを取得し、VFSに追加
      await wasmModule.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/`);

      // Documentクラスのインスタンスを作成
      const doc = wasmModule.Document.Create();
      // Wordドキュメントを読み込む
      doc.LoadFromFile({ fileName: inputFileName });

      // WordドキュメントをHTML形式で出力フォルダに保存
      doc.SaveToFile({ fileName: `${outputFolderName}/document.html`, fileFormat: wasmModule.FileFormat.Html });

      // リソースを解放
      doc.Dispose();

      // 新しいJSZipオブジェクトを作成
      const zip = new JSZip();

      // ディレクトリとその内容をZIPに追加する再帰関数
      const addFilesToZip = (folderPath, zipFolder) => {
        const items = wasmModule.FS.readdir(folderPath);
        items.filter(item => item !== "." && item !== "..").forEach((item) => {
          const itemPath = `${folderPath}/${item}`;

          try {
            // ファイルデータの読み込みを試みる
            const fileData = wasmModule.FS.readFile(itemPath);
            zipFolder.file(item, fileData);
          } catch (error) {
            if (error.code === 'EISDIR') {
              // ディレクトリの場合、新しいフォルダをZIPに作成し、再帰的に処理
              const zipSubFolder = zipFolder.folder(item);
              addFilesToZip(itemPath, zipSubFolder);
            } else {
              // その他のエラー処理
              console.error(`${itemPath}の処理中にエラーが発生しました:`, error);
            }
          }
        });
      };

      // 出力フォルダ内のすべてのファイルをZIPに追加
      addFilesToZip(outputFolderName, zip);

      // ZIPファイルを生成してダウンロード
      zip.generateAsync({ type: 'blob' }).then((content) => {
        const url = URL.createObjectURL(content);
        const a = document.createElement('a');
        a.href = url;
        a.download = `${outputFolderName}.zip`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
      });
    }
  };

  return (
      <div style={{ textAlign: 'center', height: '300px' }}>
        <h1>ReactでJavaScriptを使用してWordファイルをHTMLに変換し、ZIPとしてダウンロード</h1>
        <button onClick={WordToHTMLAndZip} disabled={!wasmModule}>
          変換してダウンロード
        </button>
      </div>
  );
}

export default App;
```

Word文書：
![JavaScriptでWordをHTMLに変換](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/fb971ad6-3565-0d52-e96b-a64ac83458d5.png)

変換後のHTML：
![ReactでWordをHTMLに変換](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/f5e72ca4-4341-01b4-8bac-02c31357a6dd.png)

## Word文書をCSSと画像を埋め込んだHTMLファイルに変換

変換前に、`Document.HtmlExportOptions.CssStyleSheetType`属性と`Document.HtmlExportOptions.ImageEmbedded`属性を設定して、HTMLファイル内にCSSファイルや画像を埋め込むようにできます。これにより、Word文書を単一のHTMLファイルとして変換できます。以下はその手順です：

- 必要なモジュールをインポートする。
- `Spire.Doc.Base.js`ファイルを読み込んでWebAssemblyモジュールを初期化する。
- `wasmModule.FetchFileToVFS()`メソッドを使用して、Wordファイルを仮想ファイルシステムにロードする。
- `wasmModule.Document.Create()`メソッドを使用して、WASMモジュール内でDocumentインスタンスを作成する。
- `Document.LoadFromFile()`メソッドでWord文書をDocumentインスタンスにロードする。
- `Document.HtmlExportOptions.CssStyleSheetType`属性を`wasmModule.CssStyleSheetType.Internal`に設定し、CSSスタイルを生成されたHTMLファイル内に埋め込む。
- `Document.HtmlExportOptions.ImageEmbedded`属性を`true`に設定し、画像を生成されたHTMLファイルに埋め込む。
- `Document.SaveToFile({ fileName: string, fileFormat: wasmModule.FileFormat.Html })`メソッドを使用して、CSSと画像が埋め込まれたHTMLファイルにWord文書を変換する。
- 生成されたHTMLファイルをダウンロードする、または必要に応じて他の操作を行う。
- リソースを解放する。

**コード例**
```js
import React, { useState, useEffect } from 'react';

function App() {

  // 読み込んだWASMモジュールを保持するステート
  const [wasmModule, setWasmModule] = useState(null);

  // コンポーネントがマウントされたときにWASMモジュールを読み込むuseEffectフック
  useEffect(() => {
    const loadWasm = async () => {
      try {
        const { Module, spiredoc } = window;
        Module.onRuntimeInitialized = () => {
          setWasmModule(spiredoc);
        };
      } catch (err) {
        console.error('WASMモジュールの読み込みに失敗しました:', err);
      }
    };

    const script = document.createElement('script');
    script.src = `${process.env.PUBLIC_URL}/Spire.Doc.Base.js`;
    script.onload = loadWasm;

    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script);
    };
  }, []);

  // WordドキュメントをHTML形式に変換する関数
  const WordToHTMLAndZip = async () => {
    if (wasmModule) {

      // 入力ファイル名と出力ファイル名を指定
      const inputFileName = 'Sample.docx';
      const outputFileName = 'ConvertedDocument.html';

      // 入力ファイルを取得し、VFSに追加
      await wasmModule.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/`);

      // Documentクラスのインスタンスを作成
      const doc = wasmModule.Document.Create();

      // Wordドキュメントを読み込む
      doc.LoadFromFile({ fileName: inputFileName });

      // HTMLファイルにCSSファイルを埋め込む
      doc.HtmlExportOptions.CssStyleSheetType = wasmModule.CssStyleSheetType.Internal;

      // HTMLファイルに画像を埋め込む
      doc.HtmlExportOptions.ImageEmbedded = true;

      // WordドキュメントをHTML形式で保存
      doc.SaveToFile({ fileName: outputFileName, fileFormat: wasmModule.FileFormat.Html });

      // リソースを解放
      doc.Dispose();

      // VFSからHTMLファイルを読み込む
      const htmlFileArray = wasmModule.FS.readFile(outputFileName);

      // HTMLファイル配列からBlobを生成し、ダウンロードをトリガー
      const blob = new Blob([new Uint8Array(htmlFileArray)], { type: 'text/html' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = outputFileName;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    }
  };

  return (
      <div style={{ textAlign: 'center', height: '300px' }}>
        <h1>ReactでJavaScriptを使用してWordをHTMLに変換</h1>
        <button onClick={WordToHTMLAndZip} disabled={!wasmModule}>
          変換してダウンロード
        </button>
      </div>
  );
}

export default App;
```

## Word文書をHTML形式に変換し、変換オプションをカスタマイズ

`Document.HtmlExportOptions`属性には、変換オプションをカスタマイズするための他の複数の属性もあります。これにより、CSSファイル名や画像のパス、ヘッダーやフッターの有無などを設定できます。以下の表に属性とその機能を示します：

| 属性                        | 説明                                                                 |
|-----------------------------|----------------------------------------------------------------------|
| CssStyleSheetType           | HTMLのCSSスタイルシートのタイプ（ExternalまたはInternal）を指定。    |
| CssStyleSheetFileName       | HTMLのCSSスタイルシートファイル名を指定。                           |
| ImageEmbedded               | HTMLコード内で画像をData URIで埋め込むかどうかを指定。               |
| ImagesPath                  | HTML内でエクスポートする画像の保存先パスを指定。                     |
| UseSaveFileRelativePath     | 画像ファイルパスをHTMLファイルパスに対して相対的にするかどうかを指定。 |
| HasHeadersFooters           | エクスポートされたHTMLにヘッダーとフッターを含めるかどうかを指定。   |
| IsTextInputFormFieldAsText  | テキスト入力フォームフィールドをHTMLにテキスト形式でエクスポートするかどうかを指定。 |
| IsExportDocumentStyles      | ドキュメントのスタイルをHTMLの`<head>`部分にエクスポートするかどうかを指定。 |

以下は操作手順の例です：

- 必要なモジュールをインポートする。
- `Spire.Doc.Base.js`ファイルを読み込んでWebAssemblyモジュールを初期化する。
- `wasmModule.FetchFileToVFS()`メソッドを使用して、Wordファイルを仮想ファイルシステムにロードする。
- `wasmModule.Document.Create()`メソッドを使用して、WASMモジュール内でDocumentインスタンスを作成する。
- `Document.LoadFromFile()`メソッドでWord文書をDocumentインスタンスにロードする。
- `Document.HtmlExportOptions`属性を使用して変換オプションをカスタマイズする。
- `Document.SaveToFile({ fileName: string, fileFormat: wasmModule.FileFormat.Html })`メソッドでWord文書をHTML形式に変換する。
- 結果のファイルをパッケージしてダウンロードする、または必要に応じて他の操作を行う。
- リソースを解放する。

**コード例**
```js
import React, { useState, useEffect } from 'react';
import JSZip from 'jszip';

function App() {

  // 読み込んだWASMモジュールを保持するステート
  const [wasmModule, setWasmModule] = useState(null);

  // コンポーネントがマウントされたときにWASMモジュールを読み込むuseEffectフック
  useEffect(() => {
    const loadWasm = async () => {
      try {

        // グローバルなwindowオブジェクトからModuleとspiredocを取得
        const { Module, spiredoc } = window;

        // ランタイムが初期化されたときにwasmModuleステートを設定
        Module.onRuntimeInitialized = () => {
          setWasmModule(spiredoc);
        };
      } catch (err) {

        // 読み込み中に発生したエラーをログに記録
        console.error('WASMモジュールの読み込みに失敗しました:', err);
      }
    };

    // WASM JavaScriptファイルを読み込むためのスクリプト要素を作成
    const script = document.createElement('script');
    script.src = `${process.env.PUBLIC_URL}/Spire.Doc.Base.js`;
    script.onload = loadWasm;

    // ドキュメントのbodyにスクリプトを追加
    document.body.appendChild(script);

    // コンポーネントがアンマウントされるときにスクリプトを削除するクリーンアップ関数
    return () => {
      document.body.removeChild(script);
    };
  }, []);

  // WordドキュメントをHTML形式に変換する関数
  const WordToHTMLAndZip = async () => {
    if (wasmModule) {
      // 入力ファイル名とベースとなる出力ファイル名を指定
      const inputFileName = 'Sample.docx';
      const baseOutputFileName = 'WordToHTML';
      const outputFolderName = 'WordToHTMLOutput';

      // 入力ファイルを取得し、VFSに追加
      await wasmModule.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/`);

      // Documentクラスのインスタンスを作成
      const doc = wasmModule.Document.Create();

      // Wordドキュメントを読み込む
      doc.LoadFromFile({ fileName: inputFileName });

      // CSSファイルを外部ファイルとして埋め込む
      doc.HtmlExportOptions.CssStyleSheetType = wasmModule.CssStyleSheetType.External;
      doc.HtmlExportOptions.CssStyleSheetFileName = `${baseOutputFileName}CSS.css`;

      // 画像ファイルを外部として扱い、そのパスを設定
      doc.HtmlExportOptions.ImageEmbedded = false;
      doc.HtmlExportOptions.ImagesPath = `/Images`;
      doc.HtmlExportOptions.UseSaveFileRelativePath = true;

      // ヘッダーとフッターを無視する設定
      doc.HtmlExportOptions.HasHeadersFooters = false;

      // フォームフィールドをテキストとして出力
      doc.HtmlExportOptions.IsTextInputFormFieldAsText = true;

      // ドキュメントスタイルをheadセクションにエクスポート
      doc.HtmlExportOptions.IsExportDocumentStyles = true;

      // WordドキュメントをHTML形式で保存
      doc.SaveToFile({
        fileName: `${outputFolderName}/${baseOutputFileName}.html`,
        fileFormat: wasmModule.FileFormat.Html
      });

      // リソースを解放
      doc.Dispose();

      // 新しいJSZipオブジェクトを作成
      const zip = new JSZip();

      // ディレクトリとその内容をZIPに追加する再帰関数
      const addFilesToZip = (folderPath, zipFolder) => {
        const items = wasmModule.FS.readdir(folderPath);
        items.filter(item => item !== "." && item !== "..").forEach((item) => {
          const itemPath = `${folderPath}/${item}`;

          try {
            // ファイルデータの読み込みを試みる。ディレクトリの場合、エラーが発生する
            const fileData = wasmModule.FS.readFile(itemPath);
            zipFolder.file(item, fileData);
          } catch (error) {
            if (error.code === 'EISDIR') {
              // ディレクトリの場合、新しいフォルダをZIPに作成し、再帰的に処理
              const zipSubFolder = zipFolder.folder(item);
              addFilesToZip(itemPath, zipSubFolder);
            } else {
              // その他のエラー処理
              console.error(`${itemPath}の処理中にエラーが発生しました:`, error);
            }
          }
        });
      };

      // 出力フォルダの内容をZIPに追加
      addFilesToZip(`${outputFolderName}`, zip);

      // ZIPファイルを生成してダウンロード
      zip.generateAsync({ type: 'blob' }).then((content) => {
        const url = URL.createObjectURL(content);
        const a = document.createElement("a");
        a.href = url;
        a.download = `${baseOutputFileName}.zip`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
      });
    }
  };

  return (
      <div style={{ textAlign: 'center', height: '300px' }}>
        <h1>ReactでJavaScriptを使用してWordファイルをHTMLに変換し、ZIPとしてダウンロード</h1>
        <button onClick={WordToHTMLAndZip} disabled={!wasmModule}>
          変換してダウンロード
        </button>
      </div>
  );
}

export default App;
```

この記事では、JavaScriptを使用してReactアプリケーションでWord文書をHTMLファイルに変換する方法について説明しました。手順とコード例を提供しました。

[無料ライセンスの申請](https://www.e-iceblue.com/TemLicense.html)