3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WinMergeでMS Officeファイルを比較するプラグイン(MarkItDown版)

Last updated at Posted at 2025-12-03

はじめに

WinMergeでMicrosoft Office、PDF、その他のドキュメントファイルを比較するためのプラグイン「markitdown.sct」を作成しました。

winmerge_markitdown_plugin.png

WinMergeでバイナリファイルを比較するためには、テキストファイルに変換する手順が必要です。
Officeドキュメントのテキストファイル変換で、従来のxdocdiff WinMerge Pluginの代わりに、MicrosoftのMarkItDownを使用してOfficeドキュメントをMarkdown形式に変換します。

なぜ作ったのか?

Officeドキュメントの変更管理、どうしていますか?

昨今のOfficeドキュメントは、単なるドキュメントにとどまらず、システムの自動生成ソースとして利用されることも増えています。そのため、想定外の変更がシステムに予期せぬ影響を与えることがあります。

変更箇所の把握方法として、修正履歴を記載したり、吹き出しや文字色・セル色で目立たせたりする方法もありますが、これらは作成者の自己申告に依存しています。修正前のドキュメントを用意して全量を目視で突き合わせるのも現実的ではありません。

そこで有効なのが、xdocdiff WinMerge Pluginを使った機械的な比較です。Officeファイルの全量比較といえばこのツール。これまで何度もお世話になってきました。

導入時のもやもや

ただ、xdocdiff WinMerge Pluginをセットアップをするたびに、いくつかのもやもやがありました。

課題 内容
バージョン管理 複数フォーク版が存在、更新の自動化が困難
配布形式 個人サイトからの実行ファイルダウンロードが必要(参考リンク参照)
企業環境 個人開発ツールの導入にはセキュリティ審査が必要な場合も
セットアップ 実行ファイルの配置、パス設定など独自の手順が多い

MarkItDownとの出会い

そんなとき、生成AIで大活躍しているMicrosoft公式のMarkItDownを発見しました。

MarkItDownは、Microsoftが開発・公開しているドキュメント変換ツールです。

  • GitHub 8万スター超の人気プロジェクト
  • Office、PDF、画像、音声など幅広い形式をMarkdownに変換
  • pip install markitdown[all]で簡単インストール
  • Microsoftによる継続的なメンテナンス(Office形式の仕様変更にも追従が期待できる)

これなら企業環境でも導入しやすい!というわけで、xdocdiffの設計思想を引き継ぎつつ、MarkItDownベースのプラグインを作成しました。

生成AI時代のユースケース

MarkItDownは、生成AIとの連携で真価を発揮します:

ユースケース 説明
RAG(検索拡張生成) 社内ドキュメントをMarkdown化してベクトルDBに投入し、AIが検索・回答
MCP連携 MCPサーバーとして動作し、ローカルファイルを直接参照
コンテキスト提供 ChatGPTやCopilotにOffice文書の内容を正確に伝える
ドキュメント要約 大量の設計書やマニュアルをAIに読み込ませて要約・分析

具体例: 「この設計書の変更点を要約して」とAIに依頼するとき、MarkItDownで変換したMarkdownを渡せば、表構造や見出し階層を維持したまま正確に伝わります。

本プラグインは、このMarkItDownをWinMergeの差分比較に活用したものです。

xdoc2txtとの比較

xdocdiff系プラグインは内部でhishida様のxdoc2txtを使用しています。本プラグインはこれをMarkItDownに置き換えたものです。両者の違いを比較します。

比較結果の見た目

以下のようなExcelファイルを比較してみます。

比較対象のExcelファイル(左: 修正前、右: 修正後)

excel_source_compare.png

今回作成したMarkItDownプラグイン(Markdown形式)

winmerge_markitdown_compare.png

大量のNaNが出力されていますがMarkdown形式になっています。Excel方眼紙の場合はさらに大量のNaNが出力されます。
Excelの表構造も無視されており、人間が見るには厳しいと言わざるをえません。

百戦錬磨のxdoc2txtプラグイン(テキスト形式)

winmerge_xdoc2txt_compare.png

すっきりしていて見やすいですね。設計書であればどこに何が書いてあるかを把握しているので、人間が見るにはこれで十分です。

WinMerge同梱の公式プラグインであるCompareMS~Files.sct

WinMerge同梱の公式プラグインとして、Excel/Word/PowerPoint/Visioそれぞれ専用のプラグインが用意されていますので、こちらにも言及します。
Office COMオートメーション経由で高精度な抽出が可能ですが、対応Officeアプリのインストールが必要で、大きなファイルでは処理に時間がかかります。

この処理速度と安定性がネックで私は利用していません。

winmerge_compmsoffice_compare.png
セルの位置が再現されており、変更箇所が直感的にわかります。

CompareMSExcelFiles.png
プラグインオプションも豊富で、かゆいところに手が届きそうです。

機能比較表

項目 xdoc2txt MarkItDown CompareMS~Files.sct
開発元 個人開発 Microsoft WinMerge公式
配布形式 実行ファイル pip install WinMerge同梱
出力形式 プレーンテキスト Markdown TSV(セル単位)
処理速度 🚀 爆速 (2秒) 普通 (15秒) 🐌 かなり遅い (2分45秒)
人間向け ⭕ 見やすい ❌ NaN地獄 ⭕ 非常に見やすい
AI向け ⭕ Markdown形式
Office対応 ✅ (Visioにも対応!)
PDF対応

※処理速度は15MBのExcelファイルを比較した場合の参考値(環境により異なります)

MarkItDownの処理速度について(正直な話)

MarkItDownはxdoc2txtより明らかに遅いです。 その理由は以下の通りです。

  1. 起動オーバーヘッド: Pythonインタプリタの起動とライブラリ読み込みに0.5〜1秒かかる
  2. PDF解析: 純Python製ライブラリ(pdfminer.six)を使用しているため遅い
  3. 処理の複雑さ: テキスト抽出だけでなく、Markdown構造への変換処理も行っている

どちらを選ぶべきか?

処理速度のネックから、CompareMS~Files.sctは除外する。

利用者 推奨 理由
🧑 人間 xdoc2txt 爆速+見やすい
🤖 AI MarkItDown Markdown形式で構造化
🏢 企業環境 MarkItDown Microsoft公式ツール、pipで導入可能

正直なところ: xdoc2txt、MarkItDownのどちらの変換テキストも、人間が利用する場合において100点ではありません。WinMergeの差分比較だけでは完結せず、Officeドキュメントをアプリで開いて目視での確認が必要です。

であれば、普段は処理速度が🚀 爆速なxdocdiffPlugin64を使い、AIにOffice文書の変更内容を正確に伝えたいときだけmarkitdown.sctに切り替えるのがおすすめです。


それでは、MarkItDown版プラグインのセットアップ手順について説明していきます。

対応ファイル形式

対応形式

カテゴリ 拡張子
Microsoft Office .doc, .docx, .docm, .xls, .xlsx, .xlsm, .ppt, .pptx, .pptm
PDF .pdf
その他 .rtf, .epub, .eml

除外した形式(理由あり)

形式 除外理由
CSV/JSON プレーンテキスト比較の方が見やすい
HTML/XML タグ構造が重要なので、そのまま比較すべき
ZIP 中身が全展開されて逆に見づらい

注意: OpenDocument形式(.odtなど)や一太郎(.jtd)には対応していません。

セットアップ手順(5分で完了)

前提条件

  • Python 3.10以上がインストールされていること
  • WinMergeがインストールされていること

ステップ1: MarkItDownのインストール

PowerShellで以下を実行:

pip install markitdown[all]

重要⚠️: [all]を忘れずに。これがないとExcel/Word/PowerPointの変換でエラーが発生します。

ステップ2: プラグインファイルの配置

markitdown.sctを以下に配置(管理者権限が必要):

C:\Program Files\WinMerge\MergePlugins\markitdown.sct

ステップ3: 動作確認

  1. WinMergeを起動
  2. メニュー: プラグインプラグインの設定
  3. リストにmarkitdownが表示されていればOK
  4. markitdownのチェックボックスをオンにしてプラグインを有効にする。(amb_xdocdiffpluginを利用している場合はチェックボックスをオフにすることを推奨)
  5. ファイルフィルターは自動で設定されます。プラグイン引数は空欄で

winmerge_plugin_setting.png

ソースコード

markitdown.sct(クリックで展開)
markitdown.sct
<scriptlet>
<implements type="Automation" id="dispatcher">
	<property name="PluginEvent">
		<get/>
	</property>
	<property name="PluginDescription">
		<get/>
	</property>
	<property name="PluginFileFilters">
		<get/>
	</property>
	<property name="PluginIsAutomatic">
		<get/>
	</property>
	<method name="UnpackFile"/>
	<method name="PackFile"/>
	<method name="ShowSettingsDialog"/>
</implements>

<script language="VBS">

'/////////////////////////////////////////////////////////////////////////////
'    This is a plugin for WinMerge.
'    Copyright (C) 2025 @ishikawa-oniisan
'
'    Based on xdocdiffU.sct:
'      Copyright (C) 2020 stonee
'
'    Original xdocdiff WinMerge Plugin:
'      http://freemind.s57.xrea.com/xdocdiffPlugin/
'
'    Original xdocdiffPlugin64:
'      http://crus.mydns.jp/xdocdiffPlugin64/
'
'    This version uses MarkItDown (https://github.com/microsoft/markitdown)
'    instead of xdoc2txt.exe for file conversion.
'
'    This program is free software; you can redistribute it and/or modify
'    it under the terms of the GNU General Public License as published by
'    the Free Software Foundation; either version 2 of the License, or
'    (at your option) any later version.
'
'    This program is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'    GNU General Public License for more details.
'
'    You should have received a copy of the GNU General Public License
'    along with this program; if not, see <https://www.gnu.org/licenses/>.
'
Option Explicit

Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
Dim wsh: Set wsh = CreateObject("WScript.Shell")

Function get_PluginEvent()
	get_PluginEvent = "FILE_PACK_UNPACK"
End Function

Function get_PluginDescription()
	get_PluginDescription = "Display the text content of MS Word, Excel, PowerPoint and other office files as Markdown. (via MarkItDown)"
End Function

Function get_PluginFileFilters()
	' MarkItDown supports: PDF, PowerPoint, Word, Excel, EPUB, Email
	' Note: CSV, JSON, HTML, XML are excluded as they are better compared as plain text
	' Note: ZIP is excluded as it expands all contents making comparison harder
	' Note: MHT is excluded as HTML structure is lost during conversion
	' Note: Legacy Japanese formats (Ichitaro, OASYS) and OpenDocument formats are NOT supported
	get_PluginFileFilters = "\.pdf;\.docx;\.docm;\.doc;\.xlsx;\.xlsm;\.xls;\.pptx;\.pptm;\.ppt;\.rtf;\.epub;\.eml$"
End Function

Function get_PluginIsAutomatic()
	get_PluginIsAutomatic = True
End Function

Function UnpackFile(fileSrc, fileDst, pbChanged, pSubcode)
	On Error Resume Next
	
	' Check if source file exists
	If Not fso.FileExists(fileSrc) Then
		UnpackFile = False
		Exit Function
	End If
	
	' Create empty destination file first to avoid timing issues
	' (This addresses the same issue mentioned in the original xdocdiffU.sct)
	Dim objFile: Set objFile = fso.CreateTextFile(fileDst, True)
	If Err.Number <> 0 Then
		UnpackFile = False
		Exit Function
	End If
	objFile.WriteLine ""
	objFile.Close
	Set objFile = Nothing
	
	' Execute MarkItDown to convert file to Markdown
	' Use UTF-8 encoding for output (consistent with xdocdiffU.sct's UTF-8 modification)
	' MarkItDown outputs UTF-8 by default, so we redirect stdout to the destination file
	Dim cmd
	' Note: In VBScript/WSH, we use & instead of && for command chaining in cmd.exe
	cmd = "cmd /c ""chcp 65001 >nul & markitdown """ & fileSrc & """ > """ & fileDst & """ 2>&1"""
	
	Dim result
	result = wsh.Run(cmd, 0, True)
	
	If Err.Number <> 0 Then
		UnpackFile = False
		Exit Function
	End If
	
	' Check if conversion was successful by verifying the output file has content
	If fso.FileExists(fileDst) Then
		Dim fileSize
		fileSize = fso.GetFile(fileDst).Size
		If fileSize > 0 Then
			pbChanged = True
			pSubcode = 0
			UnpackFile = True
		Else
			' If file is empty, conversion failed
			pbChanged = False
			pSubcode = 0
			UnpackFile = False
		End If
	Else
		pbChanged = False
		pSubcode = 0
		UnpackFile = False
	End If
	
	On Error Goto 0
End Function

Function PackFile(fileSrc, fileDst, pbChanged, pSubcode)
	' Packing is not supported (read-only plugin)
	PackFile = False
End Function

Function ShowSettingsDialog()
	MsgBox "This plugin converts Office files to Markdown using MarkItDown." & vbCrLf & vbCrLf & _
	       "Supported formats:" & vbCrLf & _
	       "- Microsoft Office: Word, Excel, PowerPoint" & vbCrLf & _
	       "- PDF documents" & vbCrLf & _
	       "- EPUB (eBooks)" & vbCrLf & _
	       "- Email: .eml" & vbCrLf & _
	       "- RTF documents" & vbCrLf & vbCrLf & _
	       "Excluded: CSV, JSON, HTML, XML, ZIP, MHT" & vbCrLf & _
	       "(better compared as plain text or binary)" & vbCrLf & vbCrLf & _
	       "Requirements:" & vbCrLf & _
	       "- markitdown must be installed and in PATH" & vbCrLf & _
	       "  (Install with: pip install markitdown[all])", _
	       vbInformation, "MarkItDown Plugin"
End Function

</script>

</scriptlet>

実装の詳細

技術的な詳細(クリックで展開)

既存プラグインとの比較

元のxdocdiffPlugin64のソースコード(C++)を掘り起こして確認したところ、以下の実装になっていました:

// xdoc2txtの呼び出し
tsxdoc2txtParam = L"xdoc2txt -f " + tsxdoc2txtParam;
::CreateProcess(NULL, xdoc2txtParam, NULL, NULL, NULL, 
                CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS, 
                NULL, NULL, &si, &pi);

一方、xdocdiffU.sctでは以下のように実装されていました(VBScriptだとシンプル!):

cmd = "cmd /c xdoc2txt.exe -i -8 """ & fileSrc & """ > """ & fileDst & """"

本プラグイン(markitdown.sct)では、xdocdiffU.sctの方針(標準出力リダイレクト、UTF-8明示)を踏襲しています:

cmd = "cmd /c ""chcp 65001 >nul & markitdown """ & fileSrc & """ > """ & fileDst & """ 2>&1"""

ポイント:

  • chcp 65001: UTF-8コードページに切り替え(文字化け対策)

  • 2>&1: 標準エラーもキャッチ(エラーメッセージを見逃さない)

  • 引用符のエスケープ地獄(VBScriptあるある)

ファイル生成タイミングの制御

WinMergeのプラグインAPIでは、変換処理中に出力ファイルの存在をチェックする場合があります。特にネットワークドライブ上のファイルを処理する際、変換完了前にチェックが実行されるとエラーになる可能性があります。

対策: 変換処理の前に空ファイルを作成

' Create empty destination file first to avoid timing issues
Dim objFile: Set objFile = fso.CreateTextFile(fileDst, True)
objFile.WriteLine ""
objFile.Close
Set objFile = Nothing

この実装により、WinMerge側の存在チェックが成功し、安定した動作が実現できます。

この手法は、stonee様のxdocdiffU.sctの記事で紹介されている不具合対処方法を参考にしています。

エラー処理の強化(信頼性向上)

変換失敗を確実に検出するため、以下の確認処理を実装しています:

' Check if conversion was successful by verifying the output file has content
If fso.FileExists(fileDst) Then
	Dim fileSize
	fileSize = fso.GetFile(fileDst).Size
	If fileSize > 0 Then
		pbChanged = True
		pSubcode = 0
		UnpackFile = True
	Else
		' If file is empty, conversion failed
		pbChanged = False
		pSubcode = 0
		UnpackFile = False
	End If
End If

ポイント:

  • 変換後のファイルが0バイトでないかを確認
  • 変換失敗時に「変更なし」と誤認されるのを防止
  • より確実なエラー検出により、安定した動作を実現

文字エンコーディング(地味に重要)

  • 出力: UTF-8 (BOMなし) ← 標準的
  • コマンドプロンプト: UTF-8 (chcp 65001) ← 文字化け防止
  • MarkItDownはデフォルトでUTF-8出力 ← ナイス設計

トラブルシューティング

症状 原因 解決方法
MarkItDownが見つからない PATHが通っていない Get-Command markitdownで確認
FileConversionException [all]なしでインストール pip install markitdown[all]で再インストール
変換エラー 原因不明 コマンドラインで直接テスト: markitdown "test.docx"
日本語が文字化け(ほとんど起きないはず) WinMergeの設定 オプション → コードページ → UTF-8

最頻出エラー: FileConversionException

以下のエラーが出たら、[all]付きで再インストール:

pip uninstall markitdown
pip install markitdown[all]

さいごに

本プラグインは、stonee様のxdocdiffU.sctのコードを参考に(というかほぼ流用して)作成しました。xdocdiff WinMerge Pluginという偉大な先人のツールがなければ、このアイデアは生まれませんでした。開発者の皆様に感謝します。

毎日、大量のレビュー依頼を捌かなければならないが、量との戦いで質を下げたくない。
そういう人に読んでいただきたいと思って執筆しました。

Excel設計書やWordドキュメントの変更箇所を瞬時に全量把握する手段があるということが知られる機会になればと思います。

Happy Diffing! 🎉

ライセンス・参考リンク

ライセンス: GPL v2

参考リンク:


作成日: 2025-12-03
バージョン: 1.0

3
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?