ドキュメント比較 .net – 完全な GroupDocs 実装ガイド
If you need to compare documents .net, you’ve come to the right place. Imagine opening two contracts that look identical and instantly spotting every change—no manual scrolling, no missed edits. That’s the power of automated document comparison, and with GroupDocs.Comparison for .NET you can make it happen in minutes.
クイック回答
- .NET でドキュメント比較を処理するライブラリは何ですか? GroupDocs.Comparison.
- Word、Excel、PDF ファイルを比較できますか? はい—50 以上のフォーマットがサポートされています。
- どのバージョンを使用すべきですか? バージョン 25.4.0 が最高のパフォーマンスと安定性を提供します。
- 本番環境でライセンスが必要ですか? 本番展開には商用ライセンスが必要です。
- 非同期処理は可能ですか? もちろんです—比較 API と共に
Task.Runを使用します。
GroupDocs.Comparison とは?
GroupDocs.Comparison は、2 つ以上のドキュメント間の差分をプログラムで検出し、ハイライトされた結果ファイルを生成する .NET ライブラリです。50 以上のフォーマットをサポートし、全体をメモリに読み込まずに数百ページのファイルを処理でき、比較設定を細かく制御できます。
.NET でドキュメント比較に GroupDocs.Comparison を使用する理由
GroupDocs.Comparison は、.NET アプリケーション向けに高速で正確、かつスケーラブルなドキュメント差分機能を提供します。大容量の PDF や Office ファイルを数秒で処理し、書式やビジュアルの忠実度を保ちつつ、挿入、削除、スタイル変更をハイライトします。ライブラリは .NET Core、.NET 5/6/7、フル .NET Framework で動作し、あらゆるプロジェクトに柔軟に対応できます。
- 速度: 標準サーバーで 200 ページの PDF を 2 秒未満で処理します。
- 精度: テキスト、書式、表、画像を 99.9 % の忠実度で検出します。
- スケーラビリティ: ストリーミング API を使用して数千ファイルのバッチジョブを処理します。
- 柔軟性: .NET Core 3.1 以上、.NET 5/6/7、.NET Framework 4.6.1 以上で動作します。
前提条件
- 開発環境: .NET Core 3.1 以上、または .NET Framework 4.6.1 以上
- GroupDocs.Comparison ライブラリ: バージョン 25.4.0(NuGet 経由でインストール)
- サンプルファイル: テスト用の Word、PDF、Excel ドキュメント
- 基本的な C# 知識: クラス、メソッド、
using文
あれば尚良い(オプション)
- NuGet パッケージ管理に慣れていること
- ファイル I/O とストリームの経験
- async/await パターンの理解
GroupDocs.Comparison を使用して .NET でドキュメントを比較する方法
GroupDocs.Comparison を使用して 2 つのドキュメントを比較するには、各ファイルをストリームに読み込み、オプションの ComparisonSettings を構成し、Comparer インスタンスの Compare メソッドを呼び出します。API は差分をハイライトした結果ドキュメントを返し、任意のサポート形式で保存できます。このアプローチは数行のコードで実装でき、比較プロセス全体をフルコントロールできます。
手順実装
1️⃣ スマートドキュメントパス管理
Centralizing file paths prevents “file not found” errors and makes environment switches painless.
public static class Constants
{
public const string SOURCE_WORD = @"YOUR_DOCUMENT_DIRECTORY\source.docx";
public const string TARGET_WORD = @"YOUR_DOCUMENT_DIRECTORY\target.docx";
public static string GetOutputDirectoryPath()
{
return @"YOUR_OUTPUT_DIRECTORY";
}
public const string RESULT_WORD = "result.docx";
}
これが機能する理由:
- 開発、テスト、本番用のパスを一箇所で更新できます。
- コードベース全体に散在するハードコーディングされた文字列を排除します。
2️⃣ コア比較ロジック
The Comparer class is the engine that drives the diff algorithm.
using (Comparer comparer = new Comparer(Constants.SOURCE_WORD))
{
// Add the target document for comparison
comparer.Add(Constants.TARGET_WORD);
// Perform the comparison and save the result
string outputFileName = Path.Combine(Constants.GetOutputDirectoryPath(), Constants.RESULT_WORD);
comparer.Compare(outputFileName);
}
定義アンカー:Comparer は、ドキュメント解析を指揮し、ハイライトされた結果を生成する GroupDocs.Comparison のコアクラスです。
役割:
Add()呼び出しを繰り返すことで複数の対象ドキュメントをサポートします。- 変更が赤、緑、またはカスタムカラーでハイライトされた結果ファイルを生成します。
3️⃣ Excel と PDF の高度な設定
You can fine‑tune the comparison to ignore formatting or focus on data changes—perfect for compare excel files c# scenarios.
CompareOptions compareOptions = new CompareOptions()
{
ShowDeletedContent = true,
ShowInsertedContent = true,
StyleChangeDetection = true
};
using (Comparer comparer = new Comparer(sourcePath))
{
comparer.Add(targetPath);
comparer.Compare(outputPath, compareOptions);
}
定義アンカー:ComparisonSettings を使用すると、DetectStyleChanges や DetectTableChanges などの特定の変更タイプを有効化または無効化できます。
4️⃣ 複数フォーマットの処理
GroupDocs.Comparison は自動的にファイルタイプを検出しますが、必要に応じてフォーマットを強制指定することも可能です—compare pdf files c# に最適です。
public static void CompareDocumentsByType(string sourcePath, string targetPath, string outputPath)
{
string extension = Path.GetExtension(sourcePath).ToLower();
using (Comparer comparer = new Comparer(sourcePath))
{
comparer.Add(targetPath);
CompareOptions options = GetOptionsForFormat(extension);
comparer.Compare(outputPath, options);
}
}
private static CompareOptions GetOptionsForFormat(string extension)
{
switch (extension)
{
case ".pdf":
return new CompareOptions { DetectStyleChanges = false };
case ".xlsx":
return new CompareOptions { CalculateCoordinates = true };
default:
return new CompareOptions();
}
}
5️⃣ 大きなファイルのストリーミング
When processing massive documents, streaming avoids loading the entire file into memory.
// For files over 50MB, consider this approach
using (var sourceStream = File.OpenRead(sourcePath))
using (var targetStream = File.OpenRead(targetPath))
using (var comparer = new Comparer(sourceStream))
{
comparer.Add(targetStream);
comparer.Compare(outputStream);
}
6️⃣ 堅牢なエラーハンドリング
Never let a corrupted file crash your service; wrap calls in try‑catch blocks and log useful details.
try
{
using (Comparer comparer = new Comparer(sourcePath))
{
comparer.Add(targetPath);
comparer.Compare(outputPath);
}
}
catch (FileNotFoundException ex)
{
Console.WriteLine($"Document not found: {ex.FileName}");
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine($"Access denied: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Comparison failed: {ex.Message}");
}
ドキュメント比較のベストプラクティス
- 入力ファイルを検証して API 呼び出し前に未サポートのフォーマットを早期に検出します。
Path.Combineを使用してクロスプラットフォームのパス構築を行います(Pitfall #1 参照)。- 必要な変更タイプのみ有効化してパフォーマンスを向上させます(例:データ中心の Excel シートではスタイル検出を無効化)。
Comparerオブジェクトを速やかに破棄してネイティブリソースを解放します。
よくある落とし穴と回避方法
落とし穴 #1: パス区切り文字の問題
解決策: 常に Path.Combine() と Path.DirectorySeparatorChar を使用してパスを構築します。
// Wrong - will break on different operating systems
string path = "C:/Documents/source.docx";
// Right - works everywhere
string path = Path.Combine("C:", "Documents", "source.docx");
落とし穴 #2: 大きなファイルでのメモリ枯渇
解決策: 50 MB 超のファイルはストリーミングモードに切り替えます。
// For files over 50MB, consider this approach
using (var sourceStream = File.OpenRead(sourcePath))
using (var targetStream = File.OpenRead(targetPath))
using (var comparer = new Comparer(sourceStream))
{
comparer.Add(targetStream);
comparer.Compare(outputStream);
}
落とし穴 #3: 例外を無視する
解決策: 包括的な try‑catch ブロックを実装し、スタックトレースを記録します。
try
{
using (Comparer comparer = new Comparer(sourcePath))
{
comparer.Add(targetPath);
comparer.Compare(outputPath);
}
}
catch (FileNotFoundException ex)
{
Console.WriteLine($"Document not found: {ex.FileName}");
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine($"Access denied: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Comparison failed: {ex.Message}");
}
パフォーマンス最適化戦略
メモリ管理
可能な限り Comparer インスタンスを再利用し、比較後に Dispose() を呼び出します。
// Always dispose of resources properly
using (var comparer = new Comparer(sourcePath))
{
comparer.Add(targetPath);
comparer.Compare(outputPath);
// Comparer is automatically disposed here
}
// For batch processing, clear resources between comparisons
for (int i = 0; i < documentPairs.Count; i++)
{
using (var comparer = new Comparer(documentPairs[i].Source))
{
comparer.Add(documentPairs[i].Target);
comparer.Compare(documentPairs[i].Output);
}
// Force garbage collection every 10 documents if needed
if (i % 10 == 0)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
非同期処理
UI を応答性のある状態に保つため、バックグラウンドスレッドで比較を実行します。
public async Task<bool> CompareDocumentsAsync(string sourcePath, string targetPath, string outputPath)
{
return await Task.Run(() =>
{
try
{
using (var comparer = new Comparer(sourcePath))
{
comparer.Add(targetPath);
comparer.Compare(outputPath);
return true;
}
}
catch
{
return false;
}
});
}
人気の .NET フレームワークとの統合
ASP.NET Core Web API 統合
2 つのファイルを受け取り、差分結果を返す REST エンドポイントを公開します。
[ApiController]
[Route("api/[controller]")]
public class DocumentComparisonController : ControllerBase
{
[HttpPost("compare")]
public async Task<IActionResult> CompareDocuments([FromForm] IFormFile sourceFile, [FromForm] IFormFile targetFile)
{
if (sourceFile == null || targetFile == null)
return BadRequest("Both source and target files are required.");
var tempFolder = Path.GetTempPath();
var sourcePath = Path.Combine(tempFolder, sourceFile.FileName);
var targetPath = Path.Combine(tempFolder, targetFile.FileName);
var outputPath = Path.Combine(tempFolder, $"comparison_{Guid.NewGuid()}.pdf");
try
{
// Save uploaded files
using (var stream = new FileStream(sourcePath, FileMode.Create))
await sourceFile.CopyToAsync(stream);
using (var stream = new FileStream(targetPath, FileMode.Create))
await targetFile.CopyToAsync(stream);
// Perform comparison
using (var comparer = new Comparer(sourcePath))
{
comparer.Add(targetPath);
comparer.Compare(outputPath);
}
// Return the result file
var fileBytes = await System.IO.File.ReadAllBytesAsync(outputPath);
return File(fileBytes, "application/pdf", "comparison_result.pdf");
}
finally
{
// Clean up temp files
File.Delete(sourcePath);
File.Delete(targetPath);
File.Delete(outputPath);
}
}
}
Blazor コンポーネント統合
ブラウザで左右に比較を表示する再利用可能なコンポーネントを作成します。
@using GroupDocs.Comparison
@inject IJSRuntime JSRuntime
<div class="document-comparison">
<InputFile OnChange="HandleFileSelection" multiple />
<button @onclick="CompareDocuments" disabled="@(!CanCompare)">Compare Documents</button>
@if (comparisonResult != null)
{
<div class="result">
<a href="@comparisonResult" download="comparison_result.pdf">Download Result</a>
</div>
}
</div>
@code {
private List<IBrowserFile> selectedFiles = new();
private string comparisonResult;
private bool CanCompare => selectedFiles.Count == 2;
private async Task HandleFileSelection(InputFileChangeEventArgs e)
{
selectedFiles = e.GetMultipleFiles(2).ToList();
}
private async Task CompareDocuments()
{
if (selectedFiles.Count != 2) return;
// Implementation similar to Web API example
// Save files, compare, and generate result
}
}
実際のユースケース
シナリオ 1: 法務契約レビュー
法律事務所は、契約改訂間の追加、削除、書式変更を自動的にハイライトできます。
public class ContractReviewService
{
public ContractComparisonResult ReviewContract(string originalContract, string revisedContract)
{
var outputPath = Path.Combine(Path.GetTempPath(), $"contract_review_{DateTime.Now:yyyyMMddHHmmss}.docx");
var compareOptions = new CompareOptions
{
ShowDeletedContent = true,
ShowInsertedContent = true,
StyleChangeDetection = true,
WordsSeparatorChars = new[] { ' ', '.', ',', '!', '?' }
};
using (var comparer = new Comparer(originalContract))
{
comparer.Add(revisedContract);
comparer.Compare(outputPath, compareOptions);
}
return new ContractComparisonResult
{
OutputPath = outputPath,
HasChanges = File.Exists(outputPath),
ComparisonDate = DateTime.Now
};
}
}
シナリオ 2: スプレッドシートのバージョン管理
財務チームは、各ファイルを手動で開くことなく Excel モデルの変更を検出できます。
public class DocumentVersionControl
{
public void TrackDocumentChanges(string documentPath, string repositoryPath)
{
var versions = Directory.GetFiles(repositoryPath, "*.docx").OrderBy(f => f);
var latestVersion = versions.LastOrDefault();
if (latestVersion != null)
{
var comparisonPath = Path.Combine(repositoryPath, $"changes_{DateTime.Now:yyyyMMdd}.docx");
using (var comparer = new Comparer(latestVersion))
{
comparer.Add(documentPath);
comparer.Compare(comparisonPath);
}
// Archive the comparison for future reference
ArchiveComparison(comparisonPath);
}
}
private void ArchiveComparison(string comparisonPath)
{
// Implementation for archiving comparison results
var archivePath = Path.Combine(Path.GetDirectoryName(comparisonPath), "archive", Path.GetFileName(comparisonPath));
Directory.CreateDirectory(Path.GetDirectoryName(archivePath));
File.Move(comparisonPath, archivePath);
}
}
トラブルシューティングガイド
問題 1: “File format not supported”
解決策: サポートリスト(50+ フォーマット)とファイル拡張子を照合し、未サポートのタイプはまず PDF に変換します。
private static readonly HashSet<string> SupportedFormats = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
".docx", ".doc", ".pdf", ".xlsx", ".xls", ".pptx", ".ppt", ".txt", ".rtf"
};
public static bool IsFormatSupported(string filePath)
{
var extension = Path.GetExtension(filePath);
return SupportedFormats.Contains(extension);
}
問題 2: 大きなファイルでのメモリ問題
解決策: ストリーミングを有効にし、ファイルをチャンクで処理します。
public static void CompareLargeDocuments(string sourcePath, string targetPath, string outputPath)
{
var fileInfo = new FileInfo(sourcePath);
if (fileInfo.Length > 50 * 1024 * 1024) // 50MB threshold
{
// Use streaming approach
using (var sourceStream = File.OpenRead(sourcePath))
using (var targetStream = File.OpenRead(targetPath))
using (var outputStream = File.Create(outputPath))
using (var comparer = new Comparer(sourceStream))
{
comparer.Add(targetStream);
comparer.Compare(outputStream);
}
}
else
{
// Standard approach for smaller files
using (var comparer = new Comparer(sourcePath))
{
comparer.Add(targetPath);
comparer.Compare(outputPath);
}
}
}
問題 3: 空の比較結果
解決策: DetectFormattingChanges や DetectStyleChanges を切り替えて感度を上げます。
var compareOptions = new CompareOptions
{
DetectStyleChanges = true,
DiagramMasterSetting = new DiagramMasterSetting
{
UseSourceMaster = true,
CloneSourceMaster = true
},
OriginalSize = new Size(600, 800),
HeaderFootersComparison = true,
PaperSize = PaperSize.A4
};
よくある質問
Q: 一度に何件のドキュメントを比較できますか?
A: 繰り返し Add() 呼び出しで単一の Comparer インスタンスに複数の対象ドキュメントを追加できますが、大量バッチでは順次処理することを推奨します。
Q: GroupDocs.Comparison はパスワード保護されたファイルを扱えますか?
A: はい—Comparer の構築時またはドキュメント読み込み時にパスワードを渡します。
using (var comparer = new Comparer(sourcePath, new LoadOptions("password")))
{
comparer.Add(targetPath, new LoadOptions("targetPassword"));
comparer.Compare(outputPath);
}
Q: GroupDocs.Comparison がサポートするファイル形式は何ですか?
A: DOCX、XLSX、PPTX、PDF、JPEG、PNG、TXT など、50 以上の形式をサポートします。
Q: 変更の外観をカスタマイズするには?
A: ComparisonSettings を使用して InsertedColor、DeletedColor、StyleChangeColor を設定します。
var compareOptions = new CompareOptions
{
InsertedItemStyle = new StyleSettings
{
HighlightColor = Color.Green,
FontColor = Color.DarkGreen
},
DeletedItemStyle = new StyleSettings
{
HighlightColor = Color.Red,
FontColor = Color.DarkRed
}
};
Q: 特定の変更タイプを無視できますか?
A: もちろんです—ComparisonSettings で DetectStyleChanges や DetectTableChanges などのオプションを無効化します。
var compareOptions = new CompareOptions
{
DetectStyleChanges = false, // Ignore formatting changes
HeaderFootersComparison = false, // Skip headers/footers
WordsSeparatorChars = new[] { ' ', '\n', '\r', '\t' } // Define word boundaries
};
Q: クラウドストレージに保存されたドキュメントを比較できますか?
A: はい—ストリームをローカルにダウンロードするか、MemoryStream から直接比較します。
using (var sourceStream = await DownloadFromCloudAsync(sourceUrl))
using (var targetStream = await DownloadFromCloudAsync(targetUrl))
using (var comparer = new Comparer(sourceStream))
{
comparer.Add(targetStream);
comparer.Compare(outputStream);
}
Q: Docker コンテナ内で GroupDocs.Comparison を実行するには?
A: Dockerfile に必要なネイティブ依存関係を含め、ライセンスファイルをコンテナにコピーします。
FROM mcr.microsoft.com/dotnet/aspnet:6.0
# Install necessary fonts and libraries for document processing
RUN apt-get update && apt-get install -y libfontconfig1 libfreetype6
Q: 本番環境で必要なライセンスは?
A: 本番展開には商用の GroupDocs.Comparison ライセンスが必須です。開発者、サイト、OEM ライセンスなどのオプションがあります。
Q: 比較失敗を優雅に処理するには?
A: 比較呼び出しを try‑catch ブロックでラップし、例外を記録してユーザーに優しいエラーメッセージを返します。
public async Task<ComparisonResult> CompareDocumentsWithRetry(string source, string target, int maxRetries = 3)
{
for (int attempt = 1; attempt <= maxRetries; attempt++)
{
try
{
using (var comparer = new Comparer(source))
{
comparer.Add(target);
var outputPath = GenerateOutputPath();
comparer.Compare(outputPath);
return new ComparisonResult { Success = true, OutputPath = outputPath };
}
}
catch (Exception ex) when (attempt < maxRetries)
{
_logger.LogWarning($"Comparison attempt {attempt} failed: {ex.Message}. Retrying...");
await Task.Delay(TimeSpan.FromSeconds(attempt * 2)); // Exponential backoff
}
catch (Exception ex)
{
_logger.LogError(ex, $"Comparison failed after {maxRetries} attempts");
return new ComparisonResult { Success = false, Error = ex.Message };
}
}
return new ComparisonResult { Success = false, Error = "Max retries exceeded" };
}
必要なリソースとドキュメント
- 完全なドキュメント: GroupDocs Comparison .NET Docs
- API リファレンスガイド: GroupDocs API Reference for .NET
- コミュニティサポートフォーラム: GroupDocs Forum
- 最新リリースのダウンロード: Releases Page
- 無料トライアルダウンロード: Try Free Version
- 一時ライセンス申請: Apply for Temporary License
- フルライセンス購入: Buy GroupDocs License
- リリース: Releases
- 一時ライセンスページ: Temporary License Page
- 購入ページ: Purchase Page
最終更新日: 2026-06-10
テスト環境: GroupDocs.Comparison 25.4.0 for .NET
作者: GroupDocs
Install-Package GroupDocs.Comparison -Version 25.4.0
dotnet add package GroupDocs.Comparison --version 25.4.0
using GroupDocs.Comparison;