3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Wordファイル(.docx)をブラウザだけでMarkdown・テキストに変換する(mammoth.js)

3
Posted at

Wordで書いた文章を、Markdownやプレーンテキストで取り出したいことがあります。ブログやGit、CMS、あるいはAIに渡す前処理など。でも本文をコピペすると、見出しやリストの構造が崩れたり、余計な書式が付いてきたりして地味に面倒です。

この記事では、Wordファイル(.docx)を、アップロードせずブラウザの中だけで HTML / Markdown / テキストに変換する方法を mammoth.js でまとめます。

ゴール:.docx を選ぶだけで、構造を保ったまま Markdown やテキストとして取り出せるようになること。


なぜ mammoth.js なのか

.docx の中身は、実は複数のXMLをまとめたZIP(OOXML)です。自前でパースするのは大変ですが、mammoth.js は「見た目の装飾は捨てて、意味のある構造だけ」をHTMLに変換してくれます。見出し・段落・リスト・太字/斜体・リンク・表などが対象で、フォントや色といった飾りは意図的に落とします。「きれいなMarkdownにしたい」用途にちょうどよい思想です。

<script src="https://cdn.jsdelivr.net/npm/mammoth@1.6.0/mammoth.browser.min.js"></script>

基本:.docx を HTML に変換する

ファイルを ArrayBuffer で読み込んで渡すだけです。

document.getElementById("file").addEventListener("change", async (e) => {
  const file = e.target.files[0];
  if (!file) return;

  const arrayBuffer = await file.arrayBuffer();
  const result = await mammoth.convertToHtml({ arrayBuffer });

  document.getElementById("out").innerHTML = result.value; // 変換されたHTML
  console.log(result.messages);                            // 警告(対応できなかった要素など)
});

result.messages には「このスタイルは変換できなかった」等の警告が入ります。品質を詰めたいときに便利です。


プレーンテキストだけ欲しいとき

装飾も構造もいらず、本文テキストだけ抜きたいなら extractRawText です。

const { value: text } = await mammoth.extractRawText({ arrayBuffer });
console.log(text); // 段落ごとに改行された素のテキスト

Markdown に変換する

mammoth.js は HTML を返すので、HTML → Markdown を一段かませます。Turndown が手軽です。

<script src="https://cdn.jsdelivr.net/npm/turndown@7.1.2/dist/turndown.js"></script>
const html = (await mammoth.convertToHtml({ arrayBuffer })).value;

const td = new TurndownService({
  headingStyle: "atx",        // # 見出し スタイル
  codeBlockStyle: "fenced",   // ``` のコードブロック
  bulletListMarker: "-",
});
const markdown = td.turndown(html);
console.log(markdown);

これで、見出し・リスト・リンク・太字などが Markdown 記法に落ちます。


Wordの独自スタイルを見出しに対応させる

「見た目は見出しなのに、Word上は普通の段落」というファイルはよくあります。mammoth の styleMap で、Wordのスタイル名を任意の要素へ対応づけられます。

const result = await mammoth.convertToHtml({ arrayBuffer }, {
  styleMap: [
    "p[style-name='Heading 1'] => h1:fresh",
    "p[style-name='Heading 2'] => h2:fresh",
    "p[style-name='Quote'] => blockquote",
  ],
});

:fresh は「連続しても結合せず、毎回新しい要素にする」指定です。


つまずきやすいところ

  • 対応は .docx のみ。 旧形式の .doc は変換できません(先にWordで .docx 保存を)。
  • 見た目は保持されない。 段組・フォント・色・細かい配置は意図的に落ちます。mammoth は「構造を移す」ツールで、レイアウト再現用ではありません。
  • 画像。 既定では画像を Base64 の data URL としてHTMLに埋め込みます。convertImage オプションで扱いを変えられます。
  • 複雑な表。 セル結合の多い表などは、きれいに移らないことがあります。
  • 警告を見る。 result.messages に落ちた要素が出るので、変換品質のチェックに使えます。

Python でやる場合

Python にも mammoth があります。

import mammoth

with open("input.docx", "rb") as f:
    result = mammoth.convert_to_html(f)
    html = result.value
    # テキストだけなら mammoth.extract_raw_text(f)

Markdownまで一気に欲しいなら pandocpandoc input.docx -t gfm -o out.md)も定番です。


まとめ

  • .docx は中身がOOXML(ZIP+XML)。自前パースせず mammoth.js に任せる
  • HTMLは convertToHtml、素のテキストは extractRawText
  • Markdownは mammoth(HTML)→ Turndown(Markdown) の二段
  • Wordの独自スタイルは styleMap で見出し等へマッピング
  • 装飾・レイアウトは保持されない(構造を移すツール)と割り切る

「Wordの中身を、崩さずMarkdownで取り出したい」に、ブラウザ完結はよく合います。参考になれば嬉しいです。


3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?