XLSB save emits empty 6-byte calcChain.bin stub — Excel rebuilds calc chain on open (10+ min hang)

Hi,

In Aspose.Cells for .NET 26.4.0, Workbook.Save(path, new XlsbSaveOptions()) writes a 6-byte stub for xl/calcChain.bin regardless of how many formula cells the workbook contains. The same workbook saved as XLSX via new OoxmlSaveOptions(SaveFormat.Xlsx) writes a 151-byte stub for xl/calcChain.xml. In both cases the stub contains zero c entries, so when Excel opens the file it has to rebuild the entire calculation chain cold. On a real-world customer workbook (~52 MB, hundreds of sheets, hundreds of thousands of formula cells) this hangs Excel for 10–15 minutes on first open. After a manual Save-As in Excel, the same workbook opens in under a minute — the only difference is that Excel writes a proper, populated calcChain.

We have searched the public API surface (WorkbookSettings, WorkbookSettings.FormulaSettings, XlsbSaveOptions, OoxmlSaveOptions, LoadOptions) via reflection and tried every formula-related property we found. None of them change the output. We would like to know whether (a) there is an API we missed for emitting a real calc chain, or (b) this is a defect that needs a fix.

Minimal repro

Standalone .NET 9 console project, attached as AsposeXlsbCalcChainRepro.zip. Builds a workbook with 100,000 input rows × 4 formula columns (400,000 formula cells), calls CalculateFormula, saves as XLSB and XLSX, then inspects the resulting zip entries.

AsposeXlsbCalcChainRepro.zip (29.7 KB)

For comparison, the customer workbook that Excel re-saved locally contains an xl/calcChain.bin of 47,522,811 bytes — i.e. a real, fully populated calc chain. The Aspose-saved version of the same workbook is the 6-byte stub.

What we have ruled out

  • Format does not matter: XLSB stub is 6 bytes, XLSX stub is 151 bytes. Both are empty in the sense that they contain no c entries.
  • CalculateFormula() does not matter: skipping it produces the same stub.
  • Workbook.Settings.FormulaSettings.EnableCalculationChain = true has no effect on the saved file.
  • Workbook.Settings.FormulaSettings.CalculateOnSave = true (the default) has no effect.
  • Workbook.Settings.MaxRowsOfSharedFormula = int.MaxValue has no effect.
  • CalcModeType.Automatic vs Manual has no effect.
  • The older Workbook.Settings.CreateCalcChain property mentioned in some Aspose documentation does not exist on WorkbookSettings in 26.4.0.

Environment

  • Aspose.Cells for .NET 26.4.0 (NuGet)
  • .NET 9.0
  • Windows 11
  • Behavior is independent of whether the source workbook was created in-process (synthetic repro) or loaded from a real customer XLSB

What we are asking

  1. Can Aspose.Cells 26.4.0 be made to emit a real, populated xl/calcChain.bin (or xl/calcChain.xml) via existing public API? If yes, which combination of WorkbookSettings, LoadOptions, SaveOptions, or method calls is required?
  2. If no — please treat this as a defect. The end state we need is Workbook.Save(path, new XlsbSaveOptions()) producing a file whose xl/calcChain.bin is the full calc chain that Excel would have written for the same workbook (so that Excel does not have to rebuild it cold on open).
  3. If a fix is going to take time, please suggest a supported workaround. We considered post-processing the saved zip to delete xl/calcChain.bin entirely (forcing Excel to treat the file as having no chain at all rather than an empty one), but we are not sure whether that produces a different open-time path in Excel or just hits the same rebuild.

Thanks,
Oded Belahousky

@oded.b

Hi,

Thank you for providing the code snippet and the comprehensive test project, including the AsposeXlsbCalcChainRepro/.gitignore, .vs directory metadata, .csproj, Program.cs, and README.md files.

We have successfully reproduced the issue using Aspose.Cells for .NET 26.4. Our investigation confirms that when saving to XLSB format, the engine is indeed emitting a 6-byte stub for the calcChain.bin file despite the presence of a large volume of formulas. This behavior forces Microsoft Excel to perform a full recalculation and rebuild the calculation chain upon opening the file, leading to the significant performance hangs you described.

We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): CELLSNET-60201

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

@oded.b

As one component designed for and used in user’s applications, the performance of its apis within the application is our primary consideration. For most situations, users do not need to construct the formula calculation chain while processing one workbook with Aspose.Cells, so by default we do not enable the calculation chain(it can be enabled by FormulaSettings.EnableCalculationChain, but mainly for calculating formulas with apis such as Workbook.CalculateFormula()). Even with this option being enabled, it is hard for us to generate the exactly same chain data with ms excel when saving the workbook. And for your case, if there are so large amount of formulas with complicated recursive dependencies, tracing all changes in the model to determine and update the formula chains accordingly will be a very time-consuming process and it will cause another performance issue for your application.

To avoid data inconsistency, we currently clear all existing formula chains when saving the workbook. For the new ticket/requirement attached with your case, whether it can fit your requirement if we saving the original chains data back to the resultant file when we find the cells data has not been modified? If yes we will investigate it further and try to support it for you.

Hi, Thank you for the detailed explanation — that clarifies why we hit this on XLSB
and why our reflection-based knob hunt came up empty.
Yes, the proposal to preserve the original calcChain back to the resultant file
when cell data has not been modified would fit our most painful production case
exactly. The customer workbook that triggered the issue enters our pipeline with
a fully populated xl/calcChain.bin (47 MB), and the dominant path through
Aspose.Cells on that file is: load → Workbook.CalculateFormula() → Save(…,
new XlsbSaveOptions()). If the chain on disk survives this round-trip,
Excel opens the saved file in well under a minute instead of 10–15 minutes.
Before we commit to relying on it, two clarifying questions about your “cell
data has not been modified” check, so we can predict which of our flows benefit:

  1. Does Workbook.CalculateFormula() count as a modification? The call updates
    cached cell values but leaves the formula strings, dependency graph, and
    structure untouched. Our customer’s path is calc-then-save with no other
    edits, so this is the key case.
  2. Cell-level granularity vs workbook-level: if our code modifies a few cells
    (for example, populating ExTable result rows or removing DR.* custom
    formulas in our Export-As-Values flow), would the original chain be
    preserved for cells that weren’t touched, or do any modifications anywhere
    in the workbook drop the entire chain?
    A secondary related ask, if it’s not a large lift: for workbooks generated
    in-process via the Aspose.Cells API (no source file, therefore no source
    chain), is there a planned/possible mode in which Workbook.Save can write a
    calcChain.bin built from the in-memory dependency graph that
    Workbook.CalculateFormula() already produced? We hit this less often than the
    preservation case, but it would close the loop for files we build from scratch.
    Happy to provide additional traces, files, or to test pre-release builds when
    the preservation path is ready.

@oded.b

Thank you for your follow-up and for confirming that the proposed preservation logic aligns with your production requirements.

To clarify your technical inquiry: currently, calling CalculateFormula does trigger internal modification flags. This is because the calculation engine may update cell values or metadata, which typically necessitates a refresh of the calculation chain to ensure data integrity. Regarding your request for a feature to generate a new calcChain.bin for in-memory workbooks, we have noted this as a significant enhancement request for our development team to consider alongside the preservation fix.

We understand that the current behavior leads to significant delays for large XLSB files when Excel is forced to rebuild the chain. Our developers are investigating the feasibility of both preserving the existing chain when modifications are absent and potentially generating a valid chain for newly created or modified workbooks.

We will keep you updated on the progress of these investigations as soon as more information becomes available.

@oded.b

Thank you for your feedback. Before reply your questions about specific apis and cell changes, let me explain the situation that may cause calculation chains change.

For most formulas/functions, changing cell data/value only will not change the formula calculation chain. For example, if A2’s formula is “=A1+B1”, then it always depends on A1 and B1 no matter what values you set/change for A1 and B1.

However, if A2’s formula is “=IF(A1>2,B1,C1)”, then when A1’s value is greater than 2, A2’s dependency is B1, otherwise its dependency is C1. So when you changed A1’s value, the formula chain for A2’s formula may be changed. And it is same for the situation that A1 is also a formula and references to other cells(then changing other cells will change A1’s calculated value, and then influence the chain of A2). There are also some other similar functions, such as CHOOSE, SWITCH, etc., which also can change the calculation chain when the dependent values change.

So, for your questions:

Generally it won’t influence the calculaton chains, unless some formulas were calculated as different results than those in the original template file and there are some formulas such as the IF(…) in above example which depend on those changed results.

It depends on the concrete formulas you used in your workbook too. Generally it is workbook level because there is no limit for formulas to reference to cells of other sheets. Of course, only when there are those special formulas/situations such kind of operations count as modification for the calculation chain.

We will add this requirement into our plan, however, it is complicated for us so maybe we cannot support it soon. We will create one ticket for it so you can trace the progress accordingly.

For this:

As we have said in my first reply, for performance consideration for most general situations, by default we do not build the calculation chain in memory. To build and save it to the resultant file, you need to enable the FormulaSettings.EnableCalculationChain and then call Workbook.CalculateFormula() before saving the workbook

@oded.b
We have opened the following new ticket in our internal issue tracking system for your requirement about building calculation chain in memory and saving it to resultant file after calculating formulas. We will deliver its fix according to the terms mentioned in Free Support Policies.

Issue ID(s): CELLSNET-60202

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

@johnson.shi Any updates on this?

@TsahiB.Datarails

Thank you for following up on this issue.

I would like to inform you that the ticket is currently being investigated by our development team. We are analyzing the internal logic responsible for generating the calculation chain within the XLSB format to ensure it aligns with Excel’s requirements and avoids the rebuild delay you described.

We will keep you updated on the progress and notify you here as soon as a fix or a significant update is available. Thank you for your patience.

The issues you have found earlier (filed as CELLSNET-60201) have been fixed in this update. This message was posted using Bugs notification tool by leo.luo.