Skip to content

Workbook

Individual workbook within a model. Contains Sheets which contain Cells. Contains its own dependency graph, for now at least, so no dependencies between workbooks.

  • emitter

_cellContainerForGlobals: CellContainer


_cellsWithErrors: VertexIdSet<CellVertexId | NameVertexId>

Vertex ID keys of cells with errors.


_errors: ModelError[] = []


_errorsByMsg: object = {}

[message: string]: ModelError


_globals: Record<string, DefinedName> = {}


_iterativeCalculationSettings: null | IterativeCalculationOptions


_model: Model


_rangeWrites: RangeVertexId[] = []

VertexIDs of range writes applied in this workbook. Redundant with this._writes, maintained separately just for quick checking.


_sheets: WorkSheet[] = []


_state: undefined | "uploading" | "processing" | "ready" | "invalid" | "replaced"


_tables: Map<string, Table>


_writes: Map<string, CellValue>

Map keyed by strings, where each string is the key of a Vertex ID


cellEvaluator: CellEvaluator


cellsWithNeutralizedFormulas: Set<Cell | DefinedName>


charts: ChartCSF[]


cloud_connection: null | CloudConnection


coerceNullToZero: CoercionMode = COERCE_NONE

Dummy declaration for type checker, overridden with defineProperty in constructor

EvaluationContext.coerceNullToZero


defect: null | string


evaluateASTNode: (ast) => MaybeBoxedFormulaArgument

Evaluate an expression, expressed as an AST node, in this context. NOTE: this must be a function, not arrow function, and be invoked on an evaluation context, so that it captures the correct this context.

ASTNode

MaybeBoxedFormulaArgument

EvaluationContext.evaluateASTNode


externals: External[]


getWorkbookByKey: (key) => undefined | Workbook

Get the workbook with the given dependency-graph key (based uniquely on the workbook name in a case-insensitive way by the wbNameToKey function).

number

undefined | Workbook

EvaluationContext.getWorkbookByKey


id: string


instanceId: number


isExternal: boolean

Whether this workbook was loaded as an external reference from another workbook.


keyInDepGraph: number


metadata: GridMetadata


mode: WorkbookMode

EvaluationContext.mode


name: string


names: DefinedName[] = []


ready: boolean = false


replacedBy: null | string = null

reserved for outside use (client loader)


resolveName: (name, sheetName?) => FormulaError | DefinedName

Get the cell object for the given defined name (matched case-insensitively) in the indicated scope or in this context. If sheetName is given, then only sheet-scoped defined names will be considered, not workbook-scoped defined names. If this context permits cross-workbook name resolution, then a match in the current workbook will be preferred but if no match is found there, then the first match across all workbooks in model order will be returned. If no match is found, #NAME? is returned.

string

null | string

FormulaError | DefinedName

EvaluationContext.resolveName


resolveSheet: (sheetName?, workbookName?) => null | WorkSheet

Get the sheet with the given name (matched case-insensitively), or the first sheet of the context workbook if no name is given. The context workbook is the default (first) workbook of the model if not evaluating in the context of a specific workbook.

null | string

null | string

null | WorkSheet

EvaluationContext.resolveSheet


resolveTable: (name, workbookName?) => null | Table

Get the table with the given name (matched case-insensitively) in the context workbook, or if not found there, then in the first workbook in the model that contains a table by this name.

string

null | string

null | Table

EvaluationContext.resolveTable


resolveWorkbook: (name?) => undefined | Workbook

Get the workbook with the given case-insensitive name, or if no name is given, the context workbook, or the default (first) workbook of the model if not evaluating in the context of a specific workbook.

null | string

undefined | Workbook

EvaluationContext.resolveWorkbook


sheetNameToIndex: object = {}

[name: string]: number


readonly styles: StyleManager


type: "unknown" | "airtable" | "notion" | "smartsheet" | "csv" | "excel" | "form-submissions" | "google-sheets" | "native"

The origin of the workbook (Excel, Google Sheets, CSV, etc).


update_time: undefined | string


version: undefined | number


optional views: WorkbookView[]


workbookName: string = ''

Dummy declaration for type checker, overridden with defineProperty in constructor

EvaluationContext.workbookName


writeState: () => any

any

EvaluationContext.writeState

get editable(): boolean

boolean


get env(): Map<"isPrint" | "isMobile" | "username", MaybeBoxedFormulaArgument>

Map<"isPrint" | "isMobile" | "username", MaybeBoxedFormulaArgument>

EvaluationContext.env


get errorLevel(): number

number


get errors(): ModelError[]

ModelError[]


get lazyImportPromise(): Promise<void>

Promise<void>

_addSheet(sheetName, index, hidden): WorkSheet

string

number

0 | 1 | 2

WorkSheet


_applyCalcCellResult(newValue, cell, ref, recordDependencyUse?): object

MaybeBoxedFormulaValue

result of formula evaluation

the cell whose formula was evaluated

Cell | DefinedName

Reference

Reference to the cell

(ref) => void

optional callback for recording dependencies during recalc

object

change: number | boolean

changedRefs: Reference[]


_applyWrite(refStr, value, oldSheetCount, oldSheetIndex): void

Write value value to the given reference, or to the same address in the sheet with index oldSheetIndex if sheet count matches oldSheetCount

string

CellValue

number

null | number

void


_clearExistingModelErrors(vertexId): void

CellVertexId | NameVertexId | RangeVertexId

void


_createFormulaRewriterForColumnDeletion(sheet, column, count): RewriteFormula

Create a formula rewriting function for column deletion. This does NOT actually delete any cell data - it only creates a function that rewrites formulas to account for deleted columns (e.g., updating references or converting them to #REF! errors).

WorkSheet

The worksheet where columns are being deleted

number

0-based column index of the first column to delete

number

The number of columns being deleted

RewriteFormula

A function that rewrites formulas to reflect the column deletion


_createFormulaRewriterForRowDeletion(sheet, row, count): RewriteFormula

Create a formula rewriting function for row deletion. This does NOT actually delete any cell data - it only creates a function that rewrites formulas to account for deleted rows (e.g., updating references or converting them to #REF! errors).

WorkSheet

The worksheet where rows are being deleted

number

0-based row index of the first row to delete

number

The number of rows being deleted

RewriteFormula

A function that rewrites formulas to reflect the row deletion


_createRewriteFormulaFunction(from, to): RewriteFormula

A1Reference

A1Reference

RewriteFormula


_createRewriteFormulaFunctionForDelete(deleteRef): RewriteFormula

A1Reference

RewriteFormula


_getExistingCachedFormulaCell(formula, prefix): object

string

string = CACHED_FORMULA_CELL_ID_PREFIX

object

cell: null | DefinedName

id: string


_hasRangeWriteContaining(vertexId): boolean

CellVertexId

boolean


_insertSheet(sheet, index): WorkSheet

WorkSheet

number

WorkSheet


_markCellsReferencingRemovedSheetForRecalculation()

Section titled “_markCellsReferencingRemovedSheetForRecalculation()”

_markCellsReferencingRemovedSheetForRecalculation(sheetBeingRemoved): void

WorkSheet

void


_moveCellsByColumn(sheet, column, moveBy): RewriteFormula

Move all cells to the right or left of a column index.

WorkSheet

number

0-based column index

number

the number of positions to move the cells by. If negative, then the cells are moved to the left

RewriteFormula


_moveCellsByRow(sheet, row, moveBy): RewriteFormula

WorkSheet

number

0-based row index

number

the number of positions to move the cells by. If negative, then the cells are moved up

RewriteFormula


_refPointsToAnotherWorkbook(reference): boolean

Reference

boolean


_removeError(modelError): void

ModelError

void


_rewriteFormulasReferencingRenamedSheet(sheet, currentName, newName): void

Precondition: formula parser has finished importing (formulaParserReady has resolved).

WorkSheet

string

string

void


_unneutralizeFormulas(): void

Reinstate formulas previously neutralized by a write

void


_updateDependenciesForWrittenFormulaCells()

Section titled “_updateDependenciesForWrittenFormulaCells()”

_updateDependenciesForWrittenFormulaCells(): void

void


_updateParsedFormula(cell): void

Precondition: formula parser has finished importing (formulaParserReady has resolved).

a cell object representing a global defined name (that restriction is relevant so that cell.id is its complete cell address, because that assumption is made here.)

Cell | DefinedName

void


_updateValueAndSpills(cellRef, cell, newValue, isRangeWrite?): Reference[]

Given a formula cell in a sheet, replace its existing value with a newly calculated one, in the case where either the new value or the previous value (or both) is a matrix. Determine and apply any blocking/unblocking of other spilling formula cells that should result from this change.

Reference

A reference pointing to cell. Must be an address (not name) reference.

Cell

The sheet formula cell whose value will be replaced

The new value.

MaybeBoxed<CellValue> | Matrix

boolean = false

passed to Cells.updateValueAndSpills, see documentation there

Reference[]

references to all areas whose cells may have changed, with the area spilled by cell (or a single-cell ref to just that cell if it did not spill) appearing first, followed by any other areas which may have changed due to spill blocking/unblocking.


_writesIter(): IterableIterator<[string, CellValue, KnownVertexId]>

Precondition: Workbook must be initialized

IterableIterator<[string, CellValue, KnownVertexId]>


addError(modelError): null | ModelError

ModelError

null | ModelError


addSheet(sheetName?, index?): WorkSheet

Add a new empty sheet to the workbook

if no sheet name is provided a unique sheet name will be generated

null | string

number

if no index is provided the sheet will be appended to the list of sheets

WorkSheet


allDefinedNames(): IterableIterator<DefinedName>

IterableIterator<DefinedName>


applyWritesFrom(oldWorkbook): void

Workbook

void


calcCell(cell, checkDirty?, recordDependencyUse?): CellChangeRecord

Calculate a new value for the given cell in this workbook. The cell should either be a formula cell, or be a value cell which was previously a formula cell, which gets passed here in order to calculate the spilling effects of its change to a value cell. The cell’s unconditional static dependencies are all assumed to be already up-to-date. The up-to-dateness of any other dependencies is checked and an EvaluationOrderException is thrown if any are not up-to-date). Assign the new value to the cell, and possibly to other cells due to spilling. Return information about all cells changed.

Precondition: Workbook is initialized and has data.

Cell | DefinedName

boolean = true

true (the default) to check for dirty states of dependency cells and throw EvaluationOrderException; false to disable this check

undefined | (ref) => void

CellChangeRecord

a cell change record in which:

  • change is the change in the cell value (numeric if the cell value changed from a number to another number, else true if the cell value changed but not from a number to a number, else false).
  • changedRefs is a list of references to cell ranges which changed.

clearCachedFormula(formula): undefined | null

undefined | null | string

undefined | null


clearCachedFormulasExcept(formulas): void

string[]

void


clearCells(ref): boolean

Precondition: Workbook must be initialized

A reference to the cell, or range of cells, to clear. Defined names are not supported.

string | Reference

boolean

true if any changes were made (so a recalculation is in order).


deleteColumns(sheetName, columnIndex, count): RewriteFormula

Delete count columns at a specific index in the given sheet.

string

number

0-based column index

number

how many columns should be deleted

RewriteFormula


deleteRows(sheetName, rowIndex, count): RewriteFormula

Delete count rows at a specific index in the given sheet.

string

number

0-based row index

number

how many rows should be deleted

RewriteFormula


emit(event, …arguments_): Emitter

Emit an event, invoking all handlers registered for it.

string

The name of the event to emit.

any[]

Arguments to pass to the event handlers.

Emitter

The Emitter instance for method chaining.

EventEmitter.emit


evaluateAST(ast, options): MaybeBoxedFormulaValue

Evaluate a formula in the form of an AST, in a given evaluation context. This wraps the evaluateAST function as a Workbook method, just to enable calling it via evaluation context to dodge circular imports.

ASTRootNode

Partial<EvaluationContext>

MaybeBoxedFormulaValue

EvaluationContext.evaluateAST


getCachedFormulaCell(formula, calculateIfNew, prefix): null | DefinedName

Get or create a cached-formula defined-name object for the given formula. Calculate its value unless false is passed for calculateIfNew.

undefined | null | string

boolean = true

string = CACHED_FORMULA_CELL_ID_PREFIX

null | DefinedName


getCell(cellId, sheetName?): null | Cell

string

null | string

null | Cell


getGlobal(name): FormulaError | DefinedName

string

FormulaError | DefinedName


getSheet(sheetName?): null | WorkSheet

null | string

null | WorkSheet

the named sheet if sheetName is truthy (null if not found), else the first sheet.


getSheetByIndex(index?): null | WorkSheet

Get a sheet of the given index or else, if index is not provided, the first sheet of this workbook.

the index of a sheet

null | number

null | WorkSheet

the sheet found at the given index, or else the first sheet if none was given. If no sheets are present this method returns null.


getSheetIndex(sheetName?): null | number

Get the order index of a sheet with the given name.

string

the name of the sheet whose index should be returned. It will be matched case-insensitively.

null | number

The index of the sheet with the given name, or null if no sheet with that name exists, or 0 if no/empty name was given.


getSheets(): WorkSheet[]

WorkSheet[]


getSheetSize(sheetName?): [number, number]

Get the size of a sheet with the given name.

the name of the sheet whose size should be returned. It will be matched case-insensitively. If not provided, or empty, the size of the first sheet (0, 0) is returned.

null | string

[number, number]

The size of the sheet with the given name, or null if no sheet with that name exists, or (0, 0) if no/empty name was given.


getTable(name): null | Table

string

null | Table


getTableContainingCell(sheet, cell): null | Table

WorkSheet

Cell

null | Table


getTables(): Table[]

Table[]


hasListeners(event): boolean

Check if there are any handlers registered for a specific event.

string

The name of the event.

boolean

true if there are one or more handlers, false otherwise.

EventEmitter.hasListeners

hasListeners(): boolean

Check if there are any handlers registered for any event.

boolean

true if there are one or more handlers for any event, false otherwise.

EventEmitter.hasListeners


hasWrite(vertexId): boolean

CellVertexId | NameVertexId

boolean


insertColumns(sheetName, columnIndex, count, toTheRight): RewriteFormula

Insert count columns at a specific index in the given sheet.

string

number

0-based column index

number

how many columns to insert

boolean

determines whether the inserted columns are inserted to the left or right of the column at columnIndex.

RewriteFormula


insertRows(sheetName, rowIndex, count, below): RewriteFormula

Insert count rows at a specific index in the given sheet.

string

number

0-based row index

number

how many rows to insert

boolean

determines whether the inserted rows are inserted below or above of the row at rowIndex.

RewriteFormula


isDependencyRoot(sheetIndex, row, column, ignoreRangeDependencies): boolean

Determines whether the specified cell has one or more incoming dependencies but no outgoing ones.

number

0-based sheet index

number

0-based row index

number

0-based column index

boolean = false

if set to true, then a cell won’t be considered a root if it only appears in range references

boolean


isGlobal(name): boolean

string

boolean


iterFormulaCells(): IterableIterator<Cell | DefinedName>

IterableIterator<Cell | DefinedName>


listenerCount(event): number

Get the count of listeners for a specific event.

string

The name of the event.

number

The number of listeners for the event.

EventEmitter.listenerCount

listenerCount(): number

Get the count of all event handlers in total.

number

The total number of event handlers.

EventEmitter.listenerCount


listeners(event): (…arguments_) => void[]

Retrieve the event handlers registered for a specific event.

string

The name of the event.

(…arguments_) => void[]

An array of functions registered as handlers for the event.

EventEmitter.listeners


moveCells(from, to): RewriteFormula

Precondition: formula parser has finished importing (formulaParserReady has resolved).

Must be the same dimensions as to

string | A1Reference

Must be the same dimensions as from

string | A1Reference

RewriteFormula


moveColumns(sheetName, from, to, count): RewriteFormula

string

number

0-based index of first column to move

number

0-based index of end-position of first column to move

number

the number of columns to move

RewriteFormula


moveRows(sheetName, from, to, count): RewriteFormula

string

number

0-based index of first row to move

number

0-based index of end-position of first row to move

number

the number of rows to move

RewriteFormula


neutralizeFormulaCell(cell): void

Transiently mark the given cell as not a formula cell (because of a value write). This can be reversed by calling unneutralizeFormulaCell, and that happens automatically on reset.

Cell | DefinedName

void


off(event, listener): Emitter

Remove a specific event handler for a specified event.

string

The name of the event.

(…arguments_) => void

The specific handler function to remove.

Emitter

The Emitter instance for method chaining.

EventEmitter.off

off(event): Emitter

Remove all event handlers for a specified event.

string

The name of the event for which to remove all handlers.

Emitter

The Emitter instance for method chaining.

EventEmitter.off

off(): Emitter

Remove all event handlers for all events.

Emitter

The Emitter instance for method chaining.

EventEmitter.off


on(event, listener): Emitter

Register an event handler that listens to a specified event.

string

The name of the event to listen to.

(…arguments_) => void

The function to execute when the event is emitted.

Emitter

The Emitter instance for method chaining.

EventEmitter.on


once(event, listener): Emitter

Register a one-time event handler for a specified event.

string

The name of the event to listen to.

(…arguments_) => void

The function to execute once when the event is emitted.

Emitter

The Emitter instance for method chaining.

EventEmitter.once


recordWrite(vertexId, value): void

KnownVertexId

CellValue

void


removeDefinedName(name, sheetName?): boolean

Remove a defined name (global or sheet-scoped) from the workbook. This will schedule cells depending on that name for recalculation, but will not perform that recalculation.

string

the name of the defined name to remove. It will be matched case-insensitively.

the name of a sheet the defined name is scoped to, null if it is a global defined name. It will be matched case-insensitively.

null | string

boolean

true if the name was removed, false if it did not exist (or the sheet did not exist)


removeSheet(sheetName): boolean

Remove a sheet from the workbook.

string

the name of the sheet to delete. It will be matched case-insensitively.

boolean

true if the sheet was removed, false if it did not exist

if there are writes that have not been reset


renameSheet(currentName, newName): void

Rename the given sheet to a new name, updating all formulas referencing it Precondition: formula parser has finished importing (formulaParserReady has resolved).

string

string

must be different from currentName

void

if no sheet exists named currentName


reset(): void

void


resetDefinedNames(): void

Assign static-reference values to defined names, or if not static, record them as requiring initial recalculation.

void


resetModel(): void

void


rewriteFormulas(rewriteFormula): number

(formula) => string

number

number of formulas changed


rowHeight(rowIndex, sheetName): number

Height of the given column in the given sheet, in pixels.

number

1-based row index

string

name of the sheet in which to look up a row height

number


setColumnWidth(sheetName, column, width): void

string

number

0-based column index

number

non-negative

void

if there is no sheet with sheetName in this workbook, or if col and/or width are invalid


setDefinedName<AbortOnError>(name, formula, sheet?, abortOnError?, validateNow?): DefinedName | AbortOnError extends true ? null : never

Add a defined name in this workbook with the given formula. If any error is detected in the formula (syntax error, or use of something we do not support), abort and return null if abortOnError is true, else go ahead and make the defined name but record the error with this.addError.

AbortOnError extends boolean = false

string

string

sheet to scope the name to, or null for workbook scope

null | WorkSheet

AbortOnError

true to return null and make no change if formula has any errors

boolean = true

set to false to skip formula validation here (caller is responsible for it then)

DefinedName | AbortOnError extends true ? null : never


setRowHeight(sheetName, rowNum, height): void

Sets the height of a row.

One function, SUBTOTAL, may yield different results depending on whether some cells in the range belong to hidden rows or not. Therefore, if the row becomes hidden, or was hidden before this change, a recalculation of formulas referencing cells in the affected row will be required. This call will register state about that, so that the next recalculation will update formula cells as needed. It is up to the caller to make sure a recalculation is eventually triggered.

Precondition: Workbook is initialized.

string

number

0-based row index

number

non-negative

void

if there is no sheet with sheetName in this workbook, or if rowNum and/or height are invalid


sheetHasBeenPruned(sheetName): boolean

string

boolean


state(newState?, defect?): object

"uploading" | "processing" | "ready" | "invalid"

null | string

object

defect: null | string

id: string

state: undefined | "uploading" | "processing" | "ready" | "invalid" | "replaced"

update_time: undefined | string


toCSF(): CSFOutput

CSFOutput


toJsf(): JSF

Serialize this workbook to JSF (JSON Spreadsheet Format).

This is the inverse of Workbook.fromJsf, producing a JSF object that can be used to reconstruct the workbook state.

JSF

A JSF object representing this workbook


toXlsx(): Promise<Buffer<ArrayBufferLike>>

Convert this workbook to XLSX format and return the result as a Buffer.

This method converts the workbook to JSF format first, then generates an XLSX file from that representation.

Promise<Buffer<ArrayBufferLike>>

A Promise resolving to a Buffer containing the XLSX file data


toXlsxFile(path): Promise<void>

Convert this workbook to XLSX format and write it to a file.

This method converts the workbook to JSF format first, then generates an XLSX file from that representation and writes it to the specified path.

string

The file path to write the XLSX file to

Promise<void>


unneutralizeFormulaCell(cell): void

Revert the action of neutralizeFormulaCell, reinstating the formula.

Cell | DefinedName

void


updateCellResetState(ref): void

Update the reset state of the cell referenced by ref. The reference can be to a cell in a sheet, or a defined name in the Workbook.

Reference

void


updateDependencies(vertexIDs?): void

(CellVertexId | NameVertexId)[]

void


write(ref, val, neutralizeFormulaOnSingleCellWrite?): boolean

Write the given value to the given cell (A1 address or global name)

Precondition: Workbook must be initialized

the address or global name to write to

string | Reference

CellValue

the value to write

boolean = false

set to true if writes to single formula cells should neutralize them

boolean

true if a write occurred


writeCellData(cellRef, cellData): Cell | DefinedName

Write the given cell data attributes (.v, .f, etc.) to an existing or new cell.

If cell value is an error value, normalize it to the corresponding singleton error value in errorTable.

If cellData has a formula, it is parsed and (if parsing succeeds) the AST is stored in the cell object.

If cellData has an .f attribute (whether null or not), the whole workbook’s dependency graph is rebuilt (unless you pass false for rebuildDependencyGraph).

Preconditions:

  • Formula parser has finished importing (formulaParserReady has resolved).
  • Workbook must be initialized.

the cell to write, as a Reference or a string representing one. If this indicates a range, the top-left cell of that range is written. This must not be a name reference as this method does not support those yet.

string | Reference

Omit<Cell, "s" | "f" | "v"> & object & object & object

object with attributes to write to the cell

Cell | DefinedName

the existing or new Cell instance.

if precondition is not satisfied (the formula parser has not finished importing), or if a string is passed and it fails to parse as a Reference.


writes(): [string, CellValue][]

Precondition: Workbook must be initialized

[string, CellValue][]


static fromCsf(csf, model, options): Workbook

Create a Workbook from CSF format directly, bypassing JSF conversion. This provides significantly better performance than converting CSF→JSF→Workbook.

WorkbookCSF

Workbook data in CSF format

Model

The Model instance to attach this workbook to

WorkbookOptions = {}

Workbook initialization options

Workbook

A new Workbook instance populated from CSF


static fromJsf(jsf, model, options): Workbook

Create a Workbook from JSF format.

JSF

Workbook data in JSF format

Model

The Model instance to attach this workbook to

WorkbookOptions = {}

Workbook initialization options

Workbook

A new Workbook instance populated from JSF


static fromXlsx(data, model, filename, options?): Promise<Workbook>

Create a Workbook from XLSX binary data.

This is a convenience method that wraps @borgar/xlsx-convert to load XLSX data directly into a Workbook without requiring users to manually import the conversion library.

Note: This creates only the main workbook. External references in the XLSX file are not automatically added to the model. Use Model.addWorkbookFromXlsx to also add externals.

Binary XLSX data (works in browsers and Node.js)

ArrayBuffer | Buffer<ArrayBufferLike> | Uint8Array<ArrayBufferLike>

Model

The Model instance to attach this workbook to

string

Filename to associate with the workbook

WorkbookOptions

Workbook initialization options

Promise<Workbook>

A Promise resolving to a new Workbook instance


static fromXlsxFile(path, model, options?): Promise<Workbook>

Create a Workbook from an XLSX file path.

This is a convenience method that wraps @borgar/xlsx-convert to load XLSX files directly into a Workbook without requiring users to manually import the conversion library.

Note: This creates only the main workbook. External references in the XLSX file are not automatically added to the model. Use Model.addWorkbookFromXlsxFile to also add externals.

string

Path to the XLSX file (Node.js only - uses fs)

Model

The Model instance to attach this workbook to

WorkbookOptions

Workbook initialization options

Promise<Workbook>

A Promise resolving to a new Workbook instance