/** * Public worksheet tables collection (`Worksheet.tables`) over the * `CT_Table` wire model (TASK-1210) and the `tableParts` / table-part * plumbing. * * Citations: * - ECMA-376-1 §18.5 (`table`, `tableColumn(s)`, `tableStyleInfo`) * - transitional sml.xsd `CT_Table` / `CT_TableColumns` / `CT_TableColumn` / * `CT_TableStyleInfo` / `ST_TotalsRowFunction` / `ST_TableType` * - docs/specs/tables.md (public API + behavior contracts), * docs/ooxml-mapping/tables.md * * Semantics: * - `Table.name` is the schema-required `@displayName` (unique per sheet). * - `table@id` values are workbook-unique, allocated as max+1, never * renumbered. * - Formulas are opaque text (leading `=` stripped on authoring, never * evaluated per `.agent/policies/security.md`). * - The grid stays sparse for body rows: `add` does not allocate data cells. * Empty header-row cells are filled with the derived column names so * `tableColumn@name` matches sheet text (Excel repairs tables when headers * are missing under `table@ref`). */ import { TableEntry, TableColumnEntry } from './table-model'; export { defaultAuthoredTableStyleInfo } from './table-model'; /** * SpreadsheetML `ST_TableType` tokens (`worksheet` | `xml` | `queryTable`). * Authored tables are always worksheet tables; non-worksheet kinds are load * preservation only. Not part of the published package surface (`stripInternal`). * * @private */ export declare type TableType = 'worksheet' | 'xml' | 'queryTable'; /** * The table kind as read from a file: a known type, or an unrecognized * value kept exactly as it appears. * @private */ export declare type TableTypeOrRaw = string; /** * True when `value` is one of the defined `ST_TableType` values. * @private */ export declare function isKnownTableType(value: string): value is TableType; /** * SpreadsheetML `ST_TotalsRowFunction` tokens used by the table model. * @private */ export declare type TotalsRowFunction = 'none' | 'sum' | 'min' | 'max' | 'average' | 'count' | 'countNums' | 'stdDev' | 'var' | 'custom'; /** * The totals-row function as read from a file: a known function such as * `sum`, or an unrecognized value kept exactly as it appears. * @private */ export declare type TotalsRowFunctionOrRaw = string; /** * True when `value` is one of the defined `ST_TotalsRowFunction` values. * @private */ export declare function isKnownTotalsRowFunction(value: string): value is TotalsRowFunction; /** * Describes how a table looks, naming its style and choosing whether to * emphasize its first column, last column, or banded rows and columns. */ export interface TableStyle { /** * The built-in or custom table style used — for example * `'TableStyleMedium9'`. */ name: string | undefined; /** Whether the first column is emphasized with special formatting. */ showFirstColumn: boolean; /** Whether the last column is emphasized with special formatting. */ showLastColumn: boolean; /** Whether alternate rows are shaded (banded rows). */ showRowStripes: boolean; /** Whether alternate columns are shaded (banded columns). */ showColumnStripes: boolean; } /** * Represents one column of a table, letting you set its name and totals-row * settings. * @private Not part of the published package surface. */ export interface TableColumn { /** * The column's heading text, shown in the header row. Unique within the * table. * @private */ name: string; /** * The calculation shown in the totals row, as a built-in function name * like `'sum'` or `'average'`. * @private */ totalsRowFunction: TotalsRowFunctionOrRaw; /** * The label shown in the totals row, instead of a calculation. * @private */ totalsRowLabel: string | undefined; /** * The formula used in the totals row, when a custom one replaces the * built-in function. * @private */ readonly totalsRowFormula: string | undefined; /** * Whether the totals-row formula is an array formula (one that produces * multiple results). Set via {@link TableColumn.setTotalsRowFormula}. * @private */ readonly totalsRowFormulaIsArray: boolean; /** * The formula Excel fills the whole column with when a row is added — * for example `=[@Qty]*[@Price]`. * @private */ readonly calculatedColumnFormula: string | undefined; /** * Whether the calculated-column formula is an array formula. Set via * {@link TableColumn.setCalculatedColumnFormula}. * @private */ readonly calculatedColumnFormulaIsArray: boolean; /** * Set the formula used in the totals row. An optional leading `=` is * stripped; the formula is stored as text and never evaluated. * * @param text - The formula text, or `undefined` to remove it. * @param options.isArray - Whether the formula is an array formula. * @private */ setTotalsRowFormula(text: string | undefined, options?: { readonly isArray?: boolean; }): void; /** * Set the formula Excel fills the whole column with. An optional leading * `=` is stripped; the formula is stored as text and never evaluated. * * @param text - The formula text, or `undefined` to remove it. * @param options.isArray - Whether the formula is an array formula. * @private */ setCalculatedColumnFormula(text: string | undefined, options?: { readonly isArray?: boolean; }): void; } /** * Represents a table in a worksheet, letting you set its name, style, and * totals row. */ export interface Table { /** The table's name, shown in Excel's table tools. */ name: string; /** * The cells the table covers, written as an A1-style range — for * example `'A1:D10'`. */ readonly range: string; /** A note attached to the table; `undefined` when there is none. */ readonly comment: string | undefined; /** * The table's kind as read from the file (opaque string). Authored tables * are always ordinary worksheet tables. Unknown wire values are kept * exactly as read. */ readonly tableType: string; /** * The number of rows in the table's header. Default `1`. */ readonly headerRowCount: number; /** * The table's visual style — its color scheme and banding. `undefined` * leaves the table unstyled. */ style: TableStyle | undefined; /** Whether the table ends with a totals row. */ totalsRowEnabled: boolean; /** * Whether the totals row is visible. A declared totals row can be * hidden while its column calculations stay in place. */ totalsRowShown: boolean; /** * The table's columns, in left-to-right order. * @private Not part of the published package surface. */ readonly columns: ReadonlyArray; } /** * Represents the tables on a worksheet, letting you add, list, and remove * them. */ export interface Tables { /** The number of tables on the worksheet. */ readonly count: number; /** * Get all tables as a list, in the order they appear on the worksheet. * * @returns the current tables. */ list(): ReadonlyArray; /** * Get the table at a zero-based position, in the order tables appear on * the worksheet. * * @param index - The zero-based position of the table. * @returns the table at `index`. * @throws InvalidArgumentError when the index is out of range */ get(index: number): Table; /** * Add a table over a range of cells. Column headings come from the * header row's values (`Column1`, `Column2`, … when empty). Empty header * cells are written with those derived names so the sheet matches * `tableColumn@name` (required for Excel-safe open). Body cells in the * range are not allocated. Set the style, totals row, and column * calculations on the returned table. Authored tables are always * worksheet tables (`tableType` `'worksheet'`). * * @param name - The table's name, unique on the worksheet. * @param range - The cells the table covers, like `'A1:D10'`. Header cells * that were empty are filled with derived column names; data cells are * not created by this call. * @param headerRowCount - The number of header rows; default `1`. * @returns the newly created table. * @throws InvalidArgumentError when `name`/`range` are empty or * `headerRowCount` is invalid * @throws InvalidTableError when the name duplicates an existing table * @throws InvalidAddressError when the range is unparseable/inverted */ add(name: string, range: string, headerRowCount?: number): Table; /** * Remove the table at a zero-based position. * * @param index - The zero-based position of the table to remove. * @throws InvalidArgumentError when the index is out of range */ removeAt(index: number): void; /** * Remove a table previously returned by this collection. * * @param table - The table to remove. * @throws InvalidArgumentError when the table was not created by this * collection */ remove(table: Table): void; /** Remove every table from the worksheet. */ clear(): void; /** * Check whether the worksheet has a table with exactly this name. * * @param name - The table name to look for. * @returns `true` when a table with the name exists. */ has(name: string): boolean; } /** * Host surface the worksheet implementation provides. * @private */ export interface TablesHost { /** Current table entries in file order ({@link WorksheetImpl.internalTables}). */ entries(): ReadonlyArray<{ relId: string; entry: TableEntry; }>; /** * Replace the full set (see {@link WorksheetImpl.internalSetTables}). * `removedRelIds` / `removedPartNames` record package cleanup for dropped tables. */ setEntries(entries: ReadonlyArray<{ relId: string; entry: TableEntry; }>, removedRelIds: ReadonlyArray, removedPartNames: ReadonlyArray): void; /** Allocate the next workbook-unique table id. */ allocateTableId(): number; /** Allocate a fresh worksheet relationship id for a new table part. */ allocateTableRelId(): string; /** Current `tableParts` extra attributes. */ tablePartsExtraAttrsXml(): string; /** * Record a mutation. When `entry` is provided only that table's part is * rewritten on flush (localized mutation); without it the whole tables * layer is conservatively marked (collection structure changed). */ markDirty(entry?: TableEntry): void; /** * Get cell value at row/column coordinates (1-based). Used to derive * column names from header row when creating tables without explicit columns. */ getCellValue(row: number, col: number): string | number | undefined; /** * Write a plain cell value (string/number/clear). Used so totals-row labels * appear in sheetData. Excel expects the label text in the totals row cell * (in addition to `tableColumn@totalsRowLabel`); omitting it leaves * dimension short of `table@ref` and triggers repair on open. */ setCellValue(row: number, col: number, value: string | number | undefined): void; /** * Write or clear formula text on a sheet cell (never evaluates). Required so * built-in / custom totals-row functions match MS-OE376 §2.1.710(n): the * occupied cell formula must be `SUBTOTAL(,)` (or the custom * expression) when `totalsRowCount ≠ 0`. */ setCellFormula(row: number, col: number, expression: string | undefined): void; } /** * Mutable public tables collection implementation. * @private */ export declare class TablesImpl implements Tables { private readonly host; private readonly handles; private readonly columnHandles; constructor(host: TablesHost); readonly count: number; list(): ReadonlyArray
; get(index: number): Table; add(name: string, range: string, headerRowCount?: number): Table; removeAt(index: number): void; remove(table: Table): void; clear(): void; has(name: string): boolean; private assertNameAvailable; private removeEntries; private handleFor; /** @private — column handle creation (called by TableHandle). */ columnHandleFor(col: TableColumnEntry, owner: TableHandle): TableColumn; /** @private — unique-name check used by TableHandle.name setter. */ nameTakenExcluding(displayName: string, self: TableEntry): boolean; /** @private — write totals-row label cells into the sheet grid. */ materializeTotalsRowLabels(entry: TableEntry): void; /** @private — clear former totals-row label cells after totals disabled. */ clearTotalsRowLabels(entry: TableEntry): void; /** * Write `tableColumn@name` into the matching header-row sheet cell. * Excel repairs the table part when header text and column `@name` diverge. * @private */ syncHeaderCellForColumn(entry: TableEntry, column: TableColumnEntry): void; /** @private — column uniqueness within a table, excluding one column. */ columnNameTakenExcluding(table: TableEntry, name: string, self: TableColumnEntry): boolean; } /** * Excel-hostile bare worksheet tables (no `autoFilter`) are schema-legal but * modern Excel removes the table part on repair (observed on * `tables-preserve-middle-removal.xlsx` / Content.MSO logs). Library `add` * already emits a self-closed autoFilter over header+data. When a table part * is rewritten dirty, fill a missing managed autoFilter so the wire stays * Excel-safe. * * Scope: default `worksheet` tables only — never invent filters for * `xml` / `queryTable` / unknown `tableType`. Does not replace a richer * autoFilter. Does **not** invent `tableStyleInfo` here: authors may clear * style via the public API; default Medium2 is applied only on collection * surgery (`ensureDefaultTableStyleInfoIfMissing`) so bare survivors match * `Tables.add` without undoing an intentional clear. * * @private Not part of the published package surface. */ export declare function ensureExcelSafeWorksheetTableSurface(entry: TableEntry): void; /** * Fill default `tableStyleInfo` (Medium2 + row stripes) when a worksheet * table has none — used after collection surgery so bare loaded fixtures * match `Tables.add`. Not used on ordinary dirty flushes (style clear must * round-trip as absent). * * @private Not part of the published package surface. */ export declare function ensureDefaultTableStyleInfoIfMissing(entry: TableEntry): void; /** Live {@link Table} implementation. @private */ export declare class TableHandle implements Table { readonly entry: TableEntry; /** * Relationship id of the backing table part at handle creation. * Flush may densify table rIds after collection surgery; removal uses * the live host entry, not this snapshot. * @private */ readonly entryRelId: string; private readonly owner; private readonly markDirty; constructor(owner: TablesImpl, entry: TableEntry, entryRelId: string, markDirty: () => void); name: string; readonly range: string; readonly comment: string | undefined; readonly tableType: string; readonly headerRowCount: number; style: TableStyle | undefined; totalsRowEnabled: boolean; totalsRowShown: boolean; /** @private Not part of the published package surface. */ readonly columns: ReadonlyArray; /** * Re-write totals-row sheet cells after column totals mutations. * @private */ syncTotalsRowLabels(): void; /** * Keep one header-row sheet cell aligned with `tableColumn@name` after rename. * @private */ syncHeaderCellForColumn(column: TableColumnEntry): void; } /** Live {@link TableColumn} implementation. @private */ export declare class TableColumnHandle implements TableColumn { private readonly entry; private readonly owner; private readonly markDirty; constructor(entry: TableColumnEntry, owner: TableHandle, markDirty: () => void); name: string; totalsRowFunction: TotalsRowFunctionOrRaw | string; totalsRowLabel: string | undefined; readonly totalsRowFormula: string | undefined; readonly totalsRowFormulaIsArray: boolean; setTotalsRowFormula(text: string | undefined, options?: { readonly isArray?: boolean; }): void; readonly calculatedColumnFormula: string | undefined; readonly calculatedColumnFormulaIsArray: boolean; setCalculatedColumnFormula(text: string | undefined, options?: { readonly isArray?: boolean; }): void; }