はじめに
WordやExcel、PDFの仕様書や資料の差分を知りたい時がよくあります。ひとまず、テキスト部分のみでいいので比較したいのです。この記事は仕事中の自分に向けた記事です。
高機能なドキュメントパーサー「Docling」を使えば、これらをMarkdownへ変換できます。
今回は「社内PCがそこまで高スペックではない」「セキュリティの都合上、一度モデルを落とした後は完全ローカル(オフライン)で動かしたい」「画像の解析(OCRやレイアウト抽出)は重いのでスキップしたい」という実務向けのわがまま環境を想定した変換スクリプトを作成しました。
対象読者
- 会社のPCスペックがそこまで高くない環境でドキュメントをパースしたい方
- 外部APIやクラウドを使わず、機密性の高い社内文書をローカル環境だけで処理したい方
- ドキュメント同士のテキスト比較(Diff)のためにMarkdownへ落とし込みたい方
環境構築
事前に必要なライブラリをインストールしておきます。
pip install docling
私が試したdoclingのバージョンは2.88.0でした
一度インターネットに接続できる環境でモデルを事前に以下のコマンドでキャッシュディレクトリ等にダウンロードしておき、それをローカル環境のフォルダ(例: ./docling/models)に配置して使用します。
docling-tools models download -o ./docling/models
スクリプト全文
以下のコードを convert_doc.py などの名前で保存して使用します。
import os
import sys
# PYTHONUTF8 が有効でなければ、環境変数を付けて自分自身を再起動する
if os.name == "nt" and os.environ.get("PYTHONUTF8") != "1":
os.environ["PYTHONUTF8"] = "1"
# 現在の実行引数そのまま、自分自身を再起動(現在のプロセスを置き換え)
os.execv(sys.executable, [sys.executable] + sys.argv)
import argparse
# huggingfaceのimport前に設定する
os.environ["TRANSFORMERS_OFFLINE"] = "1"
os.environ["HF_HUB_OFFLINE"] = "1"
os.environ["HF_DATASETS_OFFLINE"] = "1"
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions
from docling.document_converter import (
DocumentConverter,
ExcelFormatOption,
PdfFormatOption,
PowerpointFormatOption,
WordFormatOption,
)
def main():
# コマンドライン引数の解析
parser = argparse.ArgumentParser(
description="Doclingを使ってファイルをMarkdownに変換し、ファイルに保存します。"
)
parser.add_argument(
"input_file", type=str, help="変換する入力ファイルのパス(PDF, DOCX, PPTX, XLSX)"
)
parser.add_argument(
"output_file", type=str, help="出力するMarkdownファイルのパス(例: output.md)"
)
# 引数に --formula または -f を追加
parser.add_argument(
"--formula", "-f", action="store_true", help="数式認識を有効化します(処理時間が長くなります)"
)
args = parser.parse_args()
source = args.input_file
output_path = args.output_file
# 入力ファイルの存在確認
if not os.path.exists(source):
print(f"エラー: 入力ファイルが見つかりません: {source}", file=sys.stderr)
sys.exit(1)
artifacts_path = "./docling/models"
pdf_pipeline_options = PdfPipelineOptions(
artifacts_path=artifacts_path,
do_ocr = False,
do_formula_enrichment=args.formula,
)
doc_converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(pipeline_options=pdf_pipeline_options),
InputFormat.DOCX: WordFormatOption(pipeline_options=pdf_pipeline_options),
InputFormat.PPTX: PowerpointFormatOption(
pipeline_options=pdf_pipeline_options
),
InputFormat.XLSX: ExcelFormatOption(pipeline_options=pdf_pipeline_options),
}
)
try:
# 変換処理
print(f"変換中: {source} -> {output_path} ...")
conversion_result = doc_converter.convert(source)
doc = conversion_result.document
# Markdownテキストの生成
markdown_content = doc.export_to_markdown(image_placeholder="")
# ファイルへの書き込み(文字コードはUTF-8を指定)
with open(output_path, "w", encoding="utf-8") as f:
f.write(markdown_content)
print(f"成功: {output_path} に保存したよ!")
except Exception as e:
print(f"変換中またはファイル書き込み中にエラーが発生しました: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
2026/07/15 注: PdfPipelineOptionsをdocx,xlsx,pptxでも使っているのはおかしい気がする...
使い方
コマンドラインから以下のように入力ファイルと出力ファイルのパスを指定して実行します。
python convert_doc.py input.docx output.md
コードのポイント
-
環境変数の事前定義による完全オフライン化
from docling...などのインポートが行われる前にos.environで各種ライブラリ(Hugging Faceなど)のオフラインフラグを1に設定している。これにより、スクリプト実行時に外部への無駄なネットワーク通信やモデルの再チェックを走らせないように制限できる。 -
artifacts_pathによるローカルモデルの固定
PdfPipelineOptions(artifacts_path="./docling/models")で、モデルファイルが置いてあるパスを明示的に指定している。環境をクローズドな環境にデプロイする際にも役立つ構成。 -
image_placeholder=""で画像をスキップ
Markdown出力時のexport_to_markdown(image_placeholder="")の指定により、ドキュメント内の画像を無駄に埋め込んだりパースしたりせず、テキストベースの綺麗なMarkdownのみを抽出できるため、動作が非常に軽量になる。
まとめ
このスクリプトで生成されたMarkdown同士をDiffツールにかければ、WordやExcelのどこが修正されたのか一目瞭然になる(のかな?)ので、仕様書の更新履歴チェックなどに大活躍するはず!(といいな...)
参照元
更新履歴
2026/07/23: -f オプションで数式対応(pdfのみで確認)
2026/07/18:
変数名が間違っていたところ修正
do_ocr = False 追加
試したdoclingのバージョン明記
2026/07/15: モデルをダウンロードするコマンド追加 (モデルいりますよね...)
2026/07/12: 初版公開