Skip to content

Sheetwrite 0.6.0

Sheetwrite 0.6.0: charts, pivot tables, reference operators, OFFSET and INDIRECT, iterative calculation, the ribbon, kept XLSX parts and the upgrade checklist.
npm install @sheetwrite/core@0.6.0
Update each adapter and add-on you use to 0.6.0 too: all packages release together.
On this page

Sheetwrite 0.6.0 adds charts and pivot tables, Excel's reference operators and iterative calculation, and an optional Excel-style ribbon. XLSX files keep the parts Sheetwrite does not model. All eight packages release as 0.6.0, including the new optional @sheetwrite/charts. Read the breaking changes first: they affect apps that call the engine's CellStore directly, rely on manual volatile recalculation, or block data: images.

Highlights

  • Charts. Column, bar, line, area, pie, doughnut and scatter charts live in the workbook, float over the cells, and redraw when their data changes. @sheetwrite/charts draws them as SVG.
  • Pivot tables. The full engine calculates pivot tables and updates only the affected groups after an edit. Insert and edit them from the ribbon, and read and write them in XLSX files.
  • More formulas. Intersection, union and 3-D references, OFFSET and INDIRECT, volatile RAND and RANDBETWEEN, and the cell information functions.
  • Iterative calculation for circular references, with Excel's settings.
  • Excel-style ribbon, a grouped context menu, cell notes in the grid, and Excel's status line totals.
  • XLSX files keep what Sheetwrite does not model: charts, pivots, images, VBA and other parts are written back unchanged. Edits that would invalidate a kept chart, pivot or image drop it with a warning.

New

Charts

A sheet holds up to 100 charts in Sheet.charts. Each chart has up to 32 series that read cell ranges on any sheet. setChart and removeChart work with undo, sync and snapshots, and row, column and sheet edits update chart ranges as formulas do. In the grid, a chart floats at its anchor: select, move and resize it with the pointer or keyboard, and insert or edit it from Insert › Chart.

@sheetwrite/charts is optional, and core does not depend on it. Import @sheetwrite/charts/register to draw every chart as SVG, or use createChartViewCache(store) to give your own renderer the resolved chart data. Workbooks without charts do not change in speed or memory.

Pivot tables

Pivot definitions are part of the workbook: getPivots, setPivot, removePivot, getPivotFields and getPivotResult on grids and stores, kept in snapshots, undo, collaboration and engine memory transfers. The full engine calculates the output and, after a source edit, updates only the affected groups. SUM and AVERAGE add values exactly, so an edit gives the same result as a new calculation. Insert › PivotTable opens a field list beside the grid.

The default engine does not calculate pivots. It shows the values Excel saved in an XLSX file as read-only output that formulas can read, and the Insert › PivotTable command says that pivot tables need the full engine.

XLSX import reads pivot tables into definitions, and export writes pivot parts that Excel and LibreOffice recalculate on open. Pivots that use features a definition cannot hold stay as kept parts, with a warning.

Formulas

  • Reference operators in both engines. A space intersects two references (=SUM(A1:C3 B2:D4)), parentheses with commas make a union (=SUM((A1:A2,C1:C2))), and =SUM(Jan:Mar!B2) reads the same cells on a span of sheets. INDEX gains area_num, and AREAS counts the areas. See Operators.
  • OFFSET and INDIRECT return references, so their results can feed reference-taking functions, LAMBDA and the array helpers, or spill. See Lookup and reference functions.
  • Volatile functions recalculate after each edit, as in Excel: RAND, RANDBETWEEN, TODAY, NOW and the formulas that read them. TODAY and NOW read the clock once per recalculation. See Volatile functions.
  • Cell information: FORMULATEXT, ISFORMULA, HYPERLINK and CELL (address, col, contents, row, type).
  • Iterative calculation. The setCalculation operation sets { iterate, maxIterations, maxChange }, with Excel's defaults: off, 100 iterations, 0.001. It is undoable, part of the snapshot, and read from and written to XLSX <calcPr>. See Iterative calculation.

Grid and shell

  • Ribbon. config.ribbon: true adds Home, Insert, Data and View tabs whose groups fold as the grid narrows. It loads as its own chunk, so grids without a ribbon do not download it. New GridActions cover borders, fonts, vertical alignment, wrap, number formats, merge and center, AutoSum, find and freeze panes. See Toolbar and ribbon.
  • Context menu. Shorter, grouped, with submenus and full keyboard use. Custom menus can use submenus and icons. See Context menu.
  • Command icons come from one icon sheet that follows the text color. Replace glyphs with GridConfig.icons.
  • Cell notes show on hover and open an editor with Shift+F2 or grid.actions.editNote(). See Notes.
  • Status line and name box. Grid.summarizeSelection() returns Count, Sum, Average, Min and Max of the visible selected cells; the shell shows Excel's Average, Count and Sum. The name box selects ranges such as B2:D9. See Status bar.
  • Cell style fields: fontFamily, verticalAlign and a per-cell numberFormat, all round-tripped through XLSX.

XLSX and CSV

  • Kept parts. Opening and saving keeps charts, pivot tables, images, VBA projects, customXml, XML maps, data connections, themes and document properties as their original bytes in WorkbookSnapshot.workbook.xlsxSource. maxPreservedBytes (64 MiB by default) bounds them. See Kept parts and round trips.
  • Tables keep autofilter rules, sort state, calculated columns and totals-row functions.
  • Streaming: toCsvStream, toTsvStream, toXlsxTableStream and toXlsxWorkbookStream return a ReadableStream, and fromXlsxWorkbookFile imports a Blob without buffering every part. See Streaming functions.
  • Lower import memory. Import builds snapshot cells while it reads rows and parses worksheets in bounded chunks.

Breaking changes

ChangeWhat to do
@sheetwrite/wasm and @sheetwrite/formulas remove 10 CellStore methods that Sheetwrite did not call: canDirtyCell, dirtyRevision, markCellCleanRevision, hydratePageNumbers, hydratePageStringsPacked, spillOwnerCoordinates, isSheetAlive, pinRange, styleIdAt and sortRows. SourceSnapshot.byteLength() is removed too. Grid and store APIs do not change.If you call the engine directly: use sortRowsMulti with one key instead of sortRows, getCell(...).style instead of styleIdAt, and setSparseBlock inside beginPageLoad/commitSources instead of hydratePage*. Caller-owned pinRange pins are gone; viewport and read-window pins work as before.
RAND, RANDBETWEEN, TODAY, NOW and the formulas that read them recalculate in every transaction that changes a cell. Before, they recalculated only when you called recalculateVolatile.Nothing, unless your app relied on volatile values staying fixed between recalculateVolatile calls. recalculateVolatile(date) still sets the time until the next edit.
Command icons default to an inline data: URL.If your Content Security Policy blocks data: images, serve @sheetwrite/core/icons.svg and set --sheetwrite-icon-sheet: url("/path/to/icons.svg").

Changed

  • Imported XLSX layout matches Excel. Cells with no vertical alignment are bottom-aligned, column widths use the OOXML conversion (about 5 pixels narrower than before), and automatic row heights stay automatic. See LibreOffice compatibility.
  • Import no longer writes the default font size onto every cell; only cells with a different size get fontSize.
  • Column aggregates on dense sheets match paged sheets, as in Excel: formula results that are TRUE, FALSE or blank are ignored, and spilled values count.
  • Undo history is bounded by snapshot size. The oldest entries drop once retained range snapshots pass 256 MiB; the newest entry always stays undoable.
  • An active search stays current. On sheets with formulas, it rescans after each edit, which can cost more than before but keeps computed matches correct.
  • Wrapped text never breaks inside an emoji sequence, a flag or a letter with combining marks.

Fixed

  • renderer: "worker" works without workerUrl in bundled apps; Vite builds the worker with its imports instead of falling back to the main thread.
  • Render windows no longer paint columns past the last column, rows past the end, or unloaded cells with another cell's fill and borders.
  • Filters, sorting, hidden rows and row groups reconcile the displayed rows, selection and scroll position before change listeners run, including after undo, redo and remote operations.
  • Long formula chains no longer overflow the stack in circular-reference and nesting checks, and many formulas over the same large ranges no longer take quadratic memory.
  • Hyperlinks keep their explicit font colors and underline settings, and a link without display text shows its cell text.

Performance

These results compare one fresh 0.5.4 capture with one 0.6.0 capture of each suite, on the same machine and toolchain. Times vary by device and workload. The release comparison lists every measurement, its threshold and the capture conditions.

Faster paths

Formulas

  • Edit one input read by 100,000 formulas60% faster54.0 ms → 21.7 ms
  • Recalculate 1,000 formulas in cycles65% faster1.41 ms → 0.50 ms
  • Propagate an error through 1,000 formulas66% faster0.73 ms → 0.25 ms
  • Place a 100,000-cell spill62% faster11.4 ms → 4.4 ms

Load, undo and import

  • Undo a 1,000,000-cell clear79% faster1.69 s → 0.36 s
  • Load 1,000,000 number-only rows54% faster145 ms → 66 ms
  • XLSX import peak memory33% less310 MiB → 207 MiB

Slower paths

  • Text lookups are slower: about 4% with the default engine and 13% with the full engine, in a controlled re-measurement of 20 fresh processes per side. Both are within the 25% release budget.
  • Rebasing a 100,000-cell block across 50 row inserts takes 3.8 ms instead of 1.7 ms.
  • Revisiting an evicted paged band takes 14.7 ms instead of 8.1 ms, including a fixed settle delay.
  • XLSX export has a 4–11% higher peak memory, and rejecting hostile files (compression bombs, deeply nested XML) takes a few milliseconds longer.
  • The performance showcase in the development server became usable after 1.44 s instead of 1.10 s. Sheetwrite's own long tasks stayed at 0 ms; the site around it grew. This is not a production-bundle measurement.

Upgrade checklist

  1. EveryoneRequired

    Update every package together

    Install 0.6.0 for each @sheetwrite/* package that you use. Packages from different versions are not supported together.

    corewasmformulasxlsxchartsreactvuesvelte

  2. If you call the engine's CellStore directlyBreaking

    Replace the removed methods

    See the breaking changes table for each replacement.

  3. If you use RAND, TODAY or NOWBehavior change

    Expect recalculation after each edit

    Volatile formulas no longer wait for recalculateVolatile.

  4. If your Content Security Policy blocks data: imagesRequired

    Serve the icon sheet

    Serve @sheetwrite/core/icons.svg and set --sheetwrite-icon-sheet to its URL.

  5. If you import XLSX filesBehavior change

    Expect Excel's alignment and widths

    Cells with no alignment are bottom-aligned, and columns are about 5 pixels narrower, as Excel shows them.

  6. If you want chartsOptional

    Install @sheetwrite/charts

    Import @sheetwrite/charts/register once to draw charts as SVG.

  7. If you want pivot tables calculatedOptional

    Select the full engine

    Install @sheetwrite/formulas and pass it to initSheetwrite(). The default engine shows saved pivot values only.

  8. If you upgrade from before 0.5.4Also do

    Complete the earlier steps first

    Read the 0.5.2, 0.5.1, and 0.5.0 upgrade checklists. 0.5.3 and 0.5.4 have no extra steps.

The full list of changes is in each package's CHANGELOG.md.

Documentation