reamkit 1.31.0 → 1.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/esm/core/bidi/index.d.ts +10 -0
- package/dist/esm/core/bidi/index.js +18 -2
- package/dist/esm/core/converter/facade.js +10 -5
- package/dist/esm/core/converter/project.js +1 -0
- package/dist/esm/core/converter/ream.js +17 -6
- package/dist/esm/core/converter/sheet-images.d.ts +17 -0
- package/dist/esm/core/converter/sheet-images.js +33 -0
- package/dist/esm/core/crypto/offcrypto.js +56 -12
- package/dist/esm/core/document-model/index.d.ts +1 -1
- package/dist/esm/core/document-model/types.d.ts +112 -0
- package/dist/esm/core/drawingml/chart-geometry.d.ts +36 -13
- package/dist/esm/core/drawingml/chart-geometry.js +372 -146
- package/dist/esm/core/drawingml/chart-parser.d.ts +19 -0
- package/dist/esm/core/drawingml/chart-parser.js +126 -18
- package/dist/esm/core/drawingml/colors.d.ts +6 -0
- package/dist/esm/core/drawingml/colors.js +23 -3
- package/dist/esm/core/drawingml/shape-render.d.ts +3 -1
- package/dist/esm/core/drawingml/shape-render.js +4 -2
- package/dist/esm/core/font/measure.d.ts +9 -0
- package/dist/esm/core/font/measure.js +9 -1
- package/dist/esm/core/fonts/families.js +4 -2
- package/dist/esm/core/fonts/scripts.js +4 -2
- package/dist/esm/core/ir/flow.d.ts +6 -0
- package/dist/esm/core/ir/sheet.d.ts +43 -0
- package/dist/esm/core/number-format.d.ts +40 -15
- package/dist/esm/core/number-format.js +295 -83
- package/dist/esm/core/opc/tag-scan.d.ts +15 -0
- package/dist/esm/core/opc/tag-scan.js +41 -0
- package/dist/esm/core/opc/xml-entities.js +39 -2
- package/dist/esm/core/spreadsheet-model/index.d.ts +1 -1
- package/dist/esm/core/spreadsheet-model/types.d.ts +96 -0
- package/dist/esm/core/style-cascade/resolver.js +4 -2
- package/dist/esm/excel/column-bands.d.ts +39 -6
- package/dist/esm/excel/column-bands.js +41 -17
- package/dist/esm/excel/comments-parser.js +19 -0
- package/dist/esm/excel/conditional-format.d.ts +7 -3
- package/dist/esm/excel/conditional-format.js +77 -39
- package/dist/esm/excel/formula/context.d.ts +18 -0
- package/dist/esm/excel/formula/eval.js +51 -0
- package/dist/esm/excel/formula/functions.js +37 -14
- package/dist/esm/excel/formula/index.d.ts +2 -2
- package/dist/esm/excel/formula/lexer.d.ts +1 -1
- package/dist/esm/excel/formula/lexer.js +41 -0
- package/dist/esm/excel/formula/parser.d.ts +25 -0
- package/dist/esm/excel/formula/parser.js +95 -0
- package/dist/esm/excel/print-model.d.ts +38 -1
- package/dist/esm/excel/print-model.js +536 -83
- package/dist/esm/excel/shared-strings-parser.d.ts +9 -0
- package/dist/esm/excel/shared-strings-parser.js +11 -1
- package/dist/esm/excel/sheet-drawing.d.ts +38 -2
- package/dist/esm/excel/sheet-drawing.js +47 -13
- package/dist/esm/excel/sheet-shape-parser.d.ts +6 -2
- package/dist/esm/excel/sheet-shape-parser.js +18 -6
- package/dist/esm/excel/sheet-to-flow.d.ts +17 -0
- package/dist/esm/excel/sheet-to-flow.js +434 -47
- package/dist/esm/excel/styles-parser.d.ts +9 -0
- package/dist/esm/excel/styles-parser.js +80 -26
- package/dist/esm/excel/table-parser.js +5 -0
- package/dist/esm/excel/table-style-presets.d.ts +26 -0
- package/dist/esm/excel/table-style-presets.js +1555 -0
- package/dist/esm/excel/table-style.d.ts +13 -0
- package/dist/esm/excel/table-style.js +75 -0
- package/dist/esm/excel/tint.d.ts +10 -0
- package/dist/esm/excel/tint.js +75 -0
- package/dist/esm/excel/vml-drawing.d.ts +41 -3
- package/dist/esm/excel/vml-drawing.js +144 -11
- package/dist/esm/excel/worksheet-parser.js +89 -15
- package/dist/esm/excel/xls/biff-reader.js +10 -2
- package/dist/esm/excel/xlsx-reader.js +234 -19
- package/dist/esm/excel/xlsx-writer.js +8 -7
- package/dist/esm/html/html-writer.js +202 -20
- package/dist/esm/layout/fit-pages.d.ts +11 -0
- package/dist/esm/layout/fit-pages.js +86 -0
- package/dist/esm/layout/line-paint.d.ts +58 -0
- package/dist/esm/layout/line-paint.js +107 -0
- package/dist/esm/layout/page-doc.d.ts +51 -0
- package/dist/esm/layout/page-doc.js +141 -1
- package/dist/esm/layout/styled-layout.d.ts +7 -0
- package/dist/esm/layout/styled-layout.js +275 -52
- package/dist/esm/layout/turned-section.js +14 -2
- package/dist/esm/markdown/markdown-writer.js +75 -13
- package/dist/esm/pdf/styled-page-emitter.js +49 -71
- package/dist/esm/pdf/styled-page-renderer.js +1 -1
- package/dist/esm/pdf-reader/annot-draw.js +2 -2
- package/dist/esm/pdf-reader/annots.js +3 -1
- package/dist/esm/pdf-reader/font.js +4 -4
- package/dist/esm/pdf-reader/layout.js +1 -1
- package/dist/esm/svg/svg-text.d.ts +58 -0
- package/dist/esm/svg/svg-text.js +322 -0
- package/dist/esm/svg/svg-writer.js +135 -71
- package/dist/esm/word/document-parser.js +1 -1
- package/dist/esm/word/docx-reader.js +13 -8
- package/dist/esm/word/docx-to-pdf.js +3 -3
- package/dist/esm/word/docx-writer.js +11 -2
- package/dist/esm/word/font-table.js +89 -10
- package/dist/esm/word/numbering-parser.js +1 -1
- package/package.json +7 -3
|
@@ -171,6 +171,12 @@ export interface ParsedWorksheet {
|
|
|
171
171
|
readonly colBreaks?: ReadonlyArray<number>;
|
|
172
172
|
/** §18.3.1.36 `<drawing r:id>` — the sheet's drawing part (charts/shapes). */
|
|
173
173
|
readonly drawingRelId?: string;
|
|
174
|
+
/**
|
|
175
|
+
* §18.3.1.99 — the sheet is a `<chartsheet>`: nothing but a chart, which
|
|
176
|
+
* prints filling the page, and on a landscape one unless the sheet says
|
|
177
|
+
* otherwise.
|
|
178
|
+
*/
|
|
179
|
+
readonly chartSheet?: boolean;
|
|
174
180
|
/**
|
|
175
181
|
* §18.3.1.36 `<legacyDrawing r:id>` — the relationship to the sheet's VML
|
|
176
182
|
* drawing part. A form control put on the sheet by Excel's Forms toolbar is
|
|
@@ -226,6 +232,22 @@ export interface ParsedWorksheet {
|
|
|
226
232
|
* (E-SHEET SE2/SE3).
|
|
227
233
|
*/
|
|
228
234
|
readonly pane?: SheetPane;
|
|
235
|
+
/**
|
|
236
|
+
* ECMA-376 §18.3.1.87 `<sheetView showGridLines>` — whether the sheet's
|
|
237
|
+
* window draws the cell gridlines. A VIEW setting, like the pane: what
|
|
238
|
+
* prints is `<printOptions gridLines>`. Carried for a screen projection and
|
|
239
|
+
* the round trip; absent ⇒ shown, the default.
|
|
240
|
+
*/
|
|
241
|
+
readonly showGridLines?: boolean;
|
|
242
|
+
/**
|
|
243
|
+
* ECMA-376 §18.3.1.87 `<sheetView rightToLeft>` — the sheet reads from the
|
|
244
|
+
* right: column A stands at the right edge and the columns run leftward,
|
|
245
|
+
* and each cell's left and right borders cross over with it. What a cell's
|
|
246
|
+
* text does is unchanged — it keeps the side its alignment names. Unlike
|
|
247
|
+
* the pane and the gridlines this one prints: Excel puts the sheet on the
|
|
248
|
+
* paper the way the window shows it. Absent ⇒ left to right.
|
|
249
|
+
*/
|
|
250
|
+
readonly rightToLeft?: boolean;
|
|
229
251
|
}
|
|
230
252
|
/**
|
|
231
253
|
* A frozen pane: the count of leading rows / columns frozen in the worksheet
|
|
@@ -236,6 +258,28 @@ export interface SheetPane {
|
|
|
236
258
|
readonly frozenRows: number;
|
|
237
259
|
readonly frozenCols: number;
|
|
238
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* §18.18.77 ST_TableStyleType — the regions of a table a table style formats,
|
|
263
|
+
* in the order they apply (§18.8.41): a later region's format wins where both
|
|
264
|
+
* say something.
|
|
265
|
+
*/
|
|
266
|
+
export type TableStyleElementType = 'wholeTable' | 'firstColumnStripe' | 'secondColumnStripe' | 'firstRowStripe' | 'secondRowStripe' | 'lastColumn' | 'firstColumn' | 'headerRow' | 'totalRow' | 'firstHeaderCell' | 'lastHeaderCell' | 'firstTotalCell' | 'lastTotalCell';
|
|
267
|
+
/** §18.8.40 — one region's format in a table style: its dxf, and a stripe's band size. */
|
|
268
|
+
export interface TableStyleRegion {
|
|
269
|
+
readonly dxf: Dxf;
|
|
270
|
+
/** §18.8.41 `size` — rows (or columns) in one band of a stripe; default 1. */
|
|
271
|
+
readonly size?: number;
|
|
272
|
+
}
|
|
273
|
+
/** §18.8.40 — a table style, region by region, its colours resolved. */
|
|
274
|
+
export type TableStyleFormat = Partial<Record<TableStyleElementType, TableStyleRegion>>;
|
|
275
|
+
/** §18.8.40 `<tableStyle>` — a style a workbook defines itself: each region's dxf. */
|
|
276
|
+
export interface XlsxTableStyle {
|
|
277
|
+
readonly elements: ReadonlyArray<{
|
|
278
|
+
readonly type: TableStyleElementType;
|
|
279
|
+
readonly dxfId: number;
|
|
280
|
+
readonly size?: number;
|
|
281
|
+
}>;
|
|
282
|
+
}
|
|
239
283
|
/**
|
|
240
284
|
* ECMA-376 §18.5.1.2 `<table>` — a structured table over a cell range with a
|
|
241
285
|
* banded style. The raw parse carries the range, header rows and style flags;
|
|
@@ -247,6 +291,13 @@ export interface ExcelTable {
|
|
|
247
291
|
readonly name?: string;
|
|
248
292
|
readonly styleName?: string;
|
|
249
293
|
readonly headerRowCount: number;
|
|
294
|
+
/** §18.5.1.2 `totalsRowCount` — the totals rows at the foot of the table (default 0). */
|
|
295
|
+
readonly totalsRowCount?: number;
|
|
296
|
+
/**
|
|
297
|
+
* §18.5.1.3 `<tableColumn name>` — the columns' names, left to right: what a
|
|
298
|
+
* structured reference (`tblIncome[Amount]`) names a column by.
|
|
299
|
+
*/
|
|
300
|
+
readonly columns?: ReadonlyArray<string>;
|
|
250
301
|
readonly showRowStripes: boolean;
|
|
251
302
|
readonly showColumnStripes: boolean;
|
|
252
303
|
readonly showFirstColumn: boolean;
|
|
@@ -259,6 +310,12 @@ export interface ExcelTable {
|
|
|
259
310
|
readonly headerHex?: string;
|
|
260
311
|
readonly bandHex?: string;
|
|
261
312
|
readonly headerTextHex?: string;
|
|
313
|
+
/**
|
|
314
|
+
* §18.8.40 — the style the table names, region by region: one Excel builds
|
|
315
|
+
* in (TableStyleMedium2) or one the workbook defines, its colours resolved
|
|
316
|
+
* against the workbook's theme.
|
|
317
|
+
*/
|
|
318
|
+
readonly style?: TableStyleFormat;
|
|
262
319
|
}
|
|
263
320
|
/**
|
|
264
321
|
* ECMA-376 §18.10.1.73 `<pivotTableDefinition>` — a pivot table. Its OUTPUT
|
|
@@ -314,6 +371,14 @@ export interface XlsxFont {
|
|
|
314
371
|
/** §18.8.37 `<strike/>` — the font is struck through. */
|
|
315
372
|
readonly strike?: boolean;
|
|
316
373
|
readonly colorHex?: string;
|
|
374
|
+
/**
|
|
375
|
+
* §18.8.3 — how the `<color>` names the colour, not what it comes to:
|
|
376
|
+
* `theme:1:0`, `rgb:FF000000`, `indexed:8`, `auto`; undefined for a font with
|
|
377
|
+
* no `<color>`. Excel lets a table style colour a cell's text only where the
|
|
378
|
+
* cell names its colour as the Normal style does — `theme="1"` black takes
|
|
379
|
+
* the style's white, `rgb="FF000000"` black keeps its own.
|
|
380
|
+
*/
|
|
381
|
+
readonly colorRef?: string;
|
|
317
382
|
readonly name?: string;
|
|
318
383
|
}
|
|
319
384
|
/** §18.8.20 `<fill>` — one fill record: pattern type plus foreground/background colours. */
|
|
@@ -343,6 +408,13 @@ export interface XlsxBorder {
|
|
|
343
408
|
readonly diagonal?: XlsxBorderEdge;
|
|
344
409
|
readonly diagonalUp?: boolean;
|
|
345
410
|
readonly diagonalDown?: boolean;
|
|
411
|
+
/**
|
|
412
|
+
* §18.8.4 `<vertical>`/`<horizontal>` — the lines BETWEEN the cells of a range
|
|
413
|
+
* a differential format covers: a table style's rules between its columns
|
|
414
|
+
* and between its rows. A cell's own border has no use for them.
|
|
415
|
+
*/
|
|
416
|
+
readonly vertical?: XlsxBorderEdge;
|
|
417
|
+
readonly horizontal?: XlsxBorderEdge;
|
|
346
418
|
}
|
|
347
419
|
/** §18.18.40 ST_HorizontalAlignment — `<alignment horizontal>`. */
|
|
348
420
|
export type XlsxHorizontalAlign = 'left' | 'center' | 'right' | 'fill' | 'justify' | 'centerContinuous' | 'distributed';
|
|
@@ -362,6 +434,12 @@ export interface XlsxCellAlignment {
|
|
|
362
434
|
readonly textRotation?: number;
|
|
363
435
|
/** §18.8.1 `shrinkToFit` — scale the text down so it fits the cell on one line (W6). */
|
|
364
436
|
readonly shrinkToFit?: boolean;
|
|
437
|
+
/**
|
|
438
|
+
* §18.8.1 `readingOrder` — `1` left to right, `2` right to left. Absent (or
|
|
439
|
+
* `0`) is "context": the direction of the text's first strong character,
|
|
440
|
+
* which is also what a General cell aligns its text by.
|
|
441
|
+
*/
|
|
442
|
+
readonly readingOrder?: 'ltr' | 'rtl';
|
|
365
443
|
}
|
|
366
444
|
/**
|
|
367
445
|
* §18.8.45 `<xf>` — one cell format record: indices into the font/fill/border/
|
|
@@ -395,6 +473,11 @@ export interface XlsxStyles {
|
|
|
395
473
|
* rules (E-SHEET SC1); only the properties a dxf sets override the base.
|
|
396
474
|
*/
|
|
397
475
|
readonly dxfs?: ReadonlyArray<Dxf>;
|
|
476
|
+
/**
|
|
477
|
+
* §18.8.42 `<tableStyles>` — the table styles the workbook defines itself,
|
|
478
|
+
* by name; their regions point into {@link XlsxStyles.dxfs}.
|
|
479
|
+
*/
|
|
480
|
+
readonly tableStyles?: ReadonlyMap<string, XlsxTableStyle>;
|
|
398
481
|
}
|
|
399
482
|
/** §18.8.14 `<dxf>` — a differential (override) format a `cfRule` applies on match. */
|
|
400
483
|
export interface Dxf {
|
|
@@ -489,6 +572,11 @@ export interface CfRuleDataBar {
|
|
|
489
572
|
* figure does not sit on top of its own gauge.
|
|
490
573
|
*/
|
|
491
574
|
readonly showValue?: boolean;
|
|
575
|
+
/**
|
|
576
|
+
* The 2009 extension's `<x14:dataBar gradient>` — false paints the bar in
|
|
577
|
+
* one solid colour, where Excel's default fades it from the axis.
|
|
578
|
+
*/
|
|
579
|
+
readonly gradient?: boolean;
|
|
492
580
|
}
|
|
493
581
|
/**
|
|
494
582
|
* §18.3.1.49 `<cfRule type="iconSet">` — picks one glyph per cell from a named
|
|
@@ -501,6 +589,12 @@ export interface CfRuleIconSet {
|
|
|
501
589
|
readonly iconSet: string;
|
|
502
590
|
readonly cfvos: ReadonlyArray<Cfvo>;
|
|
503
591
|
readonly reverse?: boolean;
|
|
592
|
+
/**
|
|
593
|
+
* §18.3.1.49 `showValue` — false means the cell shows its ICON ONLY, as a
|
|
594
|
+
* status column of ticks and crosses does: the figure is what the icon
|
|
595
|
+
* already says.
|
|
596
|
+
*/
|
|
597
|
+
readonly showValue?: boolean;
|
|
504
598
|
}
|
|
505
599
|
/**
|
|
506
600
|
* §18.3.1.10 `<cfRule type="top10">` — the top (or `bottom`) N values of the
|
|
@@ -708,6 +802,8 @@ export interface SheetRichRun {
|
|
|
708
802
|
readonly sizePt?: number;
|
|
709
803
|
/** §18.4.2 `<vertAlign>` — superscript / subscript within the cell text. */
|
|
710
804
|
readonly vertAlign?: 'superscript' | 'subscript';
|
|
805
|
+
/** §18.4.5 `<rFont>` — the run's typeface, where the producer names one. */
|
|
806
|
+
readonly fontName?: string;
|
|
711
807
|
}
|
|
712
808
|
/**
|
|
713
809
|
* §18.18.18 ST_DataValidationType — the constraint a `<dataValidation>`
|
|
@@ -262,8 +262,10 @@ function resolveBodyStyles(body, sheet) {
|
|
|
262
262
|
};
|
|
263
263
|
const visit = (el) => {
|
|
264
264
|
if (el.kind === "paragraph") visitParagraph(el.paragraph);
|
|
265
|
-
else if (el.kind === "table")
|
|
266
|
-
|
|
265
|
+
else if (el.kind === "table") {
|
|
266
|
+
for (const row of el.table.rows) for (const cell of row.cells) for (const child of cell.content) visit(child);
|
|
267
|
+
for (const drawing of el.table.overlay?.drawings ?? []) visit(drawing);
|
|
268
|
+
} else if (el.kind === "shape") {
|
|
267
269
|
const shapeText = (sh) => {
|
|
268
270
|
for (const child of sh.text?.content ?? []) visit(child);
|
|
269
271
|
for (const member of sh.children ?? []) shapeText(member.shape);
|
|
@@ -1,4 +1,21 @@
|
|
|
1
1
|
import { BodyElement, TableProperties, TableRow } from '../core/document-model/index.js';
|
|
2
|
+
/** §18.3.1.70 — the width of the row-number column, in twips. */
|
|
3
|
+
export declare const HEADING_COL_TWIPS = 460;
|
|
4
|
+
/**
|
|
5
|
+
* §18.3.1.70 — how the printed headings stand: the sheet's print scale shrinks
|
|
6
|
+
* them with it, as it shrinks everything else on the page.
|
|
7
|
+
*/
|
|
8
|
+
export interface HeadingBand {
|
|
9
|
+
/** How tall the letters row stands — exactly, so a drawing anchored to the
|
|
10
|
+
* grid can be moved down by just as much. */
|
|
11
|
+
readonly lettersPt?: number;
|
|
12
|
+
/** The row-number column's width, in twips; {@link HEADING_COL_TWIPS} unscaled. */
|
|
13
|
+
readonly colTwips?: number;
|
|
14
|
+
/** The size the letters and numbers are set in; the sheet's default unscaled. */
|
|
15
|
+
readonly fontPt?: number;
|
|
16
|
+
/** The width of the boxes' lines; 0.5pt unscaled. */
|
|
17
|
+
readonly lineWidthPt?: number;
|
|
18
|
+
}
|
|
2
19
|
/**
|
|
3
20
|
* Wrap a grid in its printed row and column headings (§18.3.1.70 `headings`):
|
|
4
21
|
* the column letters across the top, the row numbers down the left, each in a
|
|
@@ -7,14 +24,23 @@ import { BodyElement, TableProperties, TableRow } from '../core/document-model/i
|
|
|
7
24
|
*
|
|
8
25
|
* @param rows The band's rows.
|
|
9
26
|
* @param widths The band's column widths in twips.
|
|
10
|
-
* @param
|
|
27
|
+
* @param columns The absolute index of each of those columns — a hidden
|
|
28
|
+
* one between them is skipped, and so is its letter.
|
|
11
29
|
* @param rowNumbers The absolute 1-based row number of each row.
|
|
30
|
+
* @param band How the headings stand, at the print scale.
|
|
12
31
|
* @returns The rows and widths with the heading band added.
|
|
13
32
|
*/
|
|
14
|
-
export declare function withHeadingBand(rows: ReadonlyArray<TableRow>, widths: ReadonlyArray<number>,
|
|
33
|
+
export declare function withHeadingBand(rows: ReadonlyArray<TableRow>, widths: ReadonlyArray<number>, columns: ReadonlyArray<number>, rowNumbers: ReadonlyArray<number>, band?: HeadingBand): {
|
|
15
34
|
rows: Array<TableRow>;
|
|
16
35
|
widths: Array<number>;
|
|
17
36
|
};
|
|
37
|
+
/** Where a drawing lies on its sheet, in points from the sheet's top-left corner. */
|
|
38
|
+
export interface DrawingBox {
|
|
39
|
+
readonly xPt: number;
|
|
40
|
+
readonly yPt: number;
|
|
41
|
+
readonly widthPt: number;
|
|
42
|
+
readonly heightPt: number;
|
|
43
|
+
}
|
|
18
44
|
/** A contiguous run of columns that prints together as one band (E-SHEET SE1). */
|
|
19
45
|
export interface ColumnBand {
|
|
20
46
|
/** First local column index (inclusive). */
|
|
@@ -50,12 +76,19 @@ export declare function computeColumnBands(columnWidths: ReadonlyArray<number>,
|
|
|
50
76
|
* @param titleRowIndex The print-title row, or -1.
|
|
51
77
|
* @param drawingReachTwips How far right the sheet's drawings reach (0 if none).
|
|
52
78
|
* @param headings §18.3.1.70 — the printed row/column headings, when the sheet
|
|
53
|
-
* asks for them: the absolute index of
|
|
54
|
-
*
|
|
55
|
-
*
|
|
79
|
+
* asks for them: the absolute index of each column and the sheet row number
|
|
80
|
+
* of each emitted row. Each band gets ITS OWN letters, which is what both
|
|
81
|
+
* references print across the top of a continuation page.
|
|
82
|
+
* @param sheet §20.5 — where the grid's first column stands on the sheet and
|
|
83
|
+
* where its printed drawings lie, at the print scale: each band is framed
|
|
84
|
+
* for the drawings over it (TableOverlay) and keeps the rows they cover.
|
|
56
85
|
* @returns One table body element per band, in band order.
|
|
57
86
|
*/
|
|
58
87
|
export declare function bandedTables(rows: ReadonlyArray<TableRow>, columnWidths: ReadonlyArray<number>, bands: ReadonlyArray<ColumnBand>, properties: TableProperties, titleRowIndex?: number, drawingReachTwips?: number, headings?: {
|
|
59
|
-
readonly
|
|
88
|
+
readonly columns: ReadonlyArray<number>;
|
|
60
89
|
readonly rowNumbers: ReadonlyArray<number>;
|
|
90
|
+
readonly band?: HeadingBand;
|
|
91
|
+
}, sheet?: {
|
|
92
|
+
readonly sheetLeftPt: number;
|
|
93
|
+
readonly drawings: ReadonlyArray<DrawingBox>;
|
|
61
94
|
}): Array<BodyElement>;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { twipsToPt } from "../core/ir/units.js";
|
|
2
|
-
//#region src/excel/column-bands.ts
|
|
3
|
-
/** §18.3.1.70 — the width of the row-number column, in twips. */
|
|
4
|
-
var HEADING_COL_TWIPS = 460;
|
|
1
|
+
import { pt, twipsToPt } from "../core/ir/units.js";
|
|
5
2
|
/** The A1-style letters of an absolute column index (0 → A, 26 → AA). */
|
|
6
3
|
function columnLetters(index) {
|
|
7
4
|
let n = index;
|
|
@@ -20,14 +17,17 @@ function columnLetters(index) {
|
|
|
20
17
|
*
|
|
21
18
|
* @param rows The band's rows.
|
|
22
19
|
* @param widths The band's column widths in twips.
|
|
23
|
-
* @param
|
|
20
|
+
* @param columns The absolute index of each of those columns — a hidden
|
|
21
|
+
* one between them is skipped, and so is its letter.
|
|
24
22
|
* @param rowNumbers The absolute 1-based row number of each row.
|
|
23
|
+
* @param band How the headings stand, at the print scale.
|
|
25
24
|
* @returns The rows and widths with the heading band added.
|
|
26
25
|
*/
|
|
27
|
-
function withHeadingBand(rows, widths,
|
|
26
|
+
function withHeadingBand(rows, widths, columns, rowNumbers, band = {}) {
|
|
27
|
+
const { lettersPt, colTwips = 460, fontPt, lineWidthPt = .5 } = band;
|
|
28
28
|
const border = {
|
|
29
29
|
style: "single",
|
|
30
|
-
width:
|
|
30
|
+
width: lineWidthPt,
|
|
31
31
|
colorHex: "808080"
|
|
32
32
|
};
|
|
33
33
|
const borders = {
|
|
@@ -47,15 +47,21 @@ function withHeadingBand(rows, widths, colStart, rowNumbers) {
|
|
|
47
47
|
properties: { alignment: "center" },
|
|
48
48
|
runs: [{
|
|
49
49
|
text,
|
|
50
|
-
properties: {}
|
|
50
|
+
properties: fontPt !== void 0 ? { fontSizePt: pt(fontPt) } : {}
|
|
51
51
|
}]
|
|
52
52
|
}
|
|
53
53
|
}]
|
|
54
54
|
});
|
|
55
55
|
const letters = [head("")];
|
|
56
|
-
for (let i = 0; i < widths.length; i++) letters.push(head(columnLetters(
|
|
56
|
+
for (let i = 0; i < widths.length; i++) letters.push(head(columnLetters(columns[i] ?? i)));
|
|
57
57
|
const out = [{
|
|
58
|
-
properties: {
|
|
58
|
+
properties: {
|
|
59
|
+
isHeader: true,
|
|
60
|
+
...lettersPt !== void 0 ? {
|
|
61
|
+
height: pt(lettersPt),
|
|
62
|
+
heightRule: "exact"
|
|
63
|
+
} : {}
|
|
64
|
+
},
|
|
59
65
|
cells: letters
|
|
60
66
|
}];
|
|
61
67
|
rows.forEach((row, i) => {
|
|
@@ -66,7 +72,7 @@ function withHeadingBand(rows, widths, colStart, rowNumbers) {
|
|
|
66
72
|
});
|
|
67
73
|
return {
|
|
68
74
|
rows: out,
|
|
69
|
-
widths: [
|
|
75
|
+
widths: [colTwips, ...widths]
|
|
70
76
|
};
|
|
71
77
|
}
|
|
72
78
|
/**
|
|
@@ -122,16 +128,33 @@ function computeColumnBands(columnWidths, contentWidthTwips, colBreaks) {
|
|
|
122
128
|
* @param titleRowIndex The print-title row, or -1.
|
|
123
129
|
* @param drawingReachTwips How far right the sheet's drawings reach (0 if none).
|
|
124
130
|
* @param headings §18.3.1.70 — the printed row/column headings, when the sheet
|
|
125
|
-
* asks for them: the absolute index of
|
|
126
|
-
*
|
|
127
|
-
*
|
|
131
|
+
* asks for them: the absolute index of each column and the sheet row number
|
|
132
|
+
* of each emitted row. Each band gets ITS OWN letters, which is what both
|
|
133
|
+
* references print across the top of a continuation page.
|
|
134
|
+
* @param sheet §20.5 — where the grid's first column stands on the sheet and
|
|
135
|
+
* where its printed drawings lie, at the print scale: each band is framed
|
|
136
|
+
* for the drawings over it (TableOverlay) and keeps the rows they cover.
|
|
128
137
|
* @returns One table body element per band, in band order.
|
|
129
138
|
*/
|
|
130
|
-
function bandedTables(rows, columnWidths, bands, properties, titleRowIndex = -1, drawingReachTwips = 0, headings) {
|
|
139
|
+
function bandedTables(rows, columnWidths, bands, properties, titleRowIndex = -1, drawingReachTwips = 0, headings, sheet) {
|
|
131
140
|
return bands.flatMap((band, bandIndex) => {
|
|
132
141
|
const bandLeft = columnWidths.slice(0, band.start).reduce((sum, w) => sum + w, 0);
|
|
133
142
|
const bandTwips = columnWidths.slice(band.start, band.end + 1);
|
|
134
143
|
const grid = bandTwips.map((w) => twipsToPt(w));
|
|
144
|
+
const sheetLeftPt = sheet ? sheet.sheetLeftPt + twipsToPt(bandLeft) : 0;
|
|
145
|
+
const sheetRightPt = sheetLeftPt + grid.reduce((sum, w) => sum + w, 0);
|
|
146
|
+
const overlayAt = (leftPt) => sheet ? { overlay: {
|
|
147
|
+
sheetLeftPt: pt(sheetLeftPt),
|
|
148
|
+
widthPt: pt(sheetRightPt - sheetLeftPt),
|
|
149
|
+
leftPt: pt(leftPt),
|
|
150
|
+
drawings: []
|
|
151
|
+
} } : {};
|
|
152
|
+
const underDrawing = (row) => {
|
|
153
|
+
const top = row.properties.sheetTopPt;
|
|
154
|
+
if (top === void 0 || !sheet) return false;
|
|
155
|
+
const bottom = top + (row.properties.height ?? 0);
|
|
156
|
+
return sheet.drawings.some((d) => d.xPt < sheetRightPt && d.xPt + d.widthPt > sheetLeftPt && d.yPt < bottom && d.yPt + d.heightPt > top);
|
|
157
|
+
};
|
|
135
158
|
const bandRowNumbers = [...headings?.rowNumbers ?? []];
|
|
136
159
|
const bandRows = rows.map((row, rowIndex) => {
|
|
137
160
|
const cells = sliceRowCells(row.cells, band);
|
|
@@ -144,7 +167,7 @@ function bandedTables(rows, columnWidths, bands, properties, titleRowIndex = -1,
|
|
|
144
167
|
};
|
|
145
168
|
});
|
|
146
169
|
if (bandIndex > 0 && !(bandLeft < drawingReachTwips) && !bandRows.some(rowDrawsSomething)) return [];
|
|
147
|
-
while (bandRows.length > 1 && !rowDrawsSomething(bandRows[bandRows.length - 1])) {
|
|
170
|
+
while (bandRows.length > 1 && !rowDrawsSomething(bandRows[bandRows.length - 1]) && !underDrawing(bandRows[bandRows.length - 1])) {
|
|
148
171
|
bandRows.pop();
|
|
149
172
|
bandRowNumbers.pop();
|
|
150
173
|
}
|
|
@@ -158,11 +181,12 @@ function bandedTables(rows, columnWidths, bands, properties, titleRowIndex = -1,
|
|
|
158
181
|
rows: bandRows,
|
|
159
182
|
numbers: bandRowNumbers
|
|
160
183
|
}]).map((part) => {
|
|
161
|
-
const headed = headings ? withHeadingBand(part.rows, bandTwips, headings.
|
|
184
|
+
const headed = headings ? withHeadingBand(part.rows, bandTwips, headings.columns.slice(band.start, band.end + 1), part.numbers, headings.band) : void 0;
|
|
162
185
|
return {
|
|
163
186
|
kind: "table",
|
|
164
187
|
table: {
|
|
165
188
|
properties,
|
|
189
|
+
...overlayAt(headed ? twipsToPt(headings?.band?.colTwips ?? 460) : 0),
|
|
166
190
|
grid: headed ? headed.widths.map((w) => twipsToPt(w)) : grid,
|
|
167
191
|
rows: headed ? leadWithBandBreak(headed.rows) : part.rows
|
|
168
192
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolveInternalEntities } from "../core/opc/xml-entities.js";
|
|
2
|
+
import { richRun } from "./shared-strings-parser.js";
|
|
2
3
|
import { XMLParser } from "fast-xml-parser";
|
|
3
4
|
//#region src/excel/comments-parser.ts
|
|
4
5
|
var decoder = new TextDecoder("utf-8");
|
|
@@ -32,10 +33,12 @@ function parseLegacyComments(data) {
|
|
|
32
33
|
const author = Number.isInteger(authorIdx) ? authors[authorIdx] : void 0;
|
|
33
34
|
const text = stripAuthorPrefix(richText(obj["text"]), author);
|
|
34
35
|
if (text.length === 0 && !author) continue;
|
|
36
|
+
const runs = richRuns(obj["text"]);
|
|
35
37
|
out.push({
|
|
36
38
|
ref,
|
|
37
39
|
...author ? { author } : {},
|
|
38
40
|
text,
|
|
41
|
+
...runs.length > 0 ? { runs } : {},
|
|
39
42
|
threaded: false
|
|
40
43
|
});
|
|
41
44
|
}
|
|
@@ -95,6 +98,22 @@ function richText(node) {
|
|
|
95
98
|
if (direct) return direct;
|
|
96
99
|
return toArray(obj["r"]).map((r) => textOf(asObject(r)?.["t"])).join("");
|
|
97
100
|
}
|
|
101
|
+
function richRuns(node) {
|
|
102
|
+
const obj = asObject(node);
|
|
103
|
+
if (!obj) {
|
|
104
|
+
const plain = textOf(node);
|
|
105
|
+
return plain ? [{ text: plain }] : [];
|
|
106
|
+
}
|
|
107
|
+
const direct = textOf(obj["t"]);
|
|
108
|
+
if (direct) return [{ text: direct }];
|
|
109
|
+
const out = [];
|
|
110
|
+
for (const r of toArray(obj["r"])) {
|
|
111
|
+
const run = asObject(r);
|
|
112
|
+
const text = textOf(run?.["t"]);
|
|
113
|
+
if (text.length > 0) out.push(richRun(text, run?.["rPr"]));
|
|
114
|
+
}
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
98
117
|
function stripAuthorPrefix(text, author) {
|
|
99
118
|
if (!author) return text;
|
|
100
119
|
const prefix = `${author}:`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CellIcon } from '../core/document-model/index.js';
|
|
2
|
-
import { ConditionalFormat, DefinedName, WorksheetCell, XlsxBorder, XlsxStyles } from '../core/spreadsheet-model/index.js';
|
|
2
|
+
import { ConditionalFormat, DefinedName, ExcelTable, WorksheetCell, XlsxBorder, XlsxStyles } from '../core/spreadsheet-model/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* A resolved per-cell override the print model layers over a cell's base format: a
|
|
5
5
|
* solid highlight fill, font tweaks, an in-cell data bar (fraction of the cell
|
|
@@ -25,12 +25,14 @@ export interface CfOverride {
|
|
|
25
25
|
readonly colorHex: string;
|
|
26
26
|
readonly startFraction?: number;
|
|
27
27
|
readonly negative?: boolean;
|
|
28
|
+
readonly solid?: boolean;
|
|
28
29
|
};
|
|
29
30
|
readonly icon?: CellIcon;
|
|
30
31
|
/**
|
|
31
32
|
* §18.3.1.28 `<dataBar showValue="0">` — the cell shows its BAR and not its
|
|
32
33
|
* number. Excel's "Show Bar Only": the figure would otherwise sit on top of
|
|
33
|
-
* its own gauge.
|
|
34
|
+
* its own gauge. §18.3.1.49 `<iconSet showValue="0">` is the same for an
|
|
35
|
+
* icon: "Show Icon Only".
|
|
34
36
|
*/
|
|
35
37
|
readonly hideValue?: boolean;
|
|
36
38
|
}
|
|
@@ -69,11 +71,13 @@ blank?: boolean) => CfOverride | undefined;
|
|
|
69
71
|
* driving `TODAY()`/`NOW()` and the `timePeriod` windows;
|
|
70
72
|
* absent ⇒ those constructs no-op (deterministic output).
|
|
71
73
|
* @param sheetGrids The whole workbook, for an `expression` rule that reaches
|
|
72
|
-
* another sheet (`Sheet2!A1`)
|
|
74
|
+
* another sheet (`Sheet2!A1`), a defined name or a table
|
|
75
|
+
* by its columns (`tblIncome[Amount]`); absent ⇒
|
|
73
76
|
* same-sheet references only.
|
|
74
77
|
* @param currentSheet The rule sheet's name, for resolving sheet-local names.
|
|
75
78
|
* @param definedNames The workbook defined names visible to `expression` rules.
|
|
76
79
|
*/
|
|
77
80
|
export declare function buildConditionalFormatter(conditionalFormats: ReadonlyArray<ConditionalFormat> | undefined, styles: XlsxStyles, cells: ReadonlyArray<WorksheetCell>, resolveText?: (cell: WorksheetCell) => string, date1904?: boolean, now?: Date, sheetGrids?: ReadonlyMap<string, {
|
|
78
81
|
readonly cells: ReadonlyArray<WorksheetCell>;
|
|
82
|
+
readonly tables?: ReadonlyArray<ExcelTable>;
|
|
79
83
|
}>, currentSheet?: string, definedNames?: ReadonlyArray<DefinedName>): CellConditionalFormatter | undefined;
|