We’re excited to announce the release of Document Solutions for Excel (DsExcel) v8.2, packed with powerful new features and performance enhancements designed to make working with Excel documents faster, smarter, and more efficient. This release introduces advanced formula support with new functions such as GROUPBY, PIVOTBY, PERCENTOF, and TRIMRANGE, delivering more flexible ways to analyze and clean data. Developers can now also work with worksheet background images for seamless interaction with SpreadJS, handle dynamic array formulas using the new Evaluate2
method, and enjoy significant performance gains across lookup functions, statistical calculations, and large workbook operations.
If you’re also interested in the latest updates across the entire Document Solutions product line, be sure to check out our full update blog here.
Ready to check out the release? Download the .NET or Java Edition of Document Solutions for Excel today!
Performance Improvements in v8.2
The v8.2 release of DsExcel delivers significant performance enhancements across formulas, style handling, and file operations.
Formula performance has been greatly improved for functions such as VLOOKUP, XLOOKUP, HLOOKUP, LOOKUP, MATCH, XMATCH, and UNIQUE, especially when searching large ranges with mixed data types. Functions like AVERAGEIF and POISSON.DIST now execute much faster, with POISSON.DIST reducing computation time by 83.96% and COMBIN reducing computation time by 70.46%. Memory consumption has also been optimized when processing templates with large data sources using ITableDataSource
.
File operations are now faster when handling workbooks with large numbers of DefinedNames. For example, opening and saving a file with over 144,000 DefinedNames is now over 50% faster, reducing the DefinedName retrieval cost from 38% of execution time to just 1%.
Enjoy faster formulas, lighter memory usage, and optimized file operations with DsExcel v8.2.
Fit to Selection for Chart Sheets
The v8.2 release introduces support for setting the zoom of a chart sheet to “Fit to Selection” using the DsExcel API. With this new feature, developers can programmatically adjust the zoom of a chart sheet so that its content maximizes the available viewing area, improving readability and presentation.
This feature is especially helpful for developers building automated Excel reporting solutions, dashboards, or chart-heavy spreadsheets, as it ensures charts automatically fill the screen without manual adjustments.
The new capability is exposed through the FitSelection property in the IWorksheetView
interface:
- C#:
bool FitSelection { get; set; }
- Java:
boolean getFitSelection()
andvoid setFitSelection(boolean value)
When set, this option does not modify the value of the regular Zoom property, but instead adjusts the display strategy so the chart sheet fully occupies the Excel window.
Fit Selection |
Custom Selection |
![]() |
![]() |
Help .NET | Demo .NET | Help Java | Demo Java
Handle Error Values in Custom Functions
In v8.2, Document Solutions for Excel introduces the ability for custom functions to handle error values directly through the new AcceptErrors
property on the CustomFunction
class.
By default, formulas return an error if any parameter evaluates to an error value (such as #N/A or #VALUE!). With the AcceptErrors
setting, developers can now choose to allow error values to be passed into their custom functions instead of having the formula fail immediately. This enables scenarios where developers may want to log, detect, or provide fallback behavior for error conditions rather than stopping execution.
This feature provides several benefits for developers:
- Improved flexibility: User-defined formulas can now gracefully handle invalid or unexpected inputs.
- Robust error handling: Developers can implement fallback logic instead of formulas failing outright.
- Enhanced control: Custom functions can inspect and respond to error values in ways that align with business logic.
The new API is available across platforms:
- .NET:
CustomFunction.AcceptErrors { get; set; }
- Java:
setAcceptErrors(boolean acceptErrors)
andgetAcceptErrors()
When AcceptErrors
is set to True, error values are passed to the function for evaluation. If left at its default (False), the function automatically returns an error when encountering invalid arguments. The code below highlights how to apply this new feature to create the image shown above.
C#
var workbook = new GrapeCity.Documents.Excel.Workbook();
Excel.Workbook.AddCustomFunction(new MyFunctionWithAcceptErrors("MyFuncCanAcceptErrors", true));
Excel.Workbook.AddCustomFunction(new MyFunctionWithAcceptErrors("MyFuncNotAcceptErrors", false));
IWorksheet worksheet = workbook.ActiveSheet;
// B3 cell's value is "Exist errors: #Div0".
worksheet.Range["A3"].Value = "=MyFuncCanAcceptErrors(1, 2, 1/0)";
worksheet.Range["B3"].Formula = "=MyFuncCanAcceptErrors(1, 2, 1/0)";
// B4 cell's value is "Exist errors: #Value".
worksheet.Range["A4"].Value = "=MyFuncCanAcceptErrors(1, \"test\" + 1, 3)";
worksheet.Range["B4"].Formula = "=MyFuncCanAcceptErrors(1, \"test\" + 1, 3)";
// B5 cell's value is "Exist errors: #Name, #Num".
worksheet.Range["A5"].Value = "=MyFuncCanAcceptErrors(SUME(1), 2, SQRT(-1), 4)";
worksheet.Range["B5"].Formula = "=MyFuncCanAcceptErrors(SUME(1), 2, SQRT(-1), 4)";
// B9 cell's value is error of #DIV/0!.
worksheet.Range["A9"].Value = "=MyFuncNotAcceptErrors(1, 2, 1/0)";
worksheet.Range["B9"].Formula = "=MyFuncNotAcceptErrors(1, 2, 1/0)";
// B10 cell's value is error of #VALUE!.
worksheet.Range["A10"].Value = "=MyFuncNotAcceptErrors(1, \"test\" + 1, 3)";
worksheet.Range["B10"].Formula = "=MyFuncNotAcceptErrors(1, \"test\" + 1, 3)";
// B11 cell's value is error #NAME?.
worksheet.Range["A11"].Value = "=MyFuncNotAcceptErrors(SUME(1), 2, SQRT(-1), 4)";
worksheet.Range["B11"].Formula = "=MyFuncNotAcceptErrors(SUME(1), 2, SQRT(-1), 4)";
Java
Workbook workbook = new Workbook();
Workbook.AddCustomFunction(new MyFunctionWithAcceptErrors("MyFuncCanAcceptErrors", true));
Workbook.AddCustomFunction(new MyFunctionWithAcceptErrors("MyFuncNotAcceptErrors", false));
IWorksheet worksheet = workbook.getActiveSheet();
// B3 cell's value is "Exist errors: #Div0"
worksheet.getRange("A3").setValue("=MyFuncCanAcceptErrors(1, 2, 1/0)");
worksheet.getRange("B3").setFormula("=MyFuncCanAcceptErrors(1, 2, 1/0)");
// B4 cell's value is "Exist errors: #Value"
worksheet.getRange("A4").setValue("=MyFuncCanAcceptErrors(1, \"test\" + 1, 3)");
worksheet.getRange("B4").setFormula("=MyFuncCanAcceptErrors(1, \"test\" + 1, 3)");
// B5 cell's value is "Exist errors: #Name, #Num"
worksheet.getRange("A5").setValue("=MyFuncCanAcceptErrors(SUME(1), 2, SQRT(-1), 4)");
worksheet.getRange("B5").setFormula("=MyFuncCanAcceptErrors(SUME(1), 2, SQRT(-1), 4)");
// B9 cell's value is error of #DIV/0!
worksheet.getRange("A9").setValue("=MyFuncNotAcceptErrors(1, 2, 1/0)");
worksheet.getRange("B9").setFormula("=MyFuncNotAcceptErrors(1, 2, 1/0)");
// B10 cell's value is error of #VALUE!
worksheet.getRange("A10").setValue("=MyFuncNotAcceptErrors(1, \"test\" + 1, 3)");
worksheet.getRange("B10").setFormula("=MyFuncNotAcceptErrors(1, \"test\" + 1, 3)");
// B11 cell's value is error #NAME?
worksheet.getRange("A11").setValue("=MyFuncNotAcceptErrors(SUME(1), 2, SQRT(-1), 4)");
worksheet.getRange("B11").setFormula("=MyFuncNotAcceptErrors(SUME(1), 2, SQRT(-1), 4)");
Help .NET | Demo .NET | Help Java | Demo Java
Shape Alternative Text and Decorative Flag for Accessibility
The v8.2.0 release enhances accessibility support in Document Solutions for Excel by adding the ability to set descriptive text and decorative flags on shapes. This ensures that spreadsheets containing charts, images, slicers, or other visual objects are more accessible to individuals using screen readers or other assistive technologies.
Previously, DsExcel supported IShape.Title
to provide a title for accessibility purposes. With this update, developers now have access to:
IShape.AlternativeText
— Get or set a descriptive text string for shapes, pictures, linked pictures, charts, slicers, group shapes, and controls. This text is read by assistive technologies as an alternative to the visual element.IShape.Decorative
— Indicate that a shape is decorative and does not convey meaningful content. When set to True, both the title and alternative text are cleared automatically.
This feature helps developers create inclusive spreadsheets by providing meaningful descriptions for important visual elements, while marking purely decorative shapes so they can be skipped by screen readers.
Help .NET | Demo .NET | Help Java | Demo Java
Eta-Reduced Lambda Support
DsExcel now fully supports eta-reduced lambda functions, allowing developers to write more concise and intuitive formulas when passing functions as parameters. Instead of wrapping functions in a full LAMBDA expression (e.g., >=BYROW(A1:A10, LAMBDA(a, ABS(a)))
), you can now simplify them to =BYROW(A1:A10, ABS)
.
This enhancement makes formulas shorter and easier to read, while also enabling advanced new functions such as PIVOTBY and GROUPBY. Eta lambdas can be passed as arguments, used in defined names, and applied with built-in or custom functions. When name conflicts occur, DsExcel resolves them using a prefixing strategy to ensure clarity and consistent behavior.
The following example demonstrates using eta-reduced lambda with BYROW:
var workbook = new Workbook();
var sheet = workbook.Worksheets[0];
sheet.Range["A1:A5"].Value = 1;
sheet.Range["B1"].Formula = "BYROW(A1:A5, SUM)";
Write cleaner, more powerful formulas in Excel with eta-reduced lambda support.
Help .NET | Demo .NET | Help Java | Demo Java
New Functions: GROUPBY, PIVOTBY, PERCENTOF, and TRIMRANGE
DsExcel v8.2 adds support for several powerful new Excel functions that make summarizing and cleaning data easier and more intuitive.
The GROUPBY function enables grouping along one axis with aggregation, filtering, and sorting. For example, you can summarize sales data by year using a simple formula. The PIVOTBY function extends this capability, supporting grouping along two axes for pivot-style summaries such as sales by state and year. Both functions support explicit or eta-reduced lambda functions like SUM
, AVERAGE
, COUNT
, and the new PERCENTOF
function.
PERCENTOF calculates the percentage that a subset contributes to a total, and it integrates seamlessly into GROUPBY and PIVOTBY formulas for percentage-based summaries.
Additionally, the new TRIMRANGE function helps clean up data ranges by automatically removing leading or trailing blank rows and columns. For a more concise syntax, DsExcel also supports Trim References, allowing you to replace the range colon (:) with patterns like .:. to trim both ends.
The following code shows how to use these new functions:
C#
Workbook workbook = new Workbook();
IWorksheet worksheet = workbook.Worksheets[0];
worksheet.Range["A1"].Value = "Region";
worksheet.Range["B1"].Value = "Product";
worksheet.Range["C1"].Value = "Sales";
object[,] data = new object[,] {
{ "North China", "Apple", 100 },
{ "North China", "Orange", 150 },
{ "South China", "Apple", 200 },
{ "South China", "Orange", 50 },
{ "North China", "Apple", 120 },
{ "East China", "Apple", 80 },
{ "East China", "Orange", 90 }
};
worksheet.Range["A2:C8"].Value = data;
worksheet.Range["A10"].Value = "GROUPBY Result (by Region)";
worksheet.Range["A12"].Formula2 = "=GROUPBY(A2:A8, C2:C8, PERCENTOF)";
worksheet.Range["E10"].Value = "PIVOTBY Result (Region vs Product)";
worksheet.Range["E11"].Formula2 = "=PIVOTBY(A2:A8, B2:B8, C2:C8, PERCENTOF)";
Java
var workbook = new Workbook();
var sheet = workbook.Worksheets[0];
sheet.Range["A2"].Value = 200;
sheet.Range["A4"].Value = 400;
sheet.Range["B2"].Formula2 = "=TRIMRANGE(A:A)";
sheet.Range["C2"].Formula2 = "=A1.:.A10";
Quickly summarize, analyze, and clean up data with the new GROUPBY, PIVOTBY, PERCENTOF, and TRIMRANGE functions in DsExcel v8.2.
Help .NET | Help Java | Demo .NET GROUPBY | Demo .NET PIVOTBY | Demo .NET TRIMRANGE | Demo Java GROUPBY | Demo Java PIVOTBY | Demo Java TRIMRANGE
New ShapeType Enumeration Values
DsExcel now extends the ShapeType enumeration to include additional shape types for more complete support when working with Excel documents. The newly supported types include Callout, FreeForm, TextBox, Graphic, and Line, enabling developers to accurately identify and manipulate a wider range of shapes without data loss.
These additions align DsExcel more closely with the Excel UI, ensuring that shapes such as callouts, freeform drawings, and vector graphics can be represented programmatically. For example, callouts are supported as AutoShapes with various styles like LineCallout1 through LineCallout4, and graphics currently support SVG vector images.
The following code shows how to create a list of all the shape types using the updated enumeration:
C#
var workbook = new Workbook();
workbook.Open("shapeType.xlsx");
foreach (var item in workbook.Worksheets)
{
foreach (var shape in item.Shapes)
{
Console.WriteLine(item.Name + ": " + shape.Type);
}
}
Java
Workbook workbook = new Workbook();
workbook.open("E:\\shapeType.xlsx");
for (IWorksheet item : workbook.getWorksheets())
{
for (IShape shape : item.getShapes())
{
System.out.println(item.getName() + ": " + shape.getType());
}
}
Work with a richer variety of shapes in Excel documents using the enhanced ShapeType enumeration.
Help .NET | Demo .NET | Help Java | Demo Java
Retrieve Sheet Tabs from SpreadJS Workbooks
DsExcel now supports APIs to retrieve information about SpreadJS sheet tabs (including TableSheet, GanttSheet, and ReportSheet) when importing or exporting SJS/SSJSON files from SpreadJS. This enables back-end systems to read sheet tab details for integration with business logic such as role-based permissions and front-end coordination.
The new APIs allow developers to:
- Use
IWorkbook.SheetTabs
(orWorkbook.SheetTabs
) to access the sheet tab collection. - Get the total number of sheet tabs with
ISheetTabs.Count
. - Access a tab by index or name using
ISheetTab[index]
andISheetTab[name]
. - Retrieve tab details such as index (
ISheetTab.Index
), name (ISheetTab.Name
), and type (ISheetTab.SheetType
).
The following code shows how to retrieve and iterate through sheet tabs in a SpreadJS workbook:
C#
var workbook = new Workbook();
workbook.Open("sheettabs.sjs");
var sheetTabs = workbook.SheetTabs;
Console.WriteLine("The count of sheet tabs: " + sheetTabs.Count);
foreach (var item in workbook.SheetTabs)
{
Console.WriteLine(item.Name);
}
Java
Workbook workbook = new Workbook();
workbook.open("sheettabs.sjs");
ISheetTabs sheetTabs = workbook.getSheetTabs();
System.out.println("The count of sheet tabs: " + sheetTabs.getCount());
for (ISheetTab item : workbook.getSheetTabs())
{
System.out.println(item.getName());
}
Easily integrate sheet tab metadata into your back-end logic with the new SheetTabs API in DsExcel.
Support for Dynamic Array Formulas with Evaluate2
DsExcel now introduces the IWorksheet.Evaluate2(string formula)
method to support the evaluation of dynamic array formulas, aligning with Excel 2021/365 behavior. While the existing Evaluate
method remains compatible with Excel 2019 and earlier (returning a single value), the new Evaluate2
method returns all values for formulas that spill into multiple cells.
With Evaluate2, developers can now handle formulas such as {1,2,3}, =A1#, or =UNIQUE(A1:A5), and retrieve full results across the spilled range. When a formula returns a reference (e.g., =A1:A5), both Evaluate and Evaluate2 behave the same, returning an IRange
object.
The following example shows how to evaluate a dynamic array formula with Evaluate2
, which returns all results at once (instead of just a single value like Evaluate
would):
var workbook = new Workbook();
var sheet = workbook.Worksheets[0];
#region Init Data
sheet.Name = "API Evaluate2";
sheet.Range["B3:B11"].Value = new object[,] {
{ "Product" },
{ "Apple"},
{ "Grape"},
{ "Pear"},
{ "Banana"},
{ "Coconut"},
{ "Strawberry"},
{ "Orange"},
{ "Pineapple"} };
ITable table = sheet.Tables.Add(sheet.Range["B3:B11"], true);
ITable table1 = sheet.Tables.Add(sheet.Range["D3:D11"], true);
table.ConvertToRange();
table1.ConvertToRange();
sheet.Range["D3"].Value = "Evaluate2 results:";
sheet.Range["B:D"].AutoFit();
#endregion
var evaluateRes = sheet.Evaluate2("=LEN(B4:B11)");
sheet.Range["D4:D11"].Value = evaluateRes;
workbook.Save("res.xlsx");
The code above will result in the following:
Evaluate modern Excel dynamic array formulas programmatically with the new Evaluate2 method in DsExcel.
Help .NET | Demo .NET | Help Java | Demo Java
Logging Support in DsExcel Java
DsExcel now supports a configurable logging system in the Java version, enabling developers to monitor system activity and quickly identify issues. The logging subsystem is built on Apache Commons Logging (JCL), allowing seamless integration with popular frameworks such as Log4j, Logback, and SLF4J. For daily development, using Log4j2 is recommended.
Developers can configure the logging level to control verbosity, with supported levels being debug, info, warn, and error (in order of priority). When a log level is set, all logs of equal or higher priority are recorded, while lower priority logs are ignored.
Easily integrate DsExcel logging into your existing logging framework to track activity and troubleshoot issues effectively. Below is an example of what the contents of a log file will contain:
...
2025-07-03 16:26:15,463 DEBUG [main] aX.o (null:-1) - Save pdf of the workbook.
2025-07-03 16:26:15,466 DEBUG [main] aX.o (null:-1) - Paginate Start(Workbook)
2025-07-03 16:26:15,538 DEBUG [main] excel.bu (null:-1) - Get instance of MypdfGraphics for fontsFolderPath: null
2025-07-03 16:26:15,539 DEBUG [main] excel.bu (null:-1) - Get instance of MypdfGraphics(Use cache): com.grapecity.documents.excel.bu@54504ecd
2025-07-03 16:26:15,542 DEBUG [main] excel.bu (null:-1) - Get instance of MypdfGraphics for fontsFolderPath: null
2025-07-03 16:26:15,542 DEBUG [main] excel.bu (null:-1) - Get instance of MypdfGraphics(Use cache): com.grapecity.documents.excel.bu@54504ecd
2025-07-03 16:26:15,573 DEBUG [main] bn.dE (null:-1) - GetDigitWidthOfDefaultStyle GraphicsType: Pdf
...
See the help link below to see how to get started with logging in your Java application.
Worksheet Background Image Support
DsExcel now supports Excel-like worksheet background images with full compatibility for SpreadJS SJS/SSJSON file formats. Using the IWorksheet.BackgroundPicture
interface, developers can retrieve background images when they are stored in Base64 format and export them to PDF with the PrintBackgroundPicture = true
option.
The following code shows how to set and retrieve a worksheet background image:
C#
var workbook = new Workbook();
workbook.Open("sheetbackgroundimage.sjs");
var backgroundimage = workbook.ActiveSheet.BackgroundPicture;
var sheet2 = workbook.Worksheets.Add();
sheet2.BackgroundPicture = backgroundimage;
workbook.Save("export.xlsx");
workbook.Save("export.sjs");
workbook.Save("export.pdf", new PdfSaveOptions { PrintBackgroundPicture = true });
Java
Workbook workbook = new Workbook();
workbook.open("sheetbackgroundimage.sjs");
byte[] backgroundimage = workbook.getActiveSheet().getBackgroundPicture();
IWorksheet sheet2 = workbook.getWorksheets().add();
sheet2.setBackgroundPicture(backgroundimage);
workbook.save("export.xlsx");
workbook.save("export.sjs");
PdfSaveOptions options = new PdfSaveOptions();
options.setPrintBackgroundPicture(true);
workbook.save("export.pdf", options);
Ensure consistent handling of worksheet background images between SpreadJS and DsExcel with the new BackgroundPicture support.
Help .NET | Demo .NET | Help Java | Demo Java
Ready to check out the release? Download the .NET or Java Edition of Document Solutions for Excel today!