Skip to content

File Formats

Formulon focuses on modern Office Open XML and binary spreadsheet formats. The same calculation core sits behind every reader and writer, so the format layer is responsible for shape preservation and feature mapping rather than calculation behavior.

Glossary: OOXML

Office Open XML — the ISO/IEC 29500 family of zipped XML formats Microsoft Office uses, including .xlsx, .xlsm, and .xltx. Each .xlsx is a ZIP container whose parts (workbook, sheets, styles, shared strings, relationships, …) describe the document.

Glossary: passthrough part

A workbook part that Formulon parses just enough to preserve on save without claiming semantic ownership. The bytes survive a recalculation round-trip even when the engine does not evaluate the feature.

XLSX

The OOXML reader/writer handles:

  • workbook parts and relationships,
  • worksheets and their cells, formulas, and cached values,
  • styles, number formats, fonts, fills, borders, themes,
  • shared strings,
  • tables and defined names,
  • comments and threaded comments,
  • hyperlinks,
  • merges,
  • data validations,
  • conditional formatting,
  • pivot tables and pivot caches,
  • external links,
  • phonetic (furigana) annotations, including per-run UTF-16 spans and their phoneticPr rendering properties,
  • protection metadata,
  • sheet views, freeze panes, hidden tabs,
  • per-row / per-column overrides.

Worksheet print settings are editable through typed setters for page setup, margins, print options, print area, print titles, header/footer, and manual row/column breaks. Raw XML setters remain available for modeled gaps, and malformed fragments are rejected before they are stored. External-link formulas use the index-spelled forms bound to the package's external-link table; path-spelled [Book1.xlsx]Sheet1!A1 references are not resolved.

Phonetic runs and rendering properties round-trip through XLSX and XLSB. Font theme scheme values also round-trip, so a theme-linked Normal font remains linked after save.

Caching behavior

On load, formula cells keep both the formula text and the cached value found in the file. After recalc(), the cached values are replaced with the engine's computed values; on save, the file contains coherent formula / value pairs.

XLSB

The binary workbook path models and emits styles (BrtFmt/BrtXF), row/column layout, merges, date1904, view/zoom/frozen panes, dynamic-array metadata, and supported tokenized formulas. XLSB pivot cache definitions, cache records, and pivot-table parts are decoded into the pivot model and evaluated when their record encoding is supported; unmeasured encodings are skipped rather than guessed. Existing XLSB worksheet tails are preserved verbatim: conditional formatting, data validation, hyperlinks, auto-filter, print setup/breaks, drawing/table references, and their relationships. Preservation is not the same as editable or evaluated support. Unsupported formulas may downgrade to cached literals; saveWithDiagnostics(WorkbookFormat.Xlsb) reports the count as downgradedFormulaCount (Python: save_with_diagnostics(WorkbookFormat.XLSB) and downgraded_formula_count).

| XLSB feature | Current behavior | | --- | --- | --- | | Styles (BrtFmt / BrtXF) | modeled and emitted | | Row/column layout, merges | modeled and emitted | | date1904, view/zoom/frozen panes | modeled and emitted | | Dynamic-array metadata and supported tokenized formulas | modeled and emitted | | Pivot cache and PivotTable parts | evaluated when the record encoding is supported; unmeasured encodings are skipped | | Worksheet tails and relationships | preserved verbatim, not editable/evaluated | | Unsupported formulas | may downgrade to cached literals; downgrade count is reported |

Do not infer comment or pivot preservation from this tail-preservation rule. Keep a source workbook and verify the emitted package when those features matter.

Saving is explicit about container format: saveAs(format) / save_as(fmt) take a WorkbookFormat to choose XLSB over XLSX. saveWithDiagnostics(format) / save_with_diagnostics(fmt) use the same selector and expose partial loss counters, while readDiagnostics() / read_diagnostics() expose counters captured during load. The CLI derives its output choice from the -o path's extension (-o out.xlsb writes MS-XLSB; anything else writes OOXML). Loading, in contrast, is content-sniffed: loadBytes() / Workbook.load() detect XLSX vs XLSB from the bytes themselves (ZIP signature vs BIFF12 record stream), not from a file name, so a .xlsb payload loads correctly even without a matching extension.

The panel below writes one workbook into both containers and hands each result straight back to loadBytes(), with no file name to go on. The counters are whatever saveWithDiagnostics() reported for that write; an all-zero panel means none of the losses above occurred on it, not that the write went unchecked. Load a workbook of your own to see the counters move.

Write one workbook as XLSX and as XLSB

The same workbook is written into both containers with saveWithDiagnostics(), then each output is handed back to loadBytes(). Loading is content-sniffed, so the bytes open correctly with no file name and no extension to go on.

Powered by the real Formulon engine (WASM) — it runs entirely in your browser, nothing is uploaded.

What is preserved vs. evaluated

InputReadWriteOutput*.xlsx / *.xlsb bytes inReaderEvaluated partscells · formulas ·defined names · tables ·CF subsetPassthrough partscharts · drawings · formcontrols · VBAEngine recalcPreserved as bytesWriter*.xlsx / *.xlsb bytes outInputReadWriteOutput*.xlsx / *.xlsb bytes inReaderEvaluated partscells · formulas · definednames · tables · CF subsetPassthrough partscharts · drawings · formcontrols · VBAEngine recalcPreserved as bytesWriter*.xlsx / *.xlsb bytes out
FeatureReadRecalculateWrite
Formulas in cellsyesyesyes
Styles / number formatsyesn/ayes
Defined names / tablesyesyes (resolved as references)yes
Conditional formattingyespartial (evaluate subset)yes
Pivot tableslayout / cachenoyes
Chartsparts preservednoyes
Form controls / drawingspassthroughnoyes
VBA projectpassthroughneveryes

VBA is preserved, not run

Workbooks containing VBA can round-trip through Formulon, but macros are never executed. Calculations that depend on macro-side state will diverge from Excel.

Non-goals

  • Legacy .xls (BIFF) read / write.
  • CSV is supported only via simple ingestion; rich Excel CSV quoting edge cases are not the target.
  • Live external connections (PowerQuery, OLE DB, Web).