We’re excited to introduce Document Solutions for Excel v9.2, a release that expands workbook compatibility, strengthens PivotTable workflows, improves exported output, and gives developers more control over how spreadsheet content is loaded, saved, secured, and exchanged across applications.
Document Solutions for Excel .NET (DsExcel .NET) and Document Solutions for Excel Java (DsExcel Java) v9.2 add PivotTable grouping APIs, Custom XML part support, hidden defined names, configurable handling for invalid formulas, and an option designed to help reduce CSV formula-injection risk. The release also improves XLSX round-tripping for mathematical equations and grouped form controls, while extending PDF, image, and HTML export support for Histogram and Pareto charts, SpreadJS File Upload cell types, and CJK RubyText.
This release further strengthens interoperability with SpreadJS, our JavaScript spreadsheet component. AI function names are now converted automatically when moving between Document Solutions for Excel and SpreadJS formats, and several SpreadJS v19.2 features can be preserved through SJS and SSJSON lossless I/O. Document Solutions Data Viewer (DsDataViewer) v9.2 also adds support for opening XLTX Excel template files through both the viewer interface and JavaScript API. Developers can also explore new local performance benchmark packages for both .NET and Java to test common spreadsheet operations on their own hardware and workbooks.
To read about the latest v9.2 features in our other Document Solutions products, check out the accompanying What’s New blog here.
Document Solutions for Excel v9.2 Includes
- New Workbook and Excel I/O Features
- PivotTable Grouping Support
- New Export Features
- Security and Formula-Handling Improvements
- SpreadJS Interoperability and Lossless I/O Improvements
- XLTX File Support in Document Solutions Data Viewer
- Performance Benchmark Demo and Local Package
- API Reference Documentation Improvements
Download the Latest Release of the .NET or Java Excel APIs Today!
New Workbook and Excel I/O Features in Document Solutions for Excel v9.2
Document Solutions for Excel v9.2 expands the types of workbook content developers can preserve and manage programmatically. These improvements include lossless handling of Excel equation objects, public APIs for workbook-level Custom XML parts, visibility control for defined names, and better support for grouped Excel Form Controls.
Support for Excel Equation Symbols and Office Math Structures
Document Solutions for Excel v9.2 improves XLSX round-tripping for workbooks that contain mathematical equations. Developers can open and save an XLSX file containing equation objects while preserving the original Office Math structures and associated Shape Format settings.

Equation objects also remain intact when developers perform common workbook and worksheet operations, including copying worksheets, cloning workbooks, and inserting or deleting rows and columns near anchored equations. This makes it easier to process technical, scientific, educational, and engineering workbooks without losing specialized equation content.
Preserve Excel Equation Objects During XLSX Processing
C#:
var workbook = new Workbook();
workbook.Open("Equations.xlsx");
// Perform workbook or worksheet operations as needed.
workbook.ActiveSheet.Range["A1:A2"].EntireRow.Insert();
workbook.Save("Equations-RoundTrip.xlsx");
Java:
Workbook workbook = new Workbook();
workbook.open("Equations.xlsx");
// Perform workbook or worksheet operations as needed.
workbook.getActiveSheet().getRange("A1:A2").getEntireRow().insert();
workbook.save("Equations-RoundTrip.xlsx");
Custom XML Part API Support
Document Solutions for Excel v9.2 introduces workbook-level APIs for working with OOXML Custom XML parts. This is useful for applications that store business metadata, integration payloads, macro-related data, or other XML content inside XLSX and XLSM files.
The new ICustomXmlPartCollection and ICustomXmlPart APIs allow developers to add, retrieve, enumerate, update, and remove Custom XML parts. Each part exposes a persistent logical ID and raw byte content. The XML bytes are stored without transformation, helping applications round-trip the original payload without changing its encoding or structure.

Custom XML parts are loaded automatically when a workbook is opened and are saved as standard OOXML package parts. This removes the need to modify the workbook’s ZIP or OPC package directly.
Add and Manage Custom XML Parts in Excel Workbooks
C#:
var workbook = new Workbook();
ICustomXmlPartCollection customXmlParts = workbook.CustomXmlParts;
ICustomXmlPart customerPart = customXmlParts.Add();
customerPart.Data = Encoding.UTF8.GetBytes(
"<customer><name>Grace Green</name><region>West</region></customer>");
string partId = customerPart.Id;
ICustomXmlPart partById = customXmlParts[partId];
partById.Data = Encoding.UTF8.GetBytes(
"<customer><name>Grace Green</name><region>East</region></customer>");
workbook.Save("CustomXmlParts.xlsx");
Java:
var workbook = new Workbook();
ICustomXmlPartCollection customXmlParts = workbook.CustomXmlParts;
ICustomXmlPart customerPart = customXmlParts.Add();
customerPart.Data = Encoding.UTF8.GetBytes(
"<customer><name>Grace Green</name><region>West</region></customer>");
string partId = customerPart.Id;
ICustomXmlPart partById = customXmlParts[partId];
partById.Data = Encoding.UTF8.GetBytes(
"<customer><name>Grace Green</name><region>East</region></customer>");
workbook.Save("CustomXmlParts.xlsx");
Help .NET | Demo .NET | Help Java | Demo Java
Support for Hidden Defined Names
Document Solutions for Excel v9.2 adds public API support for controlling whether a defined name is visible in Excel’s Name Manager. Internal helper names can remain available to formulas, templates, validation rules, and automation logic while being hidden from workbook users.
The new IName.Visible property supports both workbook-scoped and worksheet-scoped names. Newly created names remain visible by default. Setting Visible to false maps to the existing hidden state in the XLSX model and preserves that setting when the workbook is reopened in Excel.
Hidden defined-name visibility is not preserved in SJS or SSJSON because SpreadJS does not currently retain that state.
Create Hidden Workbook and Worksheet Defined Names
C#:
// Create a new workbook.
var workbook = new Workbook();
IWorksheet worksheet = workbook.Worksheets[0];
worksheet.Name = "Sheet1";
// Add two workbook-scoped defined names and set one of them to be invisible.
IName workbookName = workbook.Names.Add("HiddenWorkbookName", "=Sheet1!$A$1");
workbookName.Visible = false;
IName visibleWorkbookName = workbook.Names.Add("VisibleWorkbookName", "=Sheet1!$B$1");
visibleWorkbookName.Visible = true;
// Add two worksheet-scoped defined names and set one of them to be invisible.
IName worksheetName = worksheet.Names.Add("HiddenWorksheetName", "=Sheet1!$C$1");
worksheetName.Visible = false;
IName visibleWorksheetName = worksheet.Names.Add("VisibleWorksheetName", "=Sheet1!$D$1");
visibleWorksheetName.Visible = true;
// Save the workbook.
workbook.Save("HiddenDefinedNames.xlsx");
Java:
// Create a new workbook.
Workbook workbook = new Workbook();
IWorksheet worksheet = workbook.getWorksheets().get(0);
worksheet.setName("Sheet1");
// Add two workbook-scoped defined names and set one of them to be invisible.
IName workbookName = workbook.getNames().add("HiddenWorkbookName", "=Sheet1!$A$1");
workbookName.setVisible(false);
IName visibleWorkbookName = workbook.getNames().add("VisibleWorkbookName", "=Sheet1!$B$1");
visibleWorkbookName.setVisible(true);
// Add two worksheet-scoped defined names and set one of them to be invisible.
IName worksheetName = worksheet.getNames().add("HiddenWorksheetName", "=Sheet1!$C$1");
worksheetName.setVisible(false);
IName visibleWorksheetName = worksheet.getNames().add("VisibleWorksheetName", "=Sheet1!$D$1");
visibleWorksheetName.setVisible(true);
// Save the workbook.
workbook.save("HiddenDefinedNames.xlsx");
After setting the visibility status to “False”, the worksheet and workbook names will be hidden from Excel’s Name Manager:

Help .NET | Demo .NET | Help Java | Demo Java
Support for Form Controls Inside Group Shapes
Document Solutions for Excel v9.2 improves support for Excel Form Controls contained inside regular, nested, or mixed shape groups. Group hierarchy, control properties, position, size, and control collection access are preserved across XLSX, SJS, and SSJSON workflows.
Supported grouped controls include Button, CheckBox, OptionButton, DropDown, ListBox, Spinner, ScrollBar, GroupBox, and Label. Form Controls appear in IShape.GroupItems as ShapeType.FormControl, while remaining accessible through IWorksheet.Controls.
Existing APIs now work more consistently with grouped controls. Developers can group controls with other shapes, duplicate or delete a group, copy or cut an individual grouped control, and ungroup the collection back into top-level shapes. Grouped Form Controls are also rendered during PDF, HTML, and image export. When PdfSaveOptions.FormFields is enabled, supported controls inside a group can be exported as interactive PDF form fields.

This enhancement applies to Excel Form Controls. ActiveX controls and OLE objects inside groups are outside the scope of this feature.
Group Excel Form Controls Programmatically
C#:
var workbook = new Workbook();
IWorksheet worksheet = workbook.Worksheets["Sheet1"];
var button = worksheet.Controls.AddButton(30, 35, 110, 28);
button.Text = "Approve";
var checkBox = worksheet.Controls.AddCheckBox(30, 75, 120, 22);
checkBox.Text = "Reviewed";
checkBox.IsChecked = true;
var label = worksheet.Controls.AddLabel(55, 105, 100, 18);
label.Text = "Grouped together";
worksheet.Shapes.Range[new[]
{
button.ShapeRange[0].Name,
checkBox.ShapeRange[0].Name,
label.ShapeRange[0].Name
}].Group();
workbook.Save("GroupFormControlShapes.xlsx");
Java:
Workbook workbook = new Workbook();
IWorksheet worksheet = workbook.getWorksheets().get("Sheet1");
IButton button = worksheet.getControls().addButton(30, 35, 110, 28);
button.setText("Approve");
ICheckBox checkBox = worksheet.getControls().addCheckBox(30, 75, 120, 22);
checkBox.setText("Reviewed");
checkBox.setChecked(true);
ILabel label = worksheet.getControls().addLabel(55, 105, 100, 18);
label.setText("Grouped together");
worksheet.getShapes().getRange(new String[] {
button.getShapeRange().get(0).getName(),
checkBox.getShapeRange().get(0).getName(),
label.getShapeRange().get(0).getName()
}).group();
workbook.save("GroupFormControlShapes.xlsx");
Help .NET | Demo .NET | Help Java | Demo Java
PivotTable Grouping Support
Group PivotTable Fields by Date, Numeric Range, or Selected Items
Document Solutions for Excel v9.2 adds comprehensive PivotTable grouping support for date fields, numeric fields, and manually selected items. Group definitions are preserved through PivotTable refreshes when the source data remains compatible, and grouping information can round-trip through XLSX, SJS, and SSJSON.
Date grouping uses PivotFieldDateGroupOptions and can group values by seconds, minutes, hours, days, months, quarters, or years. When a date field is located in the row or column area, generated group fields can be added to the same layout automatically. Developers can control this behavior through AddGeneratedFieldsToLayout.
Numeric grouping uses PivotFieldNumberGroupOptions to define the start value, end value, and interval for generated ranges. Numeric grouping does not create an additional field; instead, it replaces the displayed items with range-based buckets.
Manual grouping uses PivotFieldCustomGroupOptions to combine selected PivotItems into a named group. Manual groups can be nested, and developers can use the group name or IPivotItem.Caption to customize displayed labels.
The new IPivotField.Ungroup() method removes grouping and restores the original source layout. When multiple PivotTables share the same IPivotCache, grouping and ungrouping changes are reflected across the dependent PivotTables. Grouping is not supported on a PivotCache containing calculated items.
Example: Group PivotTable Values into Numeric Ranges
C#:
//create a new workbook
var workbook = new GrapeCity.Documents.Excel.Workbook();
object[,] sourceData = new object[,]
{
{ "Order ID", "Product", "Shipping Fee", "Sales" },
{ 1001, "Apple", 18d, 120d },
{ 1002, "Banana", 42d, 95d },
{ 1003, "Carrot", 68d, 150d },
{ 1004, "Dates", 85d, 90d },
{ 1005, "Eggplant", 110d, 180d },
{ 1006, "Fig", 135d, 160d },
{ 1007, "Grapes", 170d, 140d },
{ 1008, "Honey", 205d, 210d },
{ 1009, "Ice Tea", 28d, 80d },
};
IWorksheet worksheet = workbook.Worksheets[0];
worksheet.Range["G1:J10"].Value = sourceData;
worksheet.Range["I2:J10"].NumberFormat = "$#,##0.00";
IPivotCache pivotcache = workbook.PivotCaches.Create(worksheet.Range["G1:J10"]);
IPivotTable pivottable = worksheet.PivotTables.Add(pivotcache, worksheet.Range["A1"], "numberGroupPivot");
IPivotField fieldShippingFee = pivottable.PivotFields["Shipping Fee"];
fieldShippingFee.Orientation = PivotFieldOrientation.RowField;
IPivotField fieldSales = pivottable.PivotFields["Sales"];
fieldSales.Orientation = PivotFieldOrientation.DataField;
fieldSales.NumberFormat = "$#,##0.00";
fieldShippingFee.Group(new PivotFieldNumberGroupOptions
{
Start = 0d,
End = 250d,
AutoStart = false,
AutoEnd = false,
Interval = 50d,
});
worksheet.Range["A:J"].EntireColumn.AutoFit();
// Save to an excel file
workbook.Save("NumberGroup.xlsx");
Java:
// Create a new workbook
Workbook workbook = new Workbook();
Object sourceData = new Object[][]{
{"Order ID", "Product", "Shipping Fee", "Sales"},
{1001, "Apple", 18d, 120d},
{1002, "Banana", 42d, 95d},
{1003, "Carrot", 68d, 150d},
{1004, "Dates", 85d, 90d},
{1005, "Eggplant", 110d, 180d},
{1006, "Fig", 135d, 160d},
{1007, "Grapes", 170d, 140d},
{1008, "Honey", 205d, 210d},
{1009, "Ice Tea", 28d, 80d},
};
IWorksheet worksheet = workbook.getWorksheets().get(0);
worksheet.getRange("G1:J10").setValue(sourceData);
worksheet.getRange("I2:J10").setNumberFormat("$#,##0.00");
IPivotCache pivotCache = workbook.getPivotCaches().create(worksheet.getRange("G1:J10"));
IPivotTable pivotTable = worksheet.getPivotTables().add(pivotCache, worksheet.getRange("A1"), "numberGroupPivot");
pivotTable.getPivotFields().get("Shipping Fee").setOrientation(PivotFieldOrientation.RowField);
pivotTable.getPivotFields().get("Sales").setOrientation(PivotFieldOrientation.DataField);
pivotTable.getPivotFields().get("Sales").setNumberFormat("$#,##0.00");
PivotFieldNumberGroupOptions options = new PivotFieldNumberGroupOptions();
options.setStart(0d);
options.setEnd(250d);
options.setAutoStart(false);
options.setAutoEnd(false);
options.setInterval(50d);
pivotTable.getPivotFields().get("Shipping Fee").group(options);
worksheet.getRange("A:J").getEntireColumn().autoFit();
// Save to an excel file
workbook.save("NumberGroup.xlsx");
From the code above, the following grouping output is produced:

Help .NET | Demo .NET | Help Java | Demo Java
New Export Features in Document Solutions for Excel v9.2
Document Solutions for Excel v9.2 improves exported output for modern Excel charts, SpreadJS cell types, and CJK phonetic annotations. Histogram and Pareto charts can now be exported to PDF, image, and HTML, while File Upload cell types and RubyText receive specialized rendering support.
Support for Histogram Chart Export
Document Solutions for Excel v9.2 adds support for exporting Histogram charts to PDF, image, and HTML. The export engine supports category bins, automatic bins, custom bin width, custom bin count, and configurable overflow and underflow bins.
For category bins, negative source values are excluded to align with Excel’s exported result. Automatic binning may not produce the exact same intervals as Excel because the applications can use different automatic binning heuristics, but Document Solutions for Excel produces stable and visually similar output. Explicit settings such as bin width, bin count, overflow values, and underflow values are handled directly.
Export Excel Histogram Charts to PDF, Image, and HTML
C#:
//create a new workbook
var workbook = new GrapeCity.Documents.Excel.Workbook();
IWorksheet worksheet = workbook.Worksheets[0];
worksheet.Range["A1:B11"].Value = new object[,]
{
{ "Complaint Category", "Complaint Change" },
{ "Too noisy", -180 },
{ "Overpriced", 240 },
{ "Food is tasteless", -75 },
{ "Food is not fresh", 95 },
{ "Food is too salty", 130 },
{ "Not clean", 210 },
{ "Unfriendly staff", -120 },
{ "Wait time", 160 },
{ "No atmosphere", -40 },
{ "Small portions", 320 }
};
worksheet.Range["A:B"].Columns.AutoFit();
worksheet.Tables.Add(worksheet.Range["A1:B11"], true);
// Create a histogram chart.
IShape shape = worksheet.Shapes.AddChart(ChartType.Histogram, worksheet.Range["A13:G28"]);
shape.Chart.SeriesCollection.Add(worksheet.Range["A1:B11"]);
shape.Chart.ChartTitle.Text = "Histogram of Complaint Changes";
shape.Chart.HasLegend = true;
IChartGroup chartGroup = shape.Chart.ChartGroups[0];
chartGroup.BinsType = BinsType.BinsTypeBinSize;
chartGroup.BinWidthValue = 150;
chartGroup.BinsOverflowEnabled = true;
chartGroup.BinsOverflowValue = 200;
ISeries series = shape.Chart.SeriesCollection[0];
series.HasDataLabels = true;
series.DataLabels.ShowValue = true;
// Save to a pdf file
workbook.Save("HistogramChartPdf.pdf");
Java:
// Create a new workbook
Workbook workbook = new Workbook();
IWorksheet worksheet = workbook.getWorksheets().get(0);
worksheet.getRange("A1:B11").setValue(new Object[][]{
{"Complaint Category", "Complaint Change"},
{"Too noisy", -180},
{"Overpriced", 240},
{"Food is tasteless", -75},
{"Food is not fresh", 95},
{"Food is too salty", 130},
{"Not clean", 210},
{"Unfriendly staff", -120},
{"Wait time", 160},
{"No atmosphere", -40},
{"Small portions", 320}
});
worksheet.getRange("A:B").getColumns().autoFit();
worksheet.getTables().add(worksheet.getRange("A1:B11"), true);
// Create a histogram chart.
IShape shape = worksheet.getShapes().addChart(ChartType.Histogram, worksheet.getRange("A13:G28"));
shape.getChart().getSeriesCollection().add(worksheet.getRange("A1:B11"));
shape.getChart().getChartTitle().setText("Histogram of Complaint Changes");
shape.getChart().setHasLegend(true);
IChartGroup chartGroup = shape.getChart().getChartGroups().get(0);
chartGroup.setBinsType(BinsType.BinsTypeBinSize);
chartGroup.setBinWidthValue(150);
chartGroup.setBinsOverflowEnabled(true);
chartGroup.setBinsOverflowValue(200);
ISeries series = shape.getChart().getSeriesCollection().get(0);
series.setHasDataLabels(true);
series.getDataLabels().setShowValue(true);
// Save to a pdf file
workbook.save("HistogramChartPdf.pdf");
The exported Histogram looks as follows:

Help .NET | Demo .NET | Help Java | Demo Java
Support for Pareto Chart Export
Document Solutions for Excel v9.2 adds support for exporting Pareto charts to PDF, image, and HTML. Pareto charts combine descending columns with a cumulative percentage line, helping teams identify the categories that contribute most heavily to a result, such as product defects, customer complaints, or process failures.
Pareto charts use the same bin-materialization rules as Histogram charts. Negative values are excluded for category bins, the materialized bar counts are sorted in descending order, and the cumulative percentage line is calculated from the running total of those sorted counts.
Export Excel Pareto Charts to PDF, Image, and HTML
C#:
var workbook = new Workbook();
IWorksheet worksheet = workbook.Worksheets[0];
worksheet.Range["A1:B11"].Value = new object[,]
{
{ "Complaint", "Count" },
{ "Too noisy", 270 },
{ "Overpriced", 789 },
{ "Food is tasteless", -65 },
{ "Food is not fresh", 90 },
{ "Food is too salty", 150 },
{ "Not clean", 300 },
{ "Unfriendly staff", -120 },
{ "Wait time", 109 },
{ "No atmosphere", 450 },
{ "Small portions", 621 }
};
IShape shape = worksheet.Shapes.AddChart(
ChartType.Pareto, 260, 20, 520, 320);
shape.Chart.SeriesCollection.Add(worksheet.Range["A1:B11"]);
IChartGroup chartGroup = shape.Chart.ChartGroups[0];
chartGroup.BinsType = BinsType.BinsTypeBinSize;
chartGroup.BinWidthValue = 200;
chartGroup.BinsOverflowEnabled = true;
chartGroup.BinsOverflowValue = 700;
workbook.Save("ParetoChart.pdf");
Java:
Workbook workbook = new Workbook();
IWorksheet worksheet = workbook.getWorksheets().get(0);
worksheet.getRange("A1:B11").setValue(new Object[][] {
{"Complaint", "Count"},
{"Too noisy", 270},
{"Overpriced", 789},
{"Food is tasteless", -65},
{"Food is not fresh", 90},
{"Food is too salty", 150},
{"Not clean", 300},
{"Unfriendly staff", -120},
{"Wait time", 109},
{"No atmosphere", 450},
{"Small portions", 621}
});
IShape shape = worksheet.getShapes().addChart(
ChartType.Pareto, 260, 20, 520, 320);
shape.getChart().getSeriesCollection().add(worksheet.getRange("A1:B11"));
IChartGroup chartGroup = shape.getChart().getChartGroups().get(0);
chartGroup.setBinsType(BinsType.BinsTypeBinSize);
chartGroup.setBinWidthValue(200);
chartGroup.setBinsOverflowEnabled(true);
chartGroup.setBinsOverflowValue(700);
workbook.save("ParetoChart.pdf");
Below is a screenshot of the exported Pareto chart:

Help .NET | Demo .NET | Help Java | Demo Java
Support for Exporting SpreadJS File Upload Cell Types
Document Solutions for Excel v9.2 adds PDF, image, and HTML export support for the SpreadJS File Upload cell type. The exporter handles image attachments, non-image attachments, and empty upload states so output more closely reflects the original SpreadJS workbook.
Image attachments are rendered inside the File Upload content area while respecting margins, resized rows and columns, and button-layout constraints. Non-image attachments are represented by a file icon and attachment name, including custom file icons stored through spread.options.builtInFileIcons in SJS or SSJSON. Empty File Upload cells are rendered as rounded, dashed placeholders with localized upload text based on the workbook culture.
Export SpreadJS File Upload Cells to PDF
C#:
Workbook workbook = new Workbook();
workbook.Open("FileUpload.json");
workbook.Save("FileUpload.pdf");
Java:
Workbook workbook = new Workbook();
workbook.open("FileUpload.json");
workbook.save("FileUpload.pdf");
Help .NET | Demo .NET | Help Java | Demo Java
Support for CJK RubyText in PDF and Image Export
Document Solutions for Excel v9.2 adds PDF and image export support for Excel RubyText, also known as phonetic text, in Chinese, Japanese, and Korean culture contexts. When a workbook already contains RubyText and the cell enables phonetic display, the annotation is rendered with the normal cell text in the exported output.
The exporter supports RubyText alignment, wrapping, rich text, overflow, merged cells, rotation, vertical text, ShrinkToFit, page scaling, and AutoFit scenarios. RubyText uses its own phonetic font styling and is positioned against the final displayed location of the annotated base text after formatting and layout are applied.
The feature uses phonetic data already stored in the workbook. It does not add public APIs for creating RubyText, generating kana or pinyin, or evaluating the PHONETIC() function. HTML export is not included in this enhancement.
Export Excel RubyText to PDF
C#:
var workbook = new Workbook();
workbook.Open("RubyText.xlsx");
workbook.Save("RubyText.pdf");
Java:
Workbook workbook = new Workbook();
workbook.open("RubyText.xlsx");
workbook.save("RubyText.pdf");
The Ruby exported text will appear as follows:
| Chinese Ruby Text | Japanese Ruby Text | Korean Ruby Text |
|
|
![]() |
![]() |
Help .NET | Demo .NET | Help Java | Demo Java
Security and Formula-Handling Improvements
Configure How Invalid Formulas Are Handled During Workbook Loading
Document Solutions for Excel v9.2 introduces the InvalidFormulaHandling option, giving developers control over how syntactically invalid formulas are handled when XLSX, XLSM, XLTX, SJS, and SSJSON content is loaded.
An invalid formula is one that cannot be parsed into a valid formula structure, such as a formula with mismatched parentheses, an incomplete function call, or an operator without an operand. Previously, XLSX-family files threw an exception when invalid formulas were encountered, while SJS and SSJSON used format-specific discard behavior.
The new enumeration provides four choices:
Throwraises an exception when an invalid formula is encountered.Discardremoves both the invalid formula and its cached value.DiscardFormulaOnlyremoves the formula but preserves the cached value.Preserveretains the original invalid formula text for round-trip I/O and returns the cached value when one exists; otherwise, the calculated result is#VALUE!.
XlsxOpenOptions, XlsmOpenOptions, and XltxOpenOptions use Throw by default. SjsOpenOptions uses Discard by default. DeserializationOptions.InvalidFormulaHandling is nullable so existing SJS and SSJSON deserialization behavior remains unchanged until a value is selected explicitly.
When an option is set explicitly for JSON deserialization, normal and shared formulas follow the same selected behavior. Invalid formulas preserved through this feature can also be retained when saving back to XLSX, XLSM, XLTX, SJS, or SSJSON.
Open and Preserve a Workbook Containing Invalid Formulas
C#:
var workbook = new Workbook();
var options = new XlsxOpenOptions
{
InvalidFormulaHandling = InvalidFormulaHandling.Preserve
};
workbook.Open("InvalidFormulas.xlsx", options);
workbook.Save("InvalidFormulas-Preserved.xlsx");
Java:
Workbook workbook = new Workbook();
XlsxOpenOptions options = new XlsxOpenOptions();
options.setInvalidFormulaHandling(InvalidFormulaHandling.Preserve);
workbook.open("InvalidFormulas.xlsx", options);
workbook.save("InvalidFormulas-Preserved.xlsx");
Help .NET | Demo .NET | Help Java | Demo Java
Help Reduce CSV Formula-Injection Risk During Export
Document Solutions for Excel v9.2 adds the opt-in CsvSaveOptions.EscapeFormulaLikeValues property. This option helps applications export untrusted or user-generated data as CSV without allowing formula-like text to be interpreted automatically as a spreadsheet formula when the file is opened.
When enabled, Document Solutions for Excel checks the first character of each exported value. Values beginning with =, +, -, @, their full-width variants, a tab, a carriage return, or a line feed are prefixed with an apostrophe so spreadsheet applications treat them as text.
The option is disabled by default to preserve existing behavior. It sanitizes the field text before the existing CSV quoting rules are applied and does not change the meaning of QuoteColumns or ValueQuoteType.
Escape Formula-Like Values During CSV Export
C#:
var workbook = new Workbook();
var worksheet = workbook.ActiveSheet;
worksheet.Range["A1"].Value = "=1+1";
worksheet.Range["A2"].Value = "+SUM(1,1)";
var options = new CsvSaveOptions
{
EscapeFormulaLikeValues = true,
ValueQuoteType = ValueQuoteType.Always
};
workbook.Save("export.csv", options);
Java:
Workbook workbook = new Workbook();
IWorksheet worksheet = workbook.getActiveSheet();
worksheet.getRange("A1").setValue("=1+1");
worksheet.getRange("A2").setValue("+SUM(1,1)");
CsvSaveOptions options = new CsvSaveOptions();
options.setEscapeFormulaLikeValues(true);
options.setValueQuoteType(ValueQuoteType.Always);
workbook.save("export.csv", options);
Help .NET | Demo .NET | Help Java | Demo Java
SpreadJS Interoperability Improvements
AI Function Prefix Compatibility Between Document Solutions for Excel and SpreadJS
Document Solutions for Excel v9.2 improves interoperability for AI formulas stored in SJS and SSJSON files. SpreadJS and Document Solutions for Excel use different prefixes for supported AI function names, which previously prevented formulas created by one product from being evaluated correctly by the other.
Document Solutions for Excel now performs the required conversion automatically during import and export. When SJS or SSJSON is imported, SJS.AI.TRANSLATE, SJS.AI.QUERY, and SJS.AI.TEXTSENTIMENT are converted to their AI. equivalents. When a workbook is exported to SJS or SSJSON, the SJS. prefix is added again for SpreadJS compatibility.
This conversion requires no new API and helps preserve working AI formulas in applications that use both Document Solutions for Excel and SpreadJS.
SpreadJS v19.2 Lossless I/O Improvements
Document Solutions for Excel v9.2 adds lossless SJS and SSJSON I/O support for several features introduced or expanded in SpreadJS v19.2. These enhancements focus on preserving workbook data during import, export, and conversion rather than adding new runtime authoring APIs.
DataManager Sources for PivotTables
Document Solutions for Excel can now round-trip PivotTables whose source is a SpreadJS DataManager DataTable or DataView. When the SJS or SSJSON file contains a complete PivotCache and PivotCacheRecords, the workbook can also be exported to XLSX and updated through IPivotTable.Update. Refresh is not available because Document Solutions for Excel cannot retrieve the live DataManager source.
Simplified files that contain only the DataManager source identity can be opened and round-tripped through SJS or SSJSON, but they cannot be exported safely to XLSX or used for PivotTable operations because the full cache cannot be reconstructed.
Focus Cell Options
Workbook-level Focus Cell settings introduced in SpreadJS v19.2 can now be preserved in SJS and SSJSON. Document Solutions for Excel retains the enabled, color, and opacity fields during import, export, and SJS-to-SSJSON conversion.
Focus Cell is a SpreadJS visual state and is not persisted in Excel files or rendered by Document Solutions for Excel during printing or PDF export.
PivotTable Custom Subtotals
Document Solutions for Excel v9.2 preserves PivotTable custom subtotal settings for row and column fields during SJS and SSJSON I/O. Automatic, None, and Custom subtotal states, including the selected subtotal functions, can round-trip without being lost.
Rounded Cell Borders
Rounded cell-border settings from SpreadJS can now be preserved in SJS and SSJSON files. This enhancement is limited to lossless I/O; it does not add runtime APIs or PDF and image rendering for rounded borders.
Watermark Background Image Options
Document Solutions for Excel now preserves the SpreadJS worksheet-level backgroundImage.paintOrder setting, including normal and over-content, during SJS and SSJSON import, export, and cross-format conversion.
Excel does not have an equivalent over-content watermark concept, so this setting is ignored when exporting to Excel formats. Rendering, printing, and PDF export behavior are unchanged.
Cell Scenarios
SJS and SSJSON lossless I/O now preserve SpreadJS cell scenarios used for What-If Analysis. This includes named scenario definitions, input-cell overrides, applied-scenario state, and stored base values required to restore the workbook state.
The SpreadJS-specific scenarioAdditionalInfo structure is preserved where needed even though it has no corresponding OOXML model.
Round-Trip New SpreadJS v19.2 Workbook Features
C#:
var workbook = new Workbook();
workbook.Open("spreadjs-v19-2-features.sjs");
workbook.Save("spreadjs-v19-2-features-roundtrip.sjs");
Java:
Workbook workbook = new Workbook();
workbook.open("spreadjs-v19-2-features.sjs");
workbook.save("spreadjs-v19-2-features-roundtrip.sjs");
New File Format Support in Document Solutions Data Viewer v9.2
Support for Loading XLTX Files
Document Solutions Data Viewer (DsDataViewer) v9.2 adds support for loading XLTX files, allowing users to open and view Excel template workbooks directly in the JavaScript component. XLTX is now available as a first-class file type alongside the previously supported Excel formats.
The Open dialog includes XLTX in the Data Type list, and the file picker accepts files with the .xltx extension. Applications can also open XLTX files programmatically by passing FileType.XLTX to the openFile method.

The new XltxOpenOptions type gives developers control over how workbook content is presented. Options include showing hidden and very hidden sheets, displaying hidden rows or columns, showing filters, preserving row and column groups, and supplying a password for protected XLTX files. Existing default behavior keeps hidden sheets, rows, and columns concealed while retaining filters and worksheet groups.
Load Excel Template Files in a JavaScript Data Viewer
import { DsDataViewer, FileType } from '@mescius/ds-dataviewer';
const viewer = new DsDataViewer('#root');
await viewer.openFile('Documents/template.xltx', FileType.XLTX);
Developers can also pass XLTX-specific options when opening a file:
await viewer.openFile(
'Documents/template.xltx',
FileType.XLTX,
{
showHiddenSheets: true,
showHiddenRows: true,
showHiddenColumns: true,
showFilters: true,
keepRowGroups: true,
keepColumnGroups: true,
password: '123'
}
);
Performance Benchmark Demo Page and Local Package
Document Solutions for Excel v9.2 introduces new Performance Benchmark demo pages and downloadable local benchmark packages for both Document Solutions for Excel .NET and Document Solutions for Excel Java.
The hosted pages provide a static overview of the benchmark scenarios, recommended parameters, measurement methodology, privacy behavior, and result interpretation. Rather than presenting hosted benchmark numbers as authoritative, the pages direct developers to download and run the benchmark package locally. Results can vary based on hardware, operating system, runtime version, installed product package, workbook structure, warmup settings, and repetition count.
The local packages include scenarios for generating a large workbook, opening a generated XLSX, opening and saving XLSX, calculating formulas, exporting PDF, and testing a user-provided workbook. Uploaded workbooks remain on the local machine and can be tested through Open, Open + Save, Open + Calculate, and Open + Export PDF operations.
Benchmark Common Excel API Workflows on Your Own Machine

API Reference Documentation Improvements
Document Solutions for Excel v9.2 includes broad improvements to the .NET and Java API reference documentation. API summaries, remarks, cross-references, and examples have been expanded and standardized to make it easier to identify where a feature belongs and how an API should be used.
Examples have been added where they provide meaningful implementation guidance, while low-value or redundant examples are excluded for enum values, constructors, common object methods, deprecated APIs, and selected internal capability abstractions. Java API references follow standardized Javadoc conventions, while .NET references use consistent XML documentation and cref links for IntelliSense and generated documentation.
Ready to Try Document Solutions for Excel v9.2?
With PivotTable grouping, Custom XML APIs, safer CSV export options, configurable invalid-formula handling, improved Excel equation and Form Control preservation, and richer PDF, image, and HTML output, Document Solutions for Excel v9.2 gives developers more control over advanced spreadsheet workflows across .NET and Java.
The release also improves compatibility between Document Solutions for Excel and SpreadJS through automatic AI function-name conversion and lossless support for several SpreadJS v19.2 features. Document Solutions DataViewer v9.2 extends the browser-based viewing experience with XLTX support, allowing Excel template files to be opened through the user interface or JavaScript API. Combined with the new downloadable performance benchmarks and expanded API reference documentation, these updates make it easier to build, test, view, and maintain production spreadsheet applications.
Ready to explore the release? Download the latest .NET or Java release of Document Solutions for Excel today.


