比較文件 .net – 完整 GroupDocs 實作指南

如果您需要 compare documents .net,您來對地方了。想像一下打開兩份看起來相同的合約,立即發現每一處變更——不需要手動滾動,也不會錯過編輯。這就是自動文件比較的威力,使用 GroupDocs.Comparison for .NET,您可以在幾分鐘內完成。

快速答案

  • 什麼程式庫負責 .NET 中的文件比較? GroupDocs.Comparison.
  • 我可以比較 Word、Excel 與 PDF 檔案嗎? 可以——支援超過 50 種格式。
  • 應該使用哪個版本? 版本 25.4.0 提供最佳效能與穩定性。
  • 生產環境需要授權嗎? 商業授權是生產部署的必備條件。
  • 是否支援非同步處理? 當然可以——使用 Task.Run 搭配比較 API。

什麼是 GroupDocs.Comparison?

GroupDocs.Comparison 是一套 .NET 程式庫,能以程式方式偵測兩份或多份文件之間的差異,並產生帶有高亮標示的結果檔案。它支援 50+ 格式,能在不將整個內容載入記憶體的情況下處理上百頁的檔案,並提供細緻的比較設定控制。

為什麼在 compare documents .net 中使用 GroupDocs.Comparison?

GroupDocs.Comparison 為 .NET 應用程式提供快速、精確且具擴充性的文件差異比對。它能在數秒內處理大型 PDF 與 Office 檔案,保留格式與視覺忠實度,同時高亮插入、刪除與樣式變更。此程式庫可於 .NET Core、.NET 5/6/7 以及完整的 .NET Framework 上運作,是任何專案的多功能選擇。

  • 速度: 在標準伺服器上,能於 2 秒內處理 200 頁的 PDF。
  • 精確度: 以 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 進行 compare documents .net?

要使用 GroupDocs.Comparison 比較兩份文件,只需將每個檔案載入串流,設定可選的 ComparisonSettings,然後在 Comparer 實例上呼叫 Compare 方法。API 會回傳一個高亮差異的結果文件,您可以將其儲存為任何支援的格式。此方式僅需少量程式碼,即可完整掌控比較流程。

步驟實作

1️⃣ 智慧文件路徑管理

集中管理檔案路徑可避免「找不到檔案」錯誤,且切換環境毫無痛感。

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️⃣ 核心比較邏輯

Comparer 類別是驅動差異演算法的核心引擎。

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)

您可以微調比較設定,以忽略格式或聚焦資料變更——非常適合 compare excel files c# 的情境。

CompareOptions compareOptions = new CompareOptions()
{
    ShowDeletedContent = true,
    ShowInsertedContent = true,
    StyleChangeDetection = true
};

using (Comparer comparer = new Comparer(sourcePath))
{
    comparer.Add(targetPath);
    comparer.Compare(outputPath, compareOptions);
}

定義說明:
ComparisonSettings 讓您啟用或停用特定變更類型,例如 DetectStyleChangesDetectTableChanges

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️⃣ 大檔案串流處理

處理巨量文件時,串流方式可避免將整個檔案載入記憶體。

// 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️⃣ 強韌的錯誤處理

絕不要讓損毀的檔案使服務當機;請將呼叫包在 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}");
}

文件比較最佳實踐

  • 驗證輸入檔案 再呼叫 API,以提前捕捉不支援的格式。
  • 使用 Path.Combine 進行跨平台路徑建構(參見陷阱 #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 整合

提供一個接受兩個檔案並回傳差異結果的 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:「不支援的檔案格式」

解決方案: 核對檔案副檔名是否在支援清單(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:比較結果為空

解決方案: 透過切換 DetectFormattingChangesDetectStyleChanges 提高靈敏度。

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: 超過 50 種格式,包括 DOCX、XLSX、PPTX、PDF、JPEG、PNG、TXT 等。

Q: 如何自訂變更的顯示樣式?
A: 使用 ComparisonSettings 設定 InsertedColorDeletedColorStyleChangeColor

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 中停用 DetectStyleChangesDetectTableChanges 等選項。

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" };
}

必備資源與文件


最後更新: 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;

相關教學