This page is for the exact SheetJS / xlsx failure mode where a Node service
loads or creates an .xlsx, changes an input cell, then reads a formula cell
and still sees the old cached result.
Short answer: keep SheetJS for file I/O, but add a recalculation step before you trust formula readback.
XLSX formula cells can carry both formula text and a cached value. SheetJS cell
objects expose formula text and cell values, but the Community Edition path is
file-centric. If your process changes Inputs!B2, the cached value in
Summary!B7 does not become fresh just because the source cell changed.
That is fine when Excel, LibreOffice, or another spreadsheet application will open the workbook later and calculate it. It is not fine when a backend route, queue worker, or test must make a decision from the computed value in the same Node process.
If your app already has XLSX bytes from SheetJS, use the SheetJS-named recalculation bridge at the boundary. It keeps SheetJS responsible for file I/O and adds only the missing recalculation/readback step:
npm install @bilig/sheetjs-formula-recalc
One-off proof:
npx --package @bilig/sheetjs-formula-recalc sheetjs-recalc --demo --json
Exact reproduction for the high-view Stack Overflow question:
git clone https://github.com/proompteng/bilig.git
cd bilig
npm --prefix examples/recalc-bridge-workflows install
npm --prefix examples/recalc-bridge-workflows run so:sheetjs-63085785
That script mirrors the small case from
How to recalculate all formulas in excel file through Javascript?:
A1 changes from 1 to 3, SheetJS still has the stale cached C1 = 3,
then @bilig/sheetjs-formula-recalc verifies C1 = 5.
For a real workbook:
npx --package @bilig/sheetjs-formula-recalc sheetjs-recalc pricing.xlsx \
--set Inputs!B2=48 \
--set Inputs!B3=1500 \
--read Summary!B7 \
--out pricing.recalculated.xlsx \
--json
The command writes an updated workbook and prints the values read after recalculation.
import { readFile, writeFile } from 'node:fs/promises'
import { recalculateSheetjsWorkbook } from '@bilig/sheetjs-formula-recalc'
const result = recalculateSheetjsWorkbook(await readFile('pricing.xlsx'), {
fileName: 'pricing.xlsx',
edits: [
{ target: 'Inputs!B2', value: 48 },
{ target: 'Inputs!B3', value: 1500 },
],
reads: ['Summary!B7'],
})
await writeFile('pricing.recalculated.xlsx', result.xlsx)
console.log({
value: result.reads['Summary!B7'],
warnings: result.warnings,
verified: result.warnings.length === 0,
})
The important rule is that your service owns the input cells, output cells, and verification checks. Do not read an arbitrary formula value and assume it is fresh just because an XLSX writer succeeded.
The repository includes a bridge proof that edits the same workbook through
SheetJS/xlsx, xlsx-populate, and ExcelJS, then verifies that Bilig refreshes
the stale 48000 result to 72000 in all three paths:
git clone https://github.com/proompteng/bilig.git
cd bilig
npm --prefix examples/recalc-bridge-workflows install
npm --prefix examples/recalc-bridge-workflows run smoke
Use that example when you are deciding whether to keep your current file library and add recalculation, instead of rewriting the whole workbook pipeline.
| Job | Use |
|---|---|
| Read or write many spreadsheet formats | SheetJS / xlsx |
| Generate a styled XLSX report for a human to open later | SheetJS, ExcelJS, or xlsx-populate |
| Ask Excel to recalculate when someone opens the file | workbook calc properties or Excel itself |
Recalculate SheetJS / xlsx bytes inside Node after changing inputs |
@bilig/sheetjs-formula-recalc |
| Recalculate generic XLSX bytes from another writer | @bilig/xlsx-formula-recalc |
| Keep an ExcelJS workbook and add fresh formula readback | @bilig/exceljs-formula-recalc |
| Own formula-backed workbook state as JSON in a service | @bilig/workpaper |
| Need commercial SheetJS formula calculation support | evaluate SheetJS Pro |
Before using this on a critical path, keep fixtures for:
Bilig is not full Excel. The useful promise is narrower: a Node process can edit known input cells, recalculate supported formulas, read back known output cells, and export a workbook with tests around that boundary.
If this saves you from opening Excel in a backend job just to refresh formula values, star the repository so the fix is easier for the next SheetJS user to find: https://github.com/proompteng/bilig/stargazers.
xlsx npm package:
https://www.npmjs.com/package/xlsx@bilig/sheetjs-formula-recalc npm package:
https://www.npmjs.com/package/@bilig/sheetjs-formula-recalc@bilig/xlsx-formula-recalc npm package:
https://www.npmjs.com/package/@bilig/xlsx-formula-recalc