import { BodyElement, SectionProperties, Table } from '../core/document-model/index.js'; import { CellRange, DefinedName, ParsedWorksheet, SheetRichRun, WorksheetCell, XlsxStyles } from './index.js'; import { SheetHyperlink, SheetSlicer } from '../core/ir/sheet.js'; import { Loss } from '../core/ir/loss.js'; /** * Excel "character width" → twips: the default font's Maximum Digit Width, * ~7 px at 96 DPI ≈ 5.25 pt ≈ 105 twips. */ export declare const TWIPS_PER_EXCEL_CHAR = 105; /** * ECMA-376 §18.3.1.13 — a `` measures characters of text, and the * rendered column is that many Maximum Digit Widths PLUS a fixed 5-pixel * padding: `px = chars × MDW + 5`. 5 px at 96 DPI = 3.75 pt = 75 twips. * * Omitting it made every column 75 twips narrow, which compounds: on a sheet of * equal 12-character columns the third one landed ~37 pt left of where * LibreOffice puts it. That {@link DEFAULT_COL_TWIPS} below is 960 is the proof * the padding belongs — 8.43 characters only reaches Excel's documented 64 px * default with it (8.43 × 7 + 5 = 64.01 px = 48.01 pt = 960 twips), so the * default was derived from the full formula while the explicit path dropped it. */ export declare const COL_PADDING_TWIPS = 75; /** * §18.3.1.13 — a `` in twips. * * The padding above is the formula for a column at least one character wide. * Excel documents a SEPARATE one below that: `px = Trunc(width × MDW + 0.5)`, * with no padding at all. It matters because the padding is a constant: on a * form drawn over a fine grid — tdf118668.xlsx rules 168 columns of 0.855 * characters — 3.75pt of padding nearly doubles a 4.5pt column, and the sheet * came out 1384pt wide against the reference's 754, so it paginated across two * pages where every reader prints one. * * @param chars The declared width in characters. * @param charTwips The Maximum Digit Width, in twips. * @returns The rendered column width in twips. */ export declare function columnTwips(chars: number, charTwips: number): number; /** * Excel's default column width is 8.43 "characters" ≈ 64px ≈ 960 twips. Used for * columns without an explicit ``. */ export declare const DEFAULT_COL_TWIPS = 960; /** * The row height a sheet that declares none inherits from the workbook's * Normal font. Sizes outside Excel's table scale from its 10pt entry and snap * up to the 0.75pt grid row heights are stored on (one pixel at 96 dpi). * * @param fontPt The Normal style's font size, or undefined if unknown. * @returns The default row height in points. */ export declare function defaultRowHeightPtFor(fontPt: number | undefined): number; /** * Excel's default row height is ~15pt = 300 twips. Used (for the `fitToHeight` * estimate) for rows without an explicit ``. */ export declare const DEFAULT_ROW_TWIPS = 300; /** * Build the page section (paper size + margins) from a worksheet's `` * / ``. * * Margins are always set, to Excel's own defaults when the worksheet declares * none (§18.3.1.62) — the renderer's fallback is a word processor's inch, which * is not what a spreadsheet prints. The paper size is left unset when the * worksheet names none, because there the file genuinely holds no answer: Excel * picks by locale and printer, and the renderer's deterministic A4 is as good * as anything we could invent. */ export declare function sectionFromWorksheet(worksheet: ParsedWorksheet): SectionProperties; /** * ECMA-376 §18.2.5 — resolve the sheet-scoped `_xlnm.Print_Area` defined name * (`localSheetId` = the sheet's 0-based index) into a clipping range. */ export declare function resolvePrintArea(definedNames: ReadonlyArray, sheetIdx: number): CellRange | undefined; /** ECMA-376 §18.2.5 — `_xlnm.Print_Titles` → the repeated row range (0-indexed). */ export declare function resolvePrintTitleRows(definedNames: ReadonlyArray, sheetIdx: number): { readonly startRow: number; readonly endRow: number; } | undefined; /** * The width one page has for content: the sheet's paper (declared or the A4 * default) less its left and right margins, in points. The same measure the * column bands are packed into — a drawing layer banded on any other width * would not line up with the grid beside it. */ export declare function printableWidthPt(worksheet: ParsedWorksheet): number; /** * The printable HEIGHT of one page of this sheet, in points — its paper height * less its own top and bottom margins. The vertical twin of * {@link printableWidthPt}. * * @param worksheet The parsed worksheet (paper + margins). * @returns The height a page of this sheet has for content, in points. */ export declare function printableHeightPt(worksheet: ParsedWorksheet): number; interface PrintModelOptions { readonly printArea?: CellRange; readonly gridLines: boolean; readonly titleRows?: { readonly startRow: number; readonly endRow: number; }; readonly sheetGrids?: ReadonlyMap; readonly sheetName?: string; readonly definedNames?: ReadonlyArray; readonly hyperlinks?: ReadonlyArray; readonly sharedStringRuns?: ReadonlyArray | undefined>; readonly now?: Date; readonly digitWidthPt?: number; readonly defaultFontPt?: number; readonly scaleSink?: { value: number; }; readonly bandSink?: { lefts: Array; }; readonly drawingExtentPt?: { readonly widthPt: number; readonly heightPt: number; }; readonly losses?: Array; } /** * Project one worksheet's grid into Flow body elements — a single {@link Table} * (or, when the sheet is wider than the page, several column-banded tables). The * full print model lives here: the used-range/print-area window, merge handling, * the style cascade (fonts/fills/borders/alignment), print scaling, conditional * formatting, sparklines, table/pivot banding, overflow and rotation. Memory- and * text-budget-bounded against untrusted input. * * @param worksheet The parsed grid + per-sheet geometry. * @param sharedStrings The workbook shared-string table (`t="s"` cells index it). * @param styles The workbook style table (cellXfs + fonts/fills/borders). * @param date1904 The 1904 date system flag (serial-to-date epoch). * @param print The print-model knobs (print area, gridlines, title rows, …). * @returns The body elements (one table block, or banded tables); empty for a * blank or empty-print-area sheet. */ export declare function worksheetToBody(worksheet: ParsedWorksheet, sharedStrings: ReadonlyArray, styles: XlsxStyles, date1904: boolean, print: PrintModelOptions): Array; /** * Resolve a cell's displayed text from its RAW stored value: shared-string and * inline-string lookup, boolean → `TRUE`/`FALSE`, and the number-format pass * (§18.8) for numeric cells. Error/string/date cells pass through verbatim. * * @param cell The parsed cell. * @param sharedStrings The shared-string table for `t="s"` cells. * @param styles The style table (for the cell's number format). * @param date1904 The 1904 date system flag. * @returns The resolved display string. */ export declare function resolveCellText(cell: WorksheetCell, sharedStrings: ReadonlyArray, styles: XlsxStyles, date1904: boolean): string; /** * Whether an EMPTY cell still draws something of its own — a fill or a border. * * Such a cell cannot be swallowed by a neighbour's overflowing text: the span * that gives the text its width would take the paint with it. */ /** * Whether a cell puts anything VISIBLE on an otherwise-empty page. * * The difference from {@link cellPaintsSomething} is white: a solid fill in the * paper's own colour paints nothing a reader can see, and a sheet of them is a * blank sheet. bnc762542.xlsx is 176 such cells — `fgColor indexed="9"`, the * legacy palette's white — with every word it prints living in a callout, and * both references print the callout on a bare page. 48779.xlsx is one cell of * solid red, and both print the swatch. * * @param cell The cell, or undefined. * @param styles The workbook's style tables. * @returns True when the cell draws something the eye can find. */ export declare function cellPaintsVisibly(cell: WorksheetCell | undefined, styles: XlsxStyles): boolean; export declare function cellPaintsSomething(cell: WorksheetCell | undefined, styles: XlsxStyles): boolean; /** * Project a slicer panel (E-SHEET SV2) into a styled mini-{@link Table} emitted * after the grid: a caption header spanning the button columns, then one button * cell per item — the slicer accent fill + white text when selected, a light * band when not; the last row padded so every row keeps the column count. */ export declare function slicerTable(slicer: SheetSlicer): Table; export {};