github cjnoname/excelts v9.3.0

latest release: v9.3.1
8 hours ago

9.3.0 (2026-04-18)

⚠️ Breaking Changes

Three runtime-observable breaks since v9.2.1. Full migration notes in MIGRATION.md.

1. Empty <border> now parses to undefined instead of {} (59f24cf)

Cells referencing borderId=0 (the default empty border) used to populate cell.border with {} (truthy). It now correctly parses to undefined, matching the declared type.

Impact: Truthy-check patterns break.

// Before — accidentally ran for every cell
if (cell.border) { ... }

// After — use optional chaining
if (cell.border?.top || cell.border?.left || ...) { ... }

2. Worksheet.addTable() enforces workbook-wide unique table names (59f24cf)

Duplicate table names (case-insensitive) across the workbook are now rejected at addTable() time. Previously silently accepted, producing XLSX files Excel itself refused to open.

Impact: Code that added same-named tables to different worksheets now throws.

ws1.addTable({ name: "Data", ... });
ws2.addTable({ name: "Data", ... }); // throws — use distinct names

3. { richText: [] } no longer classifies as RichText (fa350f7)

Cell.Value.getType now requires richText.length > 0. Assigning { richText: [] } used to produce a RichText cell (empty-array was truthy); it now falls through to JSON type.

Impact: Serialization and cell.type change for anyone using empty-runs arrays as "empty rich text".

// Before
cell.value = { richText: [] }; // classified as RichText

// After — use one of:
cell.value = null;                         // empty cell
cell.value = "";                           // empty string
cell.value = { richText: [{ text: "" }] }; // zero-length run

Non-breaking but noteworthy

The following changed but remain backward-compatible at runtime:

  • CellModel.richText union widened to CellRichTextValue | RichText[] | undefined for Hyperlink cells with formatted display runs (fa350f7). Readers of cell.model.richText on Hyperlink cells should branch on Array.isArray().
  • HyperlinkValue.text setter now enforces text === flatten(richText) (fa350f7). Setting .text on a hyperlink cell clears stale richText.
  • TableProperties.rows tightened from any[][] to Array<Array<CellValue | CellFormulaValue>> (fa350f7). TypeScript-only; runtime unchanged.

Major Additions (Non-Breaking)

Formula Calculation Engine — new /formula subpath

Standalone 433-function Excel-compatible calculation engine with tokenizer, parser, compiler, evaluator, dependency graph, dynamic-array spill, and LAMBDA/LET/MAP/REDUCE. Zero runtime dependencies.

Two usage modes:

// Mode A: paired with Workbook
import { Workbook } from "@cj-tech-master/excelts";
import { installFormulaEngine } from "@cj-tech-master/excelts/formula";
installFormulaEngine(); // once at startup
wb.calculateFormulas();

// Mode B: standalone — zero excel runtime, any WorkbookLike
import { calculateFormulas } from "@cj-tech-master/excelts/formula";
calculateFormulas(anyWorkbookLikeObject);

Engine is kept out of bundles that don't import it. Tree-shake-verified across esbuild / rolldown / rspack.

Dynamic Array Formulas (Excel 365)

FILTER, SORT, UNIQUE, XLOOKUP, SEQUENCE, spill-error detection, ghost-cell cleanup.

External Workbook Links

[Book.xlsx]Sheet!A1 references now round-trip through load/save.

Workbook Structure Protection + Public APIs

  • Workbook.protection — structure/windows/revision lock
  • Workbook.defaultFont — now public, for round-trip fidelity
  • Image.absoluteAnchor — absolute image positioning
  • Cell.ignoredErrors — suppress Excel's green triangles per cell

Features

  • excel: Add COUP family + BINOM.DIST.RANGE (a7e3e54)
  • excel: Add Excel 365 dynamic array formula support (FILTER/SORT/UNIQUE/XLOOKUP/SEQUENCE) (17e6c22)
  • excel: Add external workbook link support ([Book]Sheet!Ref) (8d0d046)
  • excel: Add formula calculation engine with tokenizer, parser, evaluator, dependency graph, and 220+ Excel functions (6b6c9a8)
  • excel: Add ignoredErrors support, absoluteAnchor images, and reconcilePicture null guard (da34761)
  • excel: Add matrix + series math functions (MMULT, MDETERM, MINVERSE, MUNIT, SERIESSUM) (ee6a094)
  • excel: Add REGEX, VALUETOTEXT, ARRAYTOTEXT, PERCENTRANK, PROB functions (03913e5)
  • excel: Add SQRTPI, ENCODEURL, ACCRINTM, TBILL*, PRICEMAT, YIELDMAT (96813b8)
  • excel: Add workbook structure protection and public defaultFont API (7f15a58)
  • excel: Cast-free hyperlink + formula+hyperlink cell input (86340a0)
  • excel: Harden formula engine — +5000 tests, 30+ bug fixes, 34 new functions, 3D ref + dynamic-array dependency fixes (06b0cf4)

Bug Fixes

  • excel: Fix 21 formula engine bugs, add 13 functions, 2 language features (487079a)
  • excel: Fix data validation sort, empty border truthy, and table name uniqueness (59f24cf)
  • excel: Preserve formula+hyperlink and rich-text on round-trip (#142) (fa350f7)
  • excel: SUBTOTAL/AGGREGATE full Excel semantics, totals-row SUBTOTAL codes, multi-area mask merging (128c54c)
  • excel: Support range operator ':' with dynamic refs, add 50+ functions, fix SUBTOTAL/AGGREGATE semantics (f912857)
  • Update TypeScript linting rules — add no-misused-spread and no-useless-default-assignment (480b7c0)

Code Refactoring

  • excel: Replace old formula engine with new compile→evaluate→materialize pipeline (b747df7)
  • formula: Promote to top-level module with standalone entry + strict defined-name classification (b34fe81)

Don't miss a new excelts release

NewReleases is sending notifications on new releases.