MicrosoftのMarkItDownで日本語文書をMarkdown化する実践ガイド
はじめに
LLMに社内ドキュメントを食わせたい、RAGの前処理でPDFやOffice文書を正規化したい。そういうときに便利なのが Microsoft 製の MarkItDown です。
公式READMEは英語で網羅的ですが、日本人エンジニアが実際に使うときに引っかかるポイントはほとんど書かれていません。本記事では公式情報に加えて、
- 実際に日本語の Word / Excel / PowerPoint / PDF を合成して変換
- それぞれで「何がどう変換されるか」を生の出力とともに公開
- 日本語文書特有のつまずきどころを検証結果から明らかにする
ところまで踏み込みます。読了後、読者自身の手元ファイルで同じ検証を再現できる状態をゴールとします。本記事執筆時点の最新版は v0.1.5(2025年12月リリース)です。
目次
- MarkItDownとは何か(そして何ではないか)
- 動作環境とインストール
- 基本的な使い方(CLI / Python API)
- 【本記事の目玉】日本語文書の実変換レポート
- 4.1 Word(.docx) - 業務報告書
- 4.2 Excel(.xlsx) - 結合セル・数式を含む表
- 4.3 PowerPoint(.pptx) - スライド・発表者ノート・画像
- 4.4 PDF - reportlabで生成した日本語PDF
- 検証から見えた日本語文書変換の傾向と対策
- プラグインと拡張(Azure Document Intelligence / LLM連携)
- つまずきポイント集
- まとめ
1. MarkItDownとは何か(そして何ではないか)
MarkItDown は PDF / Word / Excel / PowerPoint / 画像 / 音声 / HTML / CSV / JSON / XML / ZIP / EPUB / YouTube URL などを Markdown に変換する Python 製のユーティリティです。MITライセンス。GitHub star 87k 超え、Microsoftの AutoGen チーム発。
立ち位置は textract に近いですが、見出し・リスト・表・リンクといった文書構造をMarkdownとして保持することに重点があります。ここを勘違いしないでください。
MarkItDownは「人間が読むための高忠実度な文書変換ツール」ではありません。
PDFを綺麗に再現したい、レイアウトを崩したくない、というユースケースには向きません。あくまでLLMが理解しやすい構造化テキストに落とすためのツールです。
対応フォーマット
PDF / PowerPoint(.pptx) / Word(.docx) / Excel(.xlsx/.xls) / 画像(EXIF + OCR) / 音声(EXIF + 文字起こし) / HTML / CSV / JSON / XML / ZIP / YouTube URL / EPUB / Outlookメッセージ
2. 動作環境とインストール
| 項目 | 要件 |
|---|---|
| Python | 3.10以上 |
| 推奨 | venv / uv / conda などの仮想環境 |
| OS | Windows / macOS / Linux |
Python 3.9以下では動きません。
uv(推奨・速い)
uv venv --python=3.12 .venv
source .venv/bin/activate
uv pip install 'markitdown[all]'
仮想環境に入ったあとは pip install ではなく uv pip install を使う点に注意。
標準のvenv
python -m venv .venv
source .venv/bin/activate # Windowsは .venv\Scripts\activate
pip install 'markitdown[all]'
依存を絞りたい場合
[all] は便利ですが、Whisper関連など重い依存も入ります。必要な形式だけに絞りたい場合は個別指定できます。
pip install 'markitdown[pdf, docx, pptx, xlsx]'
利用可能な extras:
| extras | 内容 |
|---|---|
[all] |
すべて |
[pdf] [docx] [pptx] [xlsx] [xls]
|
各形式 |
[outlook] |
Outlookメッセージ(.msg) |
[az-doc-intel] |
Azure Document Intelligence連携 |
[audio-transcription] |
音声文字起こし |
[youtube-transcription] |
YouTube字幕取得 |
動作確認
markitdown --help
3. 基本的な使い方
CLI
# 標準出力に吐く
markitdown input.pdf > output.md
# -o で出力指定
markitdown input.pdf -o output.md
# 標準入力から
cat input.pdf | markitdown
Python API
from markitdown import MarkItDown
md = MarkItDown(enable_plugins=False)
result = md.convert("test.xlsx")
print(result.text_content)
バイナリストリーム(v0.1.0以降の仕様変更)
from markitdown import MarkItDown
md = MarkItDown()
with open("sample.pdf", "rb") as f: # 必ず "rb"(バイナリモード)
result = md.convert_stream(f)
print(result.text_content)
v0.1.0での破壊的変更
convert_stream() はバイナリのファイルライクオブジェクトしか受け付けなくなりました。以前は io.StringIO も通っていましたが、現在は io.BytesIO または open(path, "rb") が必須です。ネットに転がっているサンプルコードはまだ旧仕様のものが多いので注意。
4. 日本語文書の実変換レポート
ここからが本記事の本題です。公開可能な合成データを作って、実際にMarkItDownで変換してみました。どのファイルも「業務で実際に使われそうな内容」を意識しています。
サンプル生成スクリプト一式
記事末尾に「サンプル生成スクリプト全文」を付属しています。手元で再現できます。
4.1 Word(.docx) - 業務報告書の変換
入力: 見出し階層(タイトル/H1/H2) + 本文 + 表 + 箇条書き + 番号リスト + 太字・斜体の混在 + 注釈
変換結果(抜粋)
2025年度 第2四半期 事業報告書
本報告書は、2025年度第2四半期(7月〜9月)における当社の事業活動および業績についてまとめたものである。
# 1. 売上概況
第2四半期の売上高は前年同期比12.3%増の38億5,000万円となった。...
## 1.1 事業セグメント別売上
各事業セグメントの売上内訳は以下の通りである。
| | | |
| --- | --- | --- |
| セグメント | 売上高(百万円) | 前年比 |
| AIソリューション | 2,150 | +18.5% |
| メタバース | 480 | 新規 |
| 受託開発 | 980 | -3.2% |
| 保守運用 | 240 | +5.1% |
## 1.2 主要な取り組み
* 大手製造業A社向けAIエージェント基盤の本番稼働開始
* VRM形式対応メタバース展示会プラットフォームのリリース
* 社内向け生成AIガイドライン「AI四原則」の策定および公開
* 海外拠点(シンガポール)における現地採用の強化
# 2. 次四半期の重点施策
1. AIエージェント基盤のマルチテナント化完了
2. 製造業向け業種特化LLMのPoC開始
3. メタバース展示会の常設会場オープン
**※** *本資料に記載の見通しは現時点の情報に基づくものであり、...*
観察ポイント
| 要素 | 結果 | 備考 |
|---|---|---|
| 見出し1(H1) | 正確に # に変換 |
|
| 見出し2(H2) | 正確に ## に変換 |
|
| タイトル(H0相当) | プレーンテキスト化 |
# すら付かない |
| 表 | 正確に変換されるがヘッダ行が空 | 1行目が全て空で、実ヘッダが2行目にデータ扱いで入る |
| 箇条書き |
* に正確変換 |
|
| 番号リスト |
1. 2. に正確変換 |
|
| 太字 |
** で保持 |
|
| 斜体 |
* で保持 |
最大の注意点: 表のヘッダ行認識が期待通りに動かない。python-docx でヘッダとして作っても、MarkItDown側では単なる1行目のセルとして扱われ、Markdown表のヘッダ区切り | --- | がデータの1行目の上に来てしまいます。LLMに食わせるだけなら大きな問題にはなりませんが、自動パースする場合は要注意。
4.2 Excel(.xlsx) - 結合セル・数式を含む表
入力: 3シート構成のExcel
- シート1「売上実績」: タイトル行 + 結合セルによる2段ヘッダ + 地域列の結合セル + SUM数式による合計行
- シート2「製品マスタ」: 通常の表
- シート3「備考」: 単列の注釈
変換結果
## 売上実績
| 地域別・製品別 売上実績(2025年度Q2) | Unnamed: 1 | Unnamed: 2 | Unnamed: 3 | Unnamed: 4 | Unnamed: 5 |
| --- | --- | --- | --- | --- | --- |
| NaN | NaN | NaN | NaN | NaN | NaN |
| 地域 | 営業所 | AIソリューション | NaN | メタバース | NaN |
| NaN | NaN | 売上 | 前年比 | 売上 | 前年比 |
| 東日本 | 東京 | 850 | +22% | 180 | 新規 |
| NaN | 仙台 | 210 | +8% | 45 | 新規 |
| NaN | 札幌 | 180 | +12% | 30 | 新規 |
| 西日本 | 大阪 | 620 | +18% | 150 | 新規 |
| NaN | 福岡 | 290 | +15% | 75 | 新規 |
| 合計 | NaN | NaN | NaN | NaN | NaN |
## 製品マスタ
| 製品コード | 製品名 | 単価(円) | 区分 |
| --- | --- | --- | --- |
| AI-001 | AIエージェント基盤 Pro | 1200000 | SaaS |
| AI-002 | AIエージェント基盤 Enterprise | 3500000 | SaaS |
| MV-001 | メタバース展示プラットフォーム | 800000 | PaaS |
| MV-002 | VRM連携オプション | 150000 | アドオン |
観察ポイント
| 要素 | 結果 | 備考 |
|---|---|---|
| シート分割 |
## シート名 で各シートを見出し化 |
非常に親切 |
| 通常の表 | 正確にMarkdown表化 | |
| 結合セル | 展開されず NaN が入る |
セル値が複製されない |
| 数式(=SUM等) | 計算結果ではなく NaN |
これは致命的なケースあり |
| 空セル |
NaN 文字列として出力 |
空文字列ではない |
| タイトル行(A1セル) | ヘッダ行扱いで Unnamed: N 混在 |
不格好になる |
ここが最重要: 結合セルは情報を失う方向に変換される。「東日本」のグループに「東京/仙台/札幌」があることが元のExcelを知らない読み手には分からない結果になります。
対策: RAG用途でExcelを食わせる場合、事前に以下のいずれかをやるのが実務的:
- openpyxlで結合を解除して値を複製してからMarkItDownに渡す
- Excelの時点で結合セルを使わずにデータ構造を作る
- 合計行は事前に値として保存しておく(Ctrl+A → 値貼り付け等)
4.3 PowerPoint(.pptx) - スライド・ノート・画像
入力: 5スライド
- タイトルスライド
- 箇条書きスライド(階層レベル0/1混在)
- 画像付き + 発表者ノート
- 表
- 太字・赤色装飾付きテキスト
変換結果
<!-- Slide number: 1 -->
# 2025年度 第2四半期 業績報告
AI共創事業本部
2025年10月15日
<!-- Slide number: 2 -->
# ハイライト
売上高 前年同期比 +12.3%
AIソリューション事業の成長継続
メタバース事業が初の黒字化
海外売上比率が18%まで上昇
<!-- Slide number: 3 -->
# 四半期推移

### Notes:
発表者ノート: Q2の売上は385億円で過去最高。Q3・Q4は既存顧客の契約更新と新規受注見込みからさらなる成長を見込んでいる。
<!-- Slide number: 4 -->
# 主要KPI
| 指標 | 目標 | 実績 |
| --- | --- | --- |
| 売上高 | 350億円 | 385億円 |
| 営業利益率 | 15% | 17.2% |
| 顧客満足度 | 4.0以上 | 4.3 |
<!-- Slide number: 5 -->
# 次期の課題
最重要課題: 製造業向けLLMの精度向上
・学習データの拡充(目標: +200万件)
・RAG基盤のマルチテナント化
・顧客別ファインチューニングの自動化
観察ポイント
| 要素 | 結果 | 備考 |
|---|---|---|
| スライド区切り |
<!-- Slide number: N --> で明示 |
非常に嬉しい機能 |
| スライドタイトル |
# に変換 |
|
| 発表者ノート | ### Notes: として保持される |
これは大きな価値 |
| 画像 |
 形式で参照 |
中身の説明はなし(LLM連携時のみ付く) |
| 表 | 正確にMarkdown表化 | |
| 箇条書きの階層 | フラット化して消える | レベル0/1の区別なし |
・ の箇条書き |
通常の文字扱い | Markdownの - に変換されない |
| 太字・色装飾 | 失われる |
最重要課題: の太字・赤が消えた |
発表者ノートが保持されるのは大きな価値です。プレゼン資料をRAGに食わせるとき、スライドの要約が発表者ノートに書かれている会社は多く、この情報を取り込めるかは変換品質の差に直結します。
注意: 日本語の中黒箇条書き ・ はMarkdown記法に変換されない。スライド資料を作るとき、・ を使うか - を使うかで変換結果が変わります。RAG前提なら PowerPoint の「箇条書きスタイル」を使うか、本文を - で始める運用が安全。
4.4 PDF - reportlabで生成した日本語PDF
入力: WordやExcelと同内容のPDF(reportlabで生成)。見出し・表・箇条書き・番号リスト・注釈を含む
変換結果
2025年度 第2四半期 事業報告書
本報告書は、2025年度第2四半期(7月〜9月)における当社の事業活動および業績についてまとめたもの
である。
1. 売上概況
第2四半期の売上高は前年同期比12.3%増の38億5,000万円となった。主力のAIソリューション事業が
好調に推移したほか、新規事業であるメタバース関連サービスが本格的な収益貢献を開始したことが要
因である。
1.1 事業セグメント別売上
| セグメント | 売上高(百万円) | 前年比 | |
| --------- | -------- | ----- | ------ |
| AIソリューション | | 2,150 | +18.5% |
| メタバース | | 480 | 新規 |
| 受託開発 | | 980 | -3.2% |
| 保守運用 | | 240 | +5.1% |
1.2 主要な取り組み
(cid:127) 大手製造業A社向けAIエージェント基盤の本番稼働開始
(cid:127) VRM形式対応メタバース展示会プラットフォームのリリース
(cid:127) 社内向け生成AIガイドライン「AI四原則」の策定および公開
(cid:127) 海外拠点(シンガポール)における現地採用の強化
2. 次四半期の重点施策
第3四半期に注力する施策を優先度順に示す。
1 AIエージェント基盤のマルチテナント化完了
2 製造業向け業種特化LLMのPoC開始
3 メタバース展示会の常設会場オープン
※ 本資料に記載の見通しは現時点の情報に基づくものであり、...
観察ポイント
| 要素 | 結果 | 備考 |
|---|---|---|
| 見出し | すべてプレーンテキスト化 |
# が付かない(PDFの見出し情報は抽出できない) |
| 本文 | 保持 | ただし元の改行がそのまま残る |
| 表 | ヘッダ行の列数とデータ行の列数がズレる | 列がシフトしてしまう |
• 記号 |
(cid:127) として漏出 |
フォント埋め込みの問題 |
| 番号リスト | 番号と本文のスペースが失われる |
1 AI... のように詰まる |
| 注釈 | プレーンテキストに |
結論: PDFは一番厳しい。reportlab/TeX/InDesignなど生成元が何であっても、PDFから構造情報(見出し階層・表のヘッダ・リスト情報)を取り出すのはそもそも難しい問題です。MarkItDownは内部的に pdfminer.six を使っていて、これは「テキストを抽出する」までが責任範囲で、「見出しかどうかを判定する」までは踏み込みません。
対策の優先順位:
- 元がWord/PowerPoint/Excelで存在するなら、そちらを直接変換する(PDFを経由しない)
- 元PDFしかない場合は Azure Document Intelligence を併用(
-d -e <endpoint>) - スキャンPDFなら
markitdown-ocrプラグインを検討 -
(cid:xxx)問題は元PDFのフォント埋め込みサブセット化が原因。生成側を直せるなら直す
5. 検証から見えた日本語文書変換の傾向と対策
検証結果を総合すると、以下の傾向が見えます。
品質ランキング(日本語文書)
| 形式 | 総合品質 | 一言コメント |
|---|---|---|
| Word(.docx) | ★★★★☆ | 見出し・リストは正確。表ヘッダだけ要注意 |
| PowerPoint(.pptx) | ★★★★☆ | スライド区切り・発表者ノートが嬉しい。階層箇条書きは失われる |
| Excel(.xlsx) | ★★★☆☆ | シート分割は良い。結合セル・数式は情報を失う |
| ★★☆☆☆ | 見出しが消え、表の列がズレる。可能な限り元形式を使え |
RAG前処理としてMarkItDownを使う際の推奨パイプライン
- 元形式を可能な限り維持してMarkItDownに渡す(PDFではなく.docxで)
- Excelは結合セルを解除して値を複製してから変換
- PowerPointの発表者ノートは本文と同等に扱う(LLMへのコンテキストとして有用)
- PDF必須の場合はAzure Document Intelligenceを併用
- 変換後のMarkdownは一度目視確認。自動化前のサンプリングは必須
6. プラグインと拡張
Azure Document Intelligence
スキャンPDFや複雑なレイアウトPDF向け。
markitdown path-to-file.pdf -o document.md -d -e "<endpoint>"
Python API:
from markitdown import MarkItDown
md = MarkItDown(docintel_endpoint="<endpoint>")
result = md.convert("test.pdf")
LLMによる画像説明
pptxと画像ファイルに対して、LLMで説明文を生成できます。
from markitdown import MarkItDown
from openai import OpenAI
client = OpenAI()
md = MarkItDown(
llm_client=client,
llm_model="gpt-4o",
llm_prompt="画像の内容を日本語で簡潔に説明してください"
)
result = md.convert("presentation.pptx")
print(result.text_content)
これを使うと、PowerPointのグラフ画像やスクリーンショットに対してLLMが自動でキャプションを付けてくれます。RAG用途で効く機能。
markitdown-ocrプラグイン
PDF/DOCX/PPTX/XLSXに埋め込まれた画像に対してLLM VisionでOCRをかけるプラグイン。本体と同じ llm_client / llm_model パターンで使えます。
MCPサーバ
Claude Desktop や Zed Editor などの MCP クライアントからダイレクトに呼び出せます。
pip install markitdown-mcp
Claude Desktop設定例:
{
"mcpServers": {
"markitdown": {
"command": "markitdown-mcp"
}
}
}
7. つまずきポイント集
Python 3.9以下で pip install が失敗
python --version
3.10未満ならバージョンアップ。uv python install 3.12 が速い。
convert_stream で落ちる
v0.1.0の破壊的変更で、バイナリストリームのみ受け付けます。io.BytesIO か open(path, "rb") を使うこと。
PDFで (cid:NNN) が出る
元PDFのフォントサブセット化が原因で、Unicodeへの逆変換情報が失われているケース。
- 元ファイル(Word等)があればそちらを使う
- ocrmypdfで再処理してから渡す
- Azure Document Intelligenceを使う
Excelの結合セル対策コード例
from openpyxl import load_workbook
from copy import copy
def unmerge_and_fill(path):
wb = load_workbook(path)
for ws in wb.worksheets:
merged_ranges = list(ws.merged_cells.ranges)
for merged_range in merged_ranges:
min_col, min_row, max_col, max_row = merged_range.bounds
top_left_value = ws.cell(row=min_row, column=min_col).value
ws.unmerge_cells(str(merged_range))
for row in range(min_row, max_row + 1):
for col in range(min_col, max_col + 1):
ws.cell(row=row, column=col, value=top_left_value)
wb.save(path.replace('.xlsx', '_flat.xlsx'))
unmerge_and_fill('sales.xlsx')
# → sales_flat.xlsx をMarkItDownに食わせる
音声変換でffmpegが足りない
# macOS
brew install ffmpeg
# Ubuntu
sudo apt-get install ffmpeg
8. まとめ
- MarkItDownは「LLM時代の
textract」。RAG/LLM前処理用途で元形式が Word/PowerPoint/Excel ならまず第一候補 - PDFは鬼門。可能な限り元形式を使うこと。必要なら Azure Document Intelligence 併用
- Excelは 結合セル・数式に注意。事前処理で平坦化するのが実務的
- PowerPointは 発表者ノートまで取り込めるのが地味に大きい
- v0.1.0の破壊的変更により
convert_stream()はバイナリストリーム必須 - MCPサーバ版もあり、Claude Desktop等からも使える
参考リンク
- 公式リポジトリ: https://github.com/microsoft/markitdown
- PyPI: https://pypi.org/project/markitdown/
- MCPサーバパッケージ: https://github.com/microsoft/markitdown/tree/main/packages/markitdown-mcp
- Azure Document Intelligence: https://learn.microsoft.com/en-us/azure/ai-services/document-intelligence/
- Model Context Protocol: https://modelcontextprotocol.io
- 本記事の検証用サンプル生成スクリプト(GitHub Gist): https://gist.github.com/mayochan32/ffd968587ca22dc5bc96ad912930c541