import { type RichText } from './rich-text'; /** Excel error tokens. */ export type ExcelErrorCode = '#NULL!' | '#DIV/0!' | '#VALUE!' | '#REF!' | '#NAME?' | '#NUM!' | '#N/A' | '#GETTING_DATA'; /** Formula sub-kind — drives the OOXML `` attribute. */ export type FormulaKind = 'normal' | 'array' | 'shared' | 'dataTable'; export interface FormulaValue { readonly kind: 'formula'; readonly formula: string; readonly t: FormulaKind; /** Cached value Excel last computed for the cell, used when `data_only` reads it back. */ readonly cachedValue?: number | string | boolean; /** Range string (`"A1:A10"`) for array / shared / dataTable formulas. */ readonly ref?: string; /** Shared-formula index. */ readonly si?: number; /** Data-table specific fields (mirrors openpyxl DataTableFormula). */ readonly r1?: string; readonly r2?: string; readonly dt2D?: boolean; readonly dtr?: boolean; readonly del1?: boolean; readonly del2?: boolean; readonly aca?: boolean; readonly ca?: boolean; } export type CellValue = number | string | boolean | Date | { kind: 'duration'; ms: number; } | { kind: 'error'; code: ExcelErrorCode; } | { kind: 'rich-text'; runs: RichText; } | FormulaValue | null; export interface Cell { /** 1-based row index. */ row: number; /** 1-based column index. */ col: number; /** Effective cell value. `null` represents an empty cell. */ value: CellValue; /** Index into Workbook.styles.cellXfs. 0 = default. */ styleId: number; /** Optional reference to a Hyperlink registered on the worksheet. */ hyperlinkId?: number; /** Optional reference to a Comment registered on the worksheet. */ commentId?: number; } /** Marker subtype for the placeholder cells inside a merged range (top-left holds the value). */ export interface MergedCell extends Cell { merged: true; } /** Build a fresh Cell. Validates coordinates against the OOXML grid bounds. */ export declare function makeCell(row: number, col: number, value?: CellValue, styleId?: number): Cell; /** Format a Cell's coordinate as the canonical "A1" string. */ export declare function getCoordinate(c: Cell): string; /** * Direct value setter. No type inference, no validation beyond the union — the * caller is in charge. Use {@link bindValue} for the "do what I mean" path. */ export declare function setCellValue(c: Cell, value: CellValue): void; /** * "Smart" setter: infers the cell value from a JS runtime value. * - `string` starting with `=` → formula * - `string` matching an Excel error token → error variant * - other primitives / Date / null pass through verbatim * * Intentionally not the default — explicit is clearer for typed code, and * inferring on every write costs measurable time on the worksheet write hot * path. */ export declare function bindValue(c: Cell, value: number | string | boolean | Date | null): void; /** Plain `=A1+B1` style formula. Cached value is optional but recommended for round-trip. */ export declare function setFormula(c: Cell, formula: string, opts?: { cachedValue?: FormulaValue['cachedValue']; }): void; /** Array (CSE) formula spanning a `ref` range. */ export declare function setArrayFormula(c: Cell, ref: string, formula: string, opts?: { cachedValue?: FormulaValue['cachedValue']; }): void; /** * Shared formula. The first cell in the group carries the formula text + ref; * subsequent cells with the same `si` carry only the index and Excel * reconstructs the formula via reference shifting. */ export declare function setSharedFormula(c: Cell, si: number, formula?: string, ref?: string, opts?: { cachedValue?: FormulaValue['cachedValue']; }): void; /** * Excel data-table formula (``). These appear as the "What-if * Analysis → Data Table" feature output: a 1- or 2-variable sensitivity grid * where the formula references one or two input cells. The wire format mirrors * openpyxl's `DataTableFormula`: * * - `ref` — inclusive cell range the formula spans. * - `r1`, `r2`— input cell coordinates ("$A$1" etc.). * - `dt2D` — true for two-variable tables (uses both r1 and r2). * - `dtr` — row-direction flag (true) vs column-direction (false). * - `del1`/`del2` — Excel marks one of these true when the * corresponding input cell has been deleted; the formula keeps round-tripping * so Excel can show the warning state. * - `aca`/`ca` — alwaysCalculate / calculate flags. */ export interface DataTableFormulaOpts { ref: string; r1?: string; r2?: string; dt2D?: boolean; dtr?: boolean; del1?: boolean; del2?: boolean; aca?: boolean; ca?: boolean; cachedValue?: FormulaValue['cachedValue']; } /** * Set a data-table formula on a cell. Preserves all the dt-specific attributes * so the writer can re-emit `` verbatim and Excel * keeps treating the cell as a Data Table cell. */ export declare function setDataTableFormula(c: Cell, formula: string, opts: DataTableFormulaOpts): void; /** Build a `{ kind: 'error', code }` cell value. */ export declare function makeErrorValue(code: ExcelErrorCode): { kind: 'error'; code: ExcelErrorCode; }; /** Build a `{ kind: 'duration', ms }` cell value. */ export declare function makeDurationValue(ms: number): { kind: 'duration'; ms: number; }; /** True iff `c.value` is the formula variant. */ export declare function isFormulaCell(c: Cell): boolean; /** True iff `c.value` is the rich-text variant. */ export declare function isRichTextCell(c: Cell): boolean; /** Returns true iff the cell has no content. */ export declare function isEmptyCell(c: Cell): boolean; /** * Type guard for `MergedCell` — true iff the cell is a placeholder for a * merged-range covered cell (the top-left of a merged range holds the value; * the rest are `MergedCell`). Use this to filter merge-placeholders out of * value-walking loops. */ export declare function isMergedCell(c: Cell): c is MergedCell; /** Returns true iff the cell holds an Excel error value (`#REF!`, `#NAME?`, …). */ export declare function isErrorCell(c: Cell): boolean; /** * Get the formula text from a formula-bearing cell, or `undefined` for * non-formula cells. Equivalent to: isFormulaValue(c.value) ? c.value.formula : * undefined but spares callers the type-narrow + member access. */ export declare function getFormulaText(c: Cell): string | undefined; /** * Get the cached value Excel last computed for a formula cell, or `undefined` * for non-formula / uncached cells. Useful for `data_only` read paths that want * the displayed result without re-evaluating. */ export declare function getCachedFormulaValue(c: Cell): number | string | boolean | undefined; /** True iff `v` is the formula variant. */ export declare function isFormulaValue(v: CellValue): v is FormulaValue; /** True iff `v` is the rich-text variant. */ export declare function isRichTextValue(v: CellValue): v is { kind: 'rich-text'; runs: RichText; }; /** True iff `v` is the error variant. */ export declare function isErrorValue(v: CellValue): v is { kind: 'error'; code: ExcelErrorCode; }; /** True iff `v` is the duration variant. */ export declare function isDurationValue(v: CellValue): v is { kind: 'duration'; ms: number; }; export interface CellValueAsStringOptions { /** Renderer for `Date` cells. Defaults to `d => d.toISOString()`. */ dateFormat?: (value: Date) => string; /** Replacement for the `null` cell value. Defaults to `''`. */ emptyText?: string; } /** * Coerce a CellValue to its plain-string display form. Numbers / booleans * convert via `String`; rich text concatenates run text; formulas yield the * cached value (or empty string when uncached); errors yield their Excel token; * durations yield `" ms"` with no formatting; Dates yield * `Date.toISOString()`; `null` yields `""`. * * Pass `opts.dateFormat` to override the Date renderer (e.g. a locale-specific * format) and `opts.emptyText` to substitute a different placeholder for * `null` cells. */ export declare function cellValueAsString(v: CellValue, opts?: CellValueAsStringOptions): string; /** * Coerce a CellValue to `boolean | undefined`. Booleans pass through; `'TRUE'` * / `'true'` and `'FALSE'` / `'false'` (case-insensitive) parse to true / * false; numbers yield `false` for 0 and `true` for any other finite value * (matching Excel's truthy-number coercion); formula cells return their cached * boolean if any. Everything else (null, Date, error, duration, rich-text, * non-bool strings) yields `undefined`. */ export declare function cellValueAsBoolean(v: CellValue): boolean | undefined; /** * Coerce a CellValue to a `Date` when one is meaningful. Pass-through for * `Date`-typed values; ISO-8601 strings (anything `new Date(s)` parses to a * finite time) round-trip; durations are interpreted as `new Date(ms)`. * Numbers, booleans, formulas, errors, rich text, and null all return * `undefined` — this helper does **not** apply the Excel-serial-to-Date * conversion (use `excelToDate` for that). */ export declare function cellValueAsDate(v: CellValue): Date | undefined; /** * Coerce a CellValue to a number when one is meaningful. Booleans yield 0/1; * numeric strings parse via `Number(s)`; rich-text concats then parses; * formulas with a numeric cached value pass through. Returns `undefined` when * there's no sensible numeric reading (text strings, errors, dates, durations, * null, empty). */ export declare function cellValueAsNumber(v: CellValue): number | undefined; /** * Map a CellValue to the most natural JS primitive for display / export. * Unlike `cellValueAsString`/`cellValueAsNumber`/etc., which each force a * single target type and return `undefined` when the value can't be coerced, * this returns whatever primitive best represents the union variant: * * - `null` → `null` * - `string` / `number` / `boolean` / `Date` → passthrough * - rich text → joined run text (`string`) * - formula → recursive on `cachedValue` (`null` when uncached) * - error → error code (`string`) * - duration → `ms` (`number`) */ export declare function cellValueAsPrimitive(v: CellValue): string | number | boolean | Date | null;