/**
* ChartsheetXform — parse and render OOXML chartsheet XML.
*
* A chartsheet is a simple sheet type that contains only a chart.
* Structure (ECMA-376 `CT_Chartsheet`):
* ```xml
*
* ?
*
* ?
* ?
* ?
* ? CT_CsPageSetup — NOT CT_PageSetup
* ?
*
* ? legacyDrawingHF? drawingHF? picture? webPublishItems? extLst?
*
* ```
*
* Note that chartsheets do NOT support `printOptions`, `pageBreaks`,
* `rowBreaks`, or `colBreaks` — those are worksheet-only elements
* per ECMA-376 `CT_Chartsheet`. Likewise `` on a
* chartsheet is `CT_CsPageSetup`, which has a reduced attribute set
* compared to the worksheet's `CT_PageSetup` (no `scale`,
* `fitToWidth`, `fitToHeight`, `pageOrder`, `cellComments`, or
* `errors`).
*/
import { BaseXform } from "../base-xform.js";
import type { XmlSink } from "../../../../xml/types.js";
export interface ChartsheetModel {
/** Sheet number (positional index in the XLSX archive) */
sheetNo: number;
/** Sheet name (from workbook.xml) */
name: string;
/** Sheet ID (from workbook.xml) */
id: number;
/**
* Tab order index — the 0-based position in the workbook's
* `` list, shared between worksheets and chartsheets so a
* combined sort preserves the author's interleaved layout. Assigned
* at add time (monotonic across both add paths) and at load time
* (from the workbook.xml `` ordinal).
*/
orderNo?: number;
/** Relationship ID linking to this chartsheet from workbook.xml.rels */
rId?: string;
/** Sheet visibility state */
state?: "visible" | "hidden" | "veryHidden";
/** Tab selected */
tabSelected?: boolean;
/** Zoom scale */
zoomScale?: number;
/**
* `CT_ChartsheetViewBase/@workbookViewId` — 0-based index into the
* workbook's `` list that this chartsheet view is bound
* to. Defaults to 0 per OOXML schema; round-tripped verbatim so
* multi-view workbooks don't get their view hierarchy rewritten.
*/
workbookViewId?: number;
/**
* `CT_ChartsheetViewBase/@zoomToFit` — when true the chartsheet
* scales its content to fill the window. Schema default is false;
* captured/written only when explicitly set to preserve round-trip.
*/
zoomToFit?: boolean;
/** Page margins */
pageMargins?: {
l?: number;
r?: number;
t?: number;
b?: number;
left?: number;
right?: number;
top?: number;
bottom?: number;
header?: number;
footer?: number;
};
/**
* Chartsheet page setup — `CT_CsPageSetup`.
*
* Note the attribute set differs from the worksheet `CT_PageSetup`:
* - **Supported**: paperSize, firstPageNumber, orientation,
* usePrinterDefaults, blackAndWhite, draft, useFirstPageNumber,
* horizontalDpi, verticalDpi, copies, paperHeight, paperWidth
* - **Not supported on chartsheets** (worksheet-only, will be
* silently ignored on write): scale, fitToWidth, fitToHeight,
* pageOrder, cellComments, errors
*/
pageSetup?: {
paperSize?: number;
firstPageNumber?: number;
orientation?: "default" | "portrait" | "landscape";
usePrinterDefaults?: boolean;
blackAndWhite?: boolean;
draft?: boolean;
useFirstPageNumber?: boolean;
horizontalDpi?: number;
verticalDpi?: number;
copies?: number;
/** Paper height in a unit-of-measure string (e.g. "11in", "297mm"). */
paperHeight?: string;
/** Paper width in a unit-of-measure string (e.g. "8.5in", "210mm"). */
paperWidth?: string;
/**
* Relationship id referencing a `printerSettings` part. Preserved
* verbatim through round-trip so an already-authored
* `xl/printerSettings/…` rel target keeps its XML reference from
* the chartsheet. Previously this attribute was dropped by the
* parser and never emitted by the writer, leaving the printer-
* settings part accessible via the chartsheet's `.rels` but
* unreferenced from the chartsheet XML — a dangling-rel-reverse
* that strict validators flag.
*/
rId?: string;
};
/** Drawing relationship reference */
drawing?: {
rId: string;
};
/** Relationships parsed from the chartsheet .rels file */
relationships?: any[];
/** Drawing part name without extension (e.g. drawing2) */
drawingName?: string;
/** Classic chart number displayed by this chartsheet */
chartNumber?: number;
/** ChartEx number displayed by this chartsheet */
chartExNumber?: number;
/**
* Raw XML captured for elements the structured parser doesn't model
* (`sheetPr`, `sheetProtection`, `customSheetViews`, `headerFooter`,
* `legacyDrawing`, `legacyDrawingHF`, `drawingHF`, `picture`,
* `webPublishItems`, `extLst`). The writer emits these verbatim at
* the correct schema position so a round-trip through a workbook
* that uses chartsheet-specific features (e.g. password-protected
* chartsheets, printer-defined header/footer blocks) doesn't lose
* them.
*
* Keys are the element local name (e.g. `"sheetPr"`); values are the
* full `…` serialised bytes.
*
* Note: `rowBreaks`, `colBreaks`, and `pageBreaks` are NOT captured —
* per ECMA-376 `CT_Chartsheet` they are worksheet-only elements.
* Similarly `printOptions` is worksheet-only. Legacy on-disk
* chartsheets that erroneously contained them are silently
* discarded on load to produce schema-valid output on save.
*/
rawChildren?: Record;
}
declare class ChartsheetXform extends BaseXform {
private inSheetView;
/**
* Raw-capture state for elements the structured parser doesn't model.
* When `parseOpen` sees one of the names in {@link RAW_CAPTURE_TAGS}
* at depth-1 of ``, it starts recording the full
* serialised XML (open tags, text, nested children, close tags) into
* `captureParts`. The recording ends when `parseClose` fires with
* the matching root name; the assembled string is stored under
* `model.rawChildren[rootName]` for verbatim re-emission by
* {@link render}.
*
* Without this, elements like `` (password-protected
* chartsheets) and `` silently disappeared on
* round-trip, breaking the author's layout / security configuration.
*
* `sheetDepth` tracks nesting depth inside ``: the root
* itself sits at depth 1, its direct children at depth 2. Capture
* only ever starts at depth 2 so a nested element whose local name
* happens to overlap with one in {@link RAW_CAPTURE_TAGS} (e.g. an
* `` inside `` as a leaf of that subtree)
* stays part of the outer capture rather than being promoted to a
* sibling root child.
*/
private captureRoot;
private captureDepth;
private captureParts;
private skipNextCaptureClose;
private sheetDepth;
get tag(): string;
render(xmlStream: XmlSink, model?: ChartsheetModel): void;
parseOpen(node: any): boolean;
parseText(text: string): void;
parseClose(name: string): boolean;
}
export { ChartsheetXform };