GroupDocs.Merger for .NET 26.9 Release Notes
There are 14 features, improvements, and bug fixes in this release.
This release adds row-wise joining of spreadsheets into a single sheet and makes PageBuilder apply the page selection of the first TIFF document. It fixes concurrency issues with Visio documents and with PDF and XPS documents joined into DOC, honours the requested preview size in every document format family, and replaces several silent outcomes — a missing license file, an empty page list, an unsupported image or audio join — with clear exceptions.
Full list of changes in this release
| Key | Category | Summary |
|---|---|---|
| MERGERNET-2198 | Feature | Merge Excel rows from multiple files into a single sheet |
| MERGERNET-1372 | Feature | Apply the PageBuilder page selection to the first TIFF document |
| MERGERNET-2183 | Improvement | Throw an exception when SetLicense cannot find the license file |
| MERGERNET-2184 | Improvement | Reject an empty license stream in SetLicense |
| MERGERNET-2190 | Improvement | Throw a clear exception when joining an image or audio file into an unsupported format |
| MERGERNET-2202 | Improvement | Drop System.Drawing.Common from the cross-platform packages and report missing dependencies clearly |
| MERGERNET-2187 | Bug | Close the source file after Merger opens or joins a document by path |
| MERGERNET-2189 | Bug | Call the stream factory only once when constructing Merger |
| MERGERNET-2192 | Bug | Fix corrupt DOC output when joining PDF or XPS documents into DOC from multiple threads |
| MERGERNET-2194 | Bug | Apply a page orientation change to every page when no page numbers are specified |
| MERGERNET-2196 | Bug | Honour the requested preview Width and Height in every document format family |
| MERGERNET-2197 | Bug | Reject ExtractPages and RemovePages called with no page numbers instead of silently producing an empty or unchanged document |
| MERGERNET-2199 | Bug | Fix Visio documents intermittently failing with ArgumentNullException trueTypeFont when processed concurrently |
| MERGERNET-2200 | Bug | Fix PDF portfolios failing with NullReferenceException when an embedded file has no modification date |
Major Features
Row-wise spreadsheet joining: Rows of several spreadsheets can now be appended into a single sheet of the result instead of being added as separate worksheets, with an option to skip header rows of the appended files and to match sheets by position.
PageBuilder for TIFF documents: A page selection made with
PageBuilderis now applied to the first TIFF document as well — previously all of its pages were always included. Joins that do not usePageBuilderare unchanged.Accurate preview dimensions:
GeneratePreviewnow returns images at the requestedWidthandHeightfor every document format family, including Word processing, spreadsheet, Visio and OneNote documents. When only one dimension is given, the other is derived from the page’s aspect ratio.Concurrency fixes: Visio documents no longer fail intermittently when processed from several threads, and PDF and XPS documents joined into DOC from several threads no longer produce corrupt output.
Resource handling: A document opened or joined by file path no longer keeps the source file open after its content has been read, and a
Mergerconstructed from a stream factory calls that factory exactly once.Clearer errors: Joining an image or audio file into an unsupported target format, calling
ExtractPagesorRemovePageswithout page numbers, and callingSetLicensewith a missing license file or an empty license stream now throw an exception instead of failing silently. A missing runtime dependency is reported asMissingDependencyException, naming the assembly and how to install it. PDF portfolios whose embedded files have no modification date now open normally.
Public API and backward incompatible changes
1. Spreadsheet joining — row-wise mode (new API)
New public types in the GroupDocs.Merger.Domain.Options namespace:
| Type | Description |
|---|---|
| SpreadsheetJoinOptions | Join options for spreadsheets, derived from PageJoinOptions. Properties: Mode, SkipRows, SheetMatching. |
| SpreadsheetJoinMode | Worksheets (default) adds the sheets of the joined file as separate worksheets, as before. Rows appends the rows of each joined file below the last row containing data of the matching sheet of the result. |
| SpreadsheetSheetMatching | ByIndex (default) appends sheet 2 to sheet 2, sheet 3 to sheet 3, and so on; worksheets beyond the number of result worksheets are added as new worksheets. FirstSheetOnly appends only the first sheet of each joined file. |
SkipRowsskips the first N rows of every joined file, for example a header row. The first document — the one theMergerwas created with — is always taken in full.SkipRowsandSheetMatchinghave no effect inWorksheetsmode.- Supported formats: XLSX, XLS, XLSM, XLSB, XLTX, XLTM, XLT, XLAM and ODS. Row-wise mode also works when the joined spreadsheet has a different format than the main document (for example, XLS joined into XLSX).
- Carried over: cell values, formulas (relative references are adjusted to the new position), cell styles, merged cells and row heights. Not carried over: charts, pictures and other floating objects, pivot tables, tables, conditional formatting and data validation of the joined files.
- A negative
SkipRowsthrowsGroupDocsMergerException(“The count of rows to skip can not be negative.”), in any mode. - Appending more rows than the output format allows (65,536 for XLS and XLT, 1,048,576 for the other formats) throws
GroupDocsMergerException. ApplyPageBuilderthrowsGroupDocsMergerExceptionwhile a spreadsheet joined inRowsmode is pending, because appended rows do not form separate pages.- Joins without
SpreadsheetJoinOptions, or with the defaultMode, behave exactly as before.
using GroupDocs.Merger;
using GroupDocs.Merger.Domain.Options;
using (var merger = new Merger("january.xlsx"))
{
var options = new SpreadsheetJoinOptions
{
Mode = SpreadsheetJoinMode.Rows, // append rows into the existing sheets
SkipRows = 1 // skip the header row of each joined file
};
merger.Join("february.xlsx", options);
merger.Join("march.xlsx", options);
merger.Save("q1.xlsx");
}
2. TIFF — PageBuilder applies the first document’s page selection
No API change. CreatePageBuilder and ApplyPageBuilder now apply the pages selected from the first TIFF document; previously all pages of the first document were always included and only the selection of the joined documents was applied. Joins that do not use PageBuilder produce the same result as before.
After a join with ImageJoinOptions, CreatePageBuilder and ApplyPageBuilder now throw GroupDocsMergerException, because joined images are composed into one layout rather than a page sequence; previously the page builder contained no documents and AddPage failed with “Invalid document index”. To compose TIFF files page by page, join them without ImageJoinOptions.
using GroupDocs.Merger;
using GroupDocs.Merger.Domain.Builders;
using (var merger = new Merger("source1.tiff"))
{
merger.Join("source2.tiff");
PageBuilder builder = merger.CreatePageBuilder();
// Document 0 = source1.tiff, Document 1 = source2.tiff
builder.AddPage(0, 3); // page 3 of source1.tiff
builder.AddPage(1, 2); // page 2 of source2.tiff
builder.AddPage(0, 1); // page 1 of source1.tiff
merger.ApplyPageBuilder(builder);
merger.Save("merged.tiff"); // exactly these three pages, in this order
}
3. Licensing — SetLicense no longer fails silently
License.SetLicense(string licensePath)throwsInvalidOperationException(“License not found: …”) when the license file cannot be found. Previously the call returned without applying a license, and the product continued in evaluation mode. A null or empty path throwsArgumentException.License.SetLicense(Stream licenseStream)throwsArgumentNullExceptionfor an empty stream, as it already did for a null stream.
4. Page operations with an empty page list
ExtractPagesandRemovePagescalled with no page numbers now throwGroupDocsMergerException(“There are no page numbers to extract.” / “There are no page numbers to remove.”). PreviouslyExtractPagescould produce an empty document andRemovePagesreturned the document unchanged.ChangeOrientationcalled with no page numbers now changes the orientation of every page for PDF, XPS, Word processing, spreadsheet and Visio documents. Previously no page was changed.
5. Preview size
GeneratePreview now resizes every page image to the requested Width and Height — stretched to exactly that size when both are given. Previews of Word processing, spreadsheet, Visio and OneNote documents, and previews requested with only one dimension, can therefore differ in size from previous versions. A negative Width or Height now throws GroupDocsMergerException instead of being ignored.
6. System.Drawing.Common and missing dependencies
- The cross-platform packages
GroupDocs.Merger.Net60,GroupDocs.Merger.Net80andGroupDocs.Merger.Net100no longer depend onSystem.Drawing.Common. The.Windowsand.Net462packages still include it. An application that usedSystem.Drawing.Commonthrough GroupDocs.Merger must now reference that package itself. - When a required assembly or native library is missing at run time, operations throw the new MissingDependencyException (
GroupDocs.Merger.Exceptions, derived fromGroupDocsMergerException). Its message names the missing component and how to install it, and itsAssemblyNameproperty returns the name of the assembly that could not be loaded, when it can be determined. Processing OneNote and SVG documents on the cross-platform packages requiresSystem.Drawing.Common.
7. Joining images and audio into unsupported formats
Joining an image or audio file into a document format it cannot be joined into (for example, PNG into DOCX, or WAV into MP3) now throws FileTypeNotSupportedException (“Joining ‘…’ into ‘…’ is not supported”). Previously the join produced an empty result for that file.