porównywanie dokumentów .net – Kompletny przewodnik implementacji GroupDocs
If you need to porównywać dokumenty .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.
Szybkie odpowiedzi
- Jaka biblioteka obsługuje porównywanie dokumentów w .NET? GroupDocs.Comparison.
- Czy mogę porównywać pliki Word, Excel i PDF? Tak — obsługiwanych jest ponad 50 formatów.
- Którą wersję powinienem użyć? Wersja 25.4.0 oferuje najlepszą wydajność i stabilność.
- Czy potrzebuję licencji do produkcji? Wymagana jest licencja komercyjna do wdrożeń produkcyjnych.
- Czy możliwe jest przetwarzanie asynchroniczne? Oczywiście — użyj
Task.Runz API porównywania.
Czym jest GroupDocs.Comparison?
GroupDocs.Comparison to biblioteka .NET, która programowo wykrywa różnice między dwoma lub większą liczbą dokumentów i generuje podświetlony plik wynikowy. Obsługuje ponad 50 formatów, przetwarza pliki wielostronicowe bez ładowania całej zawartości do pamięci i zapewnia precyzyjną kontrolę nad ustawieniami porównywania.
Dlaczego warto używać GroupDocs.Comparison do porównywania dokumentów .net?
GroupDocs.Comparison zapewnia szybkie, dokładne i skalowalne porównywanie dokumentów dla aplikacji .NET. Może przetwarzać duże pliki PDF i Office w ciągu kilku sekund, zachowując formatowanie i wierność wizualną, jednocześnie podświetlając wstawienia, usunięcia i zmiany stylu. Biblioteka działa na .NET Core, .NET 5/6/7 oraz pełnym .NET Framework, co czyni ją wszechstronnym wyborem dla każdego projektu.
- Szybkość: Przetwarza 200‑stronicowy PDF w mniej niż 2 sekundy na standardowym serwerze.
- Dokładność: Wykrywa tekst, formatowanie, tabele i obrazy z dokładnością 99,9 %.
- Skalowalność: Obsługuje zadania wsadowe tysięcy plików przy użyciu API strumieniowego.
- Elastyczność: Działa z .NET Core 3.1+, .NET 5/6/7 oraz .NET Framework 4.6.1+.
Wymagania wstępne
- Środowisko programistyczne: .NET Core 3.1 lub nowszy, albo .NET Framework 4.6.1 +
- Biblioteka GroupDocs.Comparison: Wersja 25.4.0 (zainstalowana przez NuGet)
- Pliki przykładowe: Dokumenty Word, PDF lub Excel do testów
- Podstawowa znajomość C#: Klasy, metody, instrukcje
using
Warto mieć (opcjonalnie)
- Znajomość zarządzania pakietami NuGet
- Doświadczenie z operacjami I/O i strumieniami
- Zrozumienie wzorców async/await
Jak porównać dokumenty .net przy użyciu GroupDocs.Comparison?
To compare two documents with GroupDocs.Comparison, load each file into a stream, configure optional ComparisonSettings, and invoke the Compare method on a Comparer instance. The API returns a result document that highlights differences, and you can save it to any supported format. This approach requires only a few lines of code while giving you full control over the comparison process.
Implementacja krok po kroku
1️⃣ Inteligentne zarządzanie ścieżkami dokumentów
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";
}
Dlaczego to działa:
- One place to update paths for dev, test, or production.
- Eliminates hard‑coded strings scattered throughout the codebase.
2️⃣ Podstawowa logika porównywania
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);
}
Definicja:Comparer is GroupDocs.Comparison’s core class that orchestrates document analysis and produces the highlighted result.
Jak to pomaga:
- Supports multiple target documents via repeated
Add()calls. - Generates a result file with changes highlighted in red, green, or custom colors.
3️⃣ Zaawansowane ustawienia dla Excel i 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);
}
Definicja:ComparisonSettings lets you enable or disable specific change types such as DetectStyleChanges or DetectTableChanges.
4️⃣ Obsługa wielu formatów
GroupDocs.Comparison automatically detects the file type, but you can also force a format when needed—ideal for 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️⃣ Strumieniowanie dużych plików
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️⃣ Solidna obsługa błędów
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}");
}
Najlepsze praktyki porównywania dokumentów
- Sprawdzaj pliki wejściowe przed wywołaniem API, aby wcześnie wykryć nieobsługiwane formaty.
- Używaj
Path.Combinedo konstrukcji ścieżek wieloplatformowych (zobacz Pułapka #1). - Włączaj tylko potrzebne typy zmian aby zwiększyć wydajność (np. wyłącz wykrywanie stylów dla arkuszy Excel skoncentrowanych na danych).
- Niezwłocznie zwalniaj obiekty
Compareraby zwolnić zasoby natywne.
Częste pułapki i jak ich unikać
Pułapka #1: Problemy z separatorem ścieżek
Solution: Always build paths with Path.Combine() and 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");
Pułapka #2: Wyczerpanie pamięci przy dużych plikach
Solution: Switch to streaming mode for files larger than 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);
}
Pułapka #3: Ignorowanie wyjątków
Solution: Implement comprehensive try‑catch blocks and log stack traces.
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}");
}
Strategie optymalizacji wydajności
Zarządzanie pamięcią
Reuse Comparer instances when possible and call Dispose() after each comparison.
// 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();
}
}
Przetwarzanie asynchroniczne
Run comparisons on background threads to keep UI responsive.
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;
}
});
}
Integracja z popularnymi frameworkami .NET
Integracja ASP.NET Core Web API
Expose a REST endpoint that accepts two files and returns the diff result.
[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);
}
}
}
Integracja komponentu Blazor
Create a reusable component that shows side‑by‑side comparison in the browser.
@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
}
}
Przykłady zastosowań w rzeczywistym świecie
Scenariusz 1: Przegląd umów prawnych
Law firms can automatically highlight additions, deletions, and formatting changes across contract revisions.
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
};
}
}
Scenariusz 2: Kontrola wersji arkuszy kalkulacyjnych
Finance teams can detect changes in Excel models without manually opening each file.
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);
}
}
Przewodnik rozwiązywania problemów
Problem 1: „Format pliku nieobsługiwany”
Solution: Verify the file extension against the supported list (50+ formats) and convert unsupported types to PDF first.
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);
}
Problem 2: Problemy z pamięcią przy dużych plikach
Solution: Enable streaming and process files in chunks.
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);
}
}
}
Problem 3: Pusty wynik porównania
Solution: Increase sensitivity by toggling DetectFormattingChanges or DetectStyleChanges.
var compareOptions = new CompareOptions
{
DetectStyleChanges = true,
DiagramMasterSetting = new DiagramMasterSetting
{
UseSourceMaster = true,
CloneSourceMaster = true
},
OriginalSize = new Size(600, 800),
HeaderFootersComparison = true,
PaperSize = PaperSize.A4
};
Najczęściej zadawane pytania
P: Ile dokumentów mogę porównać jednocześnie?
A: You can add multiple target documents to a single Comparer instance using repeated Add() calls, but processing them sequentially is recommended for large batches.
P: Czy GroupDocs.Comparison obsługuje pliki zabezpieczone hasłem?
A: Yes—pass the password when constructing the Comparer or loading the document.
using (var comparer = new Comparer(sourcePath, new LoadOptions("password")))
{
comparer.Add(targetPath, new LoadOptions("targetPassword"));
comparer.Compare(outputPath);
}
P: Jakie formaty plików obsługuje GroupDocs.Comparison?
A: Over 50 formats, including DOCX, XLSX, PPTX, PDF, JPEG, PNG, TXT, and more.
P: Jak dostosować wygląd zmian?
A: Use ComparisonSettings to set InsertedColor, DeletedColor, and StyleChangeColor.
var compareOptions = new CompareOptions
{
InsertedItemStyle = new StyleSettings
{
HighlightColor = Color.Green,
FontColor = Color.DarkGreen
},
DeletedItemStyle = new StyleSettings
{
HighlightColor = Color.Red,
FontColor = Color.DarkRed
}
};
P: Czy można ignorować określone typy zmian?
A: Absolutely—disable options like DetectStyleChanges or DetectTableChanges in ComparisonSettings.
var compareOptions = new CompareOptions
{
DetectStyleChanges = false, // Ignore formatting changes
HeaderFootersComparison = false, // Skip headers/footers
WordsSeparatorChars = new[] { ' ', '\n', '\r', '\t' } // Define word boundaries
};
P: Czy mogę porównać dokumenty przechowywane w chmurze?
A: Yes—download the streams locally or compare directly from 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);
}
P: Jak uruchomić GroupDocs.Comparison w kontenerze Docker?
A: Include the necessary native dependencies in your Dockerfile and copy the license file into the container.
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
P: Jakie licencjonowanie jest wymagane do produkcji?
A: A commercial GroupDocs.Comparison license is mandatory for production deployments. Options include developer, site, and OEM licenses.
P: Jak obsługiwać niepowodzenia porównania w sposób elegancki?
A: Wrap the comparison call in a try‑catch block, log the exception, and return a user‑friendly error message.
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" };
}
Niezbędne zasoby i dokumentacja
- Pełna dokumentacja: GroupDocs Comparison .NET Docs
- Przewodnik po API: GroupDocs API Reference for .NET
- Forum wsparcia społeczności: GroupDocs Forum
- Strona z najnowszymi wersjami: Releases Page
- Pobierz wersję próbną: Try Free Version
- Złóż wniosek o tymczasową licencję: Apply for Temporary License
- Kup pełną licencję GroupDocs: Buy GroupDocs License
- Wydania: Releases
- Strona tymczasowej licencji: Temporary License Page
- Strona zakupu: Purchase Page
Last Updated: 2026-06-10
Tested With: GroupDocs.Comparison 25.4.0 for .NET
Author: GroupDocs
Install-Package GroupDocs.Comparison -Version 25.4.0
dotnet add package GroupDocs.Comparison --version 25.4.0
using GroupDocs.Comparison;