We’re happy to announce the release of GroupDocs.Comparison for .NET 26.5, available as of May 2026.
GroupDocs.Comparison version 26.5 delivers improvements to PDF rendering accuracy, enhanced CSV and spreadsheet comparison readability, new API capabilities for revision handling and spreadsheet change metadata, and an updated NuGet packaging model with multi‑framework support.
Fixes and enhancements
- [Feature] Multi‑framework NuGet packaging and TFM‑split packages. (COMPARISONNET-4770)
- [Enhancement] PDF compare: improve paragraph rendering accuracy in Inline mode. (COMPARISONNET-4751)
- [Enhancement] Enhance comparison results for PDF documents with tables. (COMPARISONNET-4763)
- [Bug] Fix ArgumentOutOfRangeException when comparing PDFs with styled tables. (COMPARISONNET-4762)
- [Feature] Support optional disposal of passed stream in RevisionHandler. (COMPARISONNET-4773)
- [Enhancement] Improve CSV comparison result readability with text markers. (COMPARISONNET-4769)
- [Feature] Extend ChangeInfo with Spreadsheet Properties. (COMPARISONNET-4767)
- [Bug] Compare method throws exception for HTML output. (COMPARISONNET-4764)
Major Features
Multi-framework NuGet packaging and TFM-split packages
GroupDocs.Comparison has transitioned to a more advanced NuGet package delivery model. The main package now targets net462;net6.0;net8.0;net10.0, replacing the previous net462;netstandard2.1 targets.
In addition, to reduce the download size, dedicated per‑framework NuGet packages are now published alongside the main package. When installing the platform‑specific package, only the binaries matching the user’s target framework are downloaded — no unused platform assemblies are included.
| Package | Target framework |
|---|---|
GroupDocs.Comparison |
net462;net6.0;net8.0;net10.0 (all frameworks) |
GroupDocs.Comparison.net462 |
.NET Framework 4.6.2 |
GroupDocs.Comparison.net6 |
.NET 6.0 |
GroupDocs.Comparison.net8 |
.NET 8.0 |
GroupDocs.Comparison.net10 |
.NET 10.0 |
Note: .NET Standard 2.1 is no longer supported as a dedicated target. Projects that previously relied on
netstandard2.1should migrate to one of the supported TFMs listed above.
Support optional disposal of passed stream in RevisionHandler
RevisionHandler now accepts a leaveOpen parameter that controls whether the underlying stream is disposed when the handler is disposed. When leaveOpen is set to true, the stream remains open after the RevisionHandler is disposed, allowing the caller to continue using it. This is useful in scenarios where the stream lifecycle is managed externally.
using FileStream revisionFileStream = new FileStream("source.docx", FileMode.Open, FileAccess.ReadWrite);
using (RevisionHandler revisionHandler = new RevisionHandler(revisionFileStream, leaveOpen: true))
{
List<RevisionInfo> revisionList = revisionHandler.GetRevisions();
foreach (var rev in revisionList)
{
if (rev.Type == RevisionType.Deletion)
rev.Action = RevisionAction.Accept;
}
ApplyRevisionOptions revisionChanges = new ApplyRevisionOptions { Changes = revisionList };
revisionHandler.ApplyRevisionChanges(resultPath, revisionChanges);
}
Extend ChangeInfo with Spreadsheet Properties
Three new properties have been added to ChangeInfo to expose spreadsheet‑specific metadata for each detected change. These properties are populated when comparing Excel (.xlsx) and CSV (.csv) files and allow you to precisely locate each change within the spreadsheet grid:
Row– ดัชนีแถว (เริ่มจาก 0) ของเซลล์ที่มีการเปลี่ยนแปลงColumn– ดัชนีคอลัมน์ (เริ่มจาก 0) ของเซลล์ที่มีการเปลี่ยนแปลงColumnHeader– ข้อความหัวคอลัมน์ของคอลัมน์ที่มีเซลล์เปลี่ยนแปลง (เมื่อมี)
ตัวอย่างด้านล่างแสดงวิธีเปรียบเทียบไฟล์ CSV สองไฟล์และทำการแปลงรายการการเปลี่ยนแปลง (รวมคุณสมบัติสเปรดชีตใหม่) เป็น JSON:
string source = "source.csv";
string target = "target.csv";
string outFilePathJson = "result.json";
using (var comparer = new Comparer(source))
{
comparer.Add(target);
var doc = comparer.Compare();
var changes = doc.Changes;
var json = changes.Select(c => new
{
id = c.Id,
type = c.Type.ToString(),
componentType = c.ComponentType,
row = c.Row,
column = c.Column,
columnHeader = c.ColumnHeader,
sourceText = c.SourceText,
targetText = c.TargetText,
text = c.Text
});
File.WriteAllText(outFilePathJson,
JsonSerializer.Serialize(json, new JsonSerializerOptions { WriteIndented = true