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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { eighthPtToPt, halfPtToPt, pt, twipsToPt } from "../core/ir/units.js";
|
|
2
2
|
import { FEATURES } from "../core/ir/features.js";
|
|
3
|
+
import { firstStrongDirection } from "../core/bidi/index.js";
|
|
3
4
|
import { applyNumberFormat, generalToWidth, numberFormatColorHex } from "../core/number-format.js";
|
|
4
5
|
import { parseAreaRef, parseTitleRowRange } from "./defined-name-ref.js";
|
|
5
6
|
import "./index.js";
|
|
@@ -35,27 +36,67 @@ function columnTwips(chars, charTwips) {
|
|
|
35
36
|
return columnTwipsOf(chars, charTwips);
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
38
|
-
*
|
|
39
|
-
* sheet
|
|
39
|
+
* How far the first `count` rows (or columns) of a sheet reach, in twips: each
|
|
40
|
+
* the default unless the sheet gives it a size of its own.
|
|
40
41
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
*
|
|
48
|
-
*
|
|
42
|
+
* @param count How many tracks, from the first.
|
|
43
|
+
* @param defaultTwips The size of a track the sheet says nothing about.
|
|
44
|
+
* @param sized The tracks it does size, by 0-based index.
|
|
45
|
+
* @returns Their total.
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* §20.5 — the part of the sheet a printed table shows, for the drawings over
|
|
49
|
+
* it (TableOverlay); empty until the drawings are put in. Nothing on a screen,
|
|
50
|
+
* which draws them over the whole sheet as it is.
|
|
51
|
+
*
|
|
52
|
+
* @param sheetLeftPt Where the table's first column stands on the sheet.
|
|
53
|
+
* @param columns The widths of the sheet's columns it prints.
|
|
54
|
+
* @param leftPt Where those begin in the table — past a row-number column.
|
|
55
|
+
* @returns The frame to spread into the table, or nothing.
|
|
56
|
+
*/
|
|
57
|
+
function sheetFrame(sheetLeftPt, columns, leftPt) {
|
|
58
|
+
if (sheetLeftPt === void 0) return {};
|
|
59
|
+
return { overlay: {
|
|
60
|
+
sheetLeftPt: pt(sheetLeftPt),
|
|
61
|
+
widthPt: pt(columns.reduce((sum, w) => sum + w, 0)),
|
|
62
|
+
leftPt: pt(leftPt),
|
|
63
|
+
drawings: []
|
|
64
|
+
} };
|
|
65
|
+
}
|
|
66
|
+
/** The drawings' boxes at the print scale. */
|
|
67
|
+
function scaledBoxes(boxes, scale) {
|
|
68
|
+
return (boxes ?? []).map((b) => ({
|
|
69
|
+
xPt: b.xPt * scale,
|
|
70
|
+
yPt: b.yPt * scale,
|
|
71
|
+
widthPt: b.widthPt * scale,
|
|
72
|
+
heightPt: b.heightPt * scale
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
function tracksBeforeTwips(count, defaultTwips, sized) {
|
|
76
|
+
let total = count * defaultTwips;
|
|
77
|
+
const seen = /* @__PURE__ */ new Set();
|
|
78
|
+
for (const t of sized) {
|
|
79
|
+
if (t.index >= count || seen.has(t.index)) continue;
|
|
80
|
+
seen.add(t.index);
|
|
81
|
+
total += t.twips - defaultTwips;
|
|
82
|
+
}
|
|
83
|
+
return total;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* §18.3.1.81 — the DEFAULT column, in twips: the sheet's `defaultColWidth`
|
|
87
|
+
* where it declares one — a stored width, padding included — and otherwise
|
|
88
|
+
* `baseColWidth` digits and their padding, rounded up to Excel's step of eight
|
|
89
|
+
* pixels. Padding a `baseColWidth` twice once stood in for that rounding: it
|
|
90
|
+
* gives 47668.xlsx's 80px as well, and nothing else.
|
|
49
91
|
*
|
|
50
|
-
* @param worksheet
|
|
51
|
-
* @param charTwips
|
|
52
|
-
* @param fallbackChars The width to use when the sheet declares neither.
|
|
92
|
+
* @param worksheet The sheet.
|
|
93
|
+
* @param charTwips The Maximum Digit Width, in twips.
|
|
53
94
|
* @returns The default column width in twips.
|
|
54
95
|
*/
|
|
55
|
-
function defaultColumnTwips(worksheet, charTwips
|
|
96
|
+
function defaultColumnTwips(worksheet, charTwips) {
|
|
56
97
|
if (worksheet.defaultColWidthChars !== void 0) return columnTwipsOf(worksheet.defaultColWidthChars, charTwips);
|
|
57
|
-
|
|
58
|
-
return
|
|
98
|
+
const px = ((worksheet.baseColWidthChars ?? DEFAULT_BASE_COL_CHARS) * charTwips + 75) / TWIPS_PER_PIXEL;
|
|
99
|
+
return Math.ceil(px / 8) * 8 * TWIPS_PER_PIXEL;
|
|
59
100
|
}
|
|
60
101
|
function columnTwipsOf(chars, charTwips) {
|
|
61
102
|
const mdwPx = charTwips / TWIPS_PER_PIXEL;
|
|
@@ -68,14 +109,8 @@ function columnTwipsOf(chars, charTwips) {
|
|
|
68
109
|
* four times as much.
|
|
69
110
|
*/
|
|
70
111
|
var EXCEL_CELL_INSET_PT = 1.5;
|
|
71
|
-
/**
|
|
72
|
-
|
|
73
|
-
*
|
|
74
|
-
* In the STORED unit, which is what {@link columnTwips} reads: Excel's default
|
|
75
|
-
* column is "8.43 characters" in its own interface and `width="9.140625"` in
|
|
76
|
-
* every file that writes it out, because the stored form carries the padding.
|
|
77
|
-
*/
|
|
78
|
-
var DEFAULT_COL_CHARS = 9.140625;
|
|
112
|
+
/** §18.3.1.81 `baseColWidth` — the digits a default column holds when the sheet does not say. */
|
|
113
|
+
var DEFAULT_BASE_COL_CHARS = 8;
|
|
79
114
|
/**
|
|
80
115
|
* The column-width unit in twips: the Maximum Digit Width of the font the
|
|
81
116
|
* document is rendered in (§18.3.1.13), or Excel's own 7 px when the caller has
|
|
@@ -89,12 +124,8 @@ var DEFAULT_COL_CHARS = 9.140625;
|
|
|
89
124
|
* are listed beside their originals because a file naming one is measured in
|
|
90
125
|
* the other's unit by every reader that has to substitute.
|
|
91
126
|
*
|
|
92
|
-
* Every entry here is measured.
|
|
93
|
-
*
|
|
94
|
-
* 72px, and §18.3.1.13's forward formula turns that into exactly the
|
|
95
|
-
* `width="9"` 54524.xlsx writes for its default band — but I have no copy of
|
|
96
|
-
* the face to measure, and fitting 0.55 to it moved 50299.xlsx from 16 pages
|
|
97
|
-
* to 22 against LibreOffice's 17. A face we cannot measure keeps the old 7px.
|
|
127
|
+
* Every Latin entry here is measured. A third number, where there is one, is
|
|
128
|
+
* what Excel adds in whole pixels to the digit it measures (see the CJK entry).
|
|
98
129
|
*/
|
|
99
130
|
var DIGIT_EM = [
|
|
100
131
|
[/^(calibri|carlito)$/i, 1063 / 2048],
|
|
@@ -102,9 +133,45 @@ var DIGIT_EM = [
|
|
|
102
133
|
[/^(times new roman|liberation serif|tinos)$/i, 1024 / 2048],
|
|
103
134
|
[/^(tahoma)$/i, 1118 / 2048],
|
|
104
135
|
[/^(verdana|dejavu sans)$/i, 1303 / 2048],
|
|
105
|
-
[
|
|
136
|
+
[
|
|
137
|
+
/* @__PURE__ */ new RegExp("^(新細明體|細明體|pmingliu|mingliu|標楷體|dfkai-sb|宋体|新宋体|simsun|nsimsun|黑体|simhei|微软雅黑|microsoft yahei|微軟正黑體|microsoft jhenghei|MS [P]?明朝|MS [P]?ゴシック|ms [p]?mincho|ms [p]?gothic|meiryo|メイリオ|游ゴシック|yu gothic|굴림체?|gulim(che)?|돋움체?|dotum(che)?|바탕체?|batang(che)?|맑은 고딕|malgun gothic)$", "iu"),
|
|
138
|
+
1024 / 2048,
|
|
139
|
+
1
|
|
140
|
+
]
|
|
106
141
|
];
|
|
107
142
|
/**
|
|
143
|
+
* The space advance, as a fraction of the em, of the faces a spreadsheet names
|
|
144
|
+
* for its normal style — §18.8.1 measures a cell's indent in them. Read off
|
|
145
|
+
* each face's `hmtx` for U+0020, the metric twins beside their originals; a
|
|
146
|
+
* face not listed takes a quarter em, which is where most spaces sit.
|
|
147
|
+
*/
|
|
148
|
+
var SPACE_EM = [
|
|
149
|
+
[/^(calibri|carlito)$/i, 463 / 2048],
|
|
150
|
+
[/^(arial|helvetica|liberation sans|arimo|arial unicode ms)$/i, 569 / 2048],
|
|
151
|
+
[/^(times new roman|liberation serif|tinos)$/i, 512 / 2048],
|
|
152
|
+
[/^(cambria|caladea)$/i, 220 / 1e3],
|
|
153
|
+
[/^(tahoma)$/i, 640 / 2048],
|
|
154
|
+
[/^(verdana|dejavu sans)$/i, 720 / 2048]
|
|
155
|
+
];
|
|
156
|
+
/**
|
|
157
|
+
* One level of §18.8.1's `indent`, in twips: "an increment of 1 represents 3
|
|
158
|
+
* spaces … of the normal style font". It was counted in DIGITS, three of them,
|
|
159
|
+
* which is twice as far — simple-monthly-budget.xlsx indents its "Amount"
|
|
160
|
+
* headings two levels and we set them 31.5pt in where LibreOffice sets them
|
|
161
|
+
* 15pt (it measures 7.49pt a level in Calibri 11, 8.39pt in Arial 10: three
|
|
162
|
+
* spaces of each).
|
|
163
|
+
*
|
|
164
|
+
* @param styles The workbook's styles; the first font is the normal style's.
|
|
165
|
+
* @returns The width of one indent level, in twips.
|
|
166
|
+
*/
|
|
167
|
+
function indentLevelTwips(styles) {
|
|
168
|
+
const font = styles.fonts[0];
|
|
169
|
+
const size = font?.sizePt !== void 0 && Number.isFinite(font.sizePt) && font.sizePt > 0 ? font.sizePt : DEFAULT_FONT_PT;
|
|
170
|
+
const name = font?.name?.trim() ?? "";
|
|
171
|
+
const em = SPACE_EM.find(([re]) => re.test(name))?.[1] ?? .25;
|
|
172
|
+
return Math.round(3 * em * size * TWIPS_PER_POINT);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
108
175
|
* §18.3.1.13 — the Maximum Digit Width, in twips, of the normal style's font.
|
|
109
176
|
*
|
|
110
177
|
* "The number of characters of the maximum digit width of the numbers 0, 1,
|
|
@@ -123,11 +190,29 @@ var DIGIT_EM = [
|
|
|
123
190
|
*/
|
|
124
191
|
function maximumDigitTwips(name, sizePt) {
|
|
125
192
|
const size = sizePt !== void 0 && Number.isFinite(sizePt) && sizePt > 0 ? sizePt : 11;
|
|
126
|
-
const
|
|
127
|
-
if (
|
|
128
|
-
const
|
|
193
|
+
const face = DIGIT_EM.find(([re]) => re.test(name.trim()));
|
|
194
|
+
if (face === void 0) return 105;
|
|
195
|
+
const [, em, extraPx = 0] = face;
|
|
196
|
+
const px = Math.trunc(em * size * (96 / 72)) + extraPx;
|
|
129
197
|
return px > 0 ? px * TWIPS_PER_PIXEL : 105;
|
|
130
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* §18.3.1.13 — the unit a sheet's columns are measured in: the Maximum Digit
|
|
201
|
+
* Width of the workbook's Normal font, in twips — the font's own where the
|
|
202
|
+
* workbook names it, the face we render with where it names none. A drawing's
|
|
203
|
+
* anchor counts columns in the same unit, or it lands beside the cells it is
|
|
204
|
+
* anchored to: 45540_form_Footer.xlsx sets its form in 宋体 12, whose digit
|
|
205
|
+
* is 8px, and anchored at Excel's 7px its check boxes stood a column off
|
|
206
|
+
* their labels.
|
|
207
|
+
*
|
|
208
|
+
* @param styles The workbook's styles (its first font is the Normal style's).
|
|
209
|
+
* @param digitWidthPt The render font's digit width, for a workbook that names no font.
|
|
210
|
+
* @returns The unit, in twips.
|
|
211
|
+
*/
|
|
212
|
+
function columnUnitTwips(styles, digitWidthPt) {
|
|
213
|
+
const font = styles.fonts[0];
|
|
214
|
+
return font?.name === void 0 ? digitTwips(digitWidthPt) : maximumDigitTwips(font.name, font.sizePt);
|
|
215
|
+
}
|
|
131
216
|
function digitTwips(digitWidthPt) {
|
|
132
217
|
if (digitWidthPt === void 0 || !Number.isFinite(digitWidthPt) || digitWidthPt <= 0) return 105;
|
|
133
218
|
return digitWidthPt * TWIPS_PER_POINT;
|
|
@@ -398,6 +483,11 @@ function scaleRunFont(props, scale) {
|
|
|
398
483
|
};
|
|
399
484
|
}
|
|
400
485
|
var PRINT_GRIDLINE_HEX = "C0C0C0";
|
|
486
|
+
var SCREEN_GRIDLINE = {
|
|
487
|
+
style: "single",
|
|
488
|
+
width: pt(.5),
|
|
489
|
+
colorHex: "D4D4D4"
|
|
490
|
+
};
|
|
401
491
|
var CF_NUMBER_FORMAT_ID = 1000001;
|
|
402
492
|
var MAX_SHEET_TEXT_CHARS = 1e6;
|
|
403
493
|
/**
|
|
@@ -417,8 +507,18 @@ var MAX_SHEET_TEXT_CHARS = 1e6;
|
|
|
417
507
|
* blank or empty-print-area sheet.
|
|
418
508
|
*/
|
|
419
509
|
function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
510
|
+
const body = gridBody(worksheet, sharedStrings, styles, date1904, print);
|
|
511
|
+
if (worksheet.rightToLeft !== true) return body;
|
|
512
|
+
return body.map((el) => el.kind === "table" ? {
|
|
513
|
+
...el,
|
|
514
|
+
table: mirrorTable(el.table, print.screen === true)
|
|
515
|
+
} : el);
|
|
516
|
+
}
|
|
517
|
+
function gridBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
420
518
|
if (worksheet.maxRow < 0 || worksheet.maxColumn < 0) return [];
|
|
421
|
-
const
|
|
519
|
+
const rtl = worksheet.rightToLeft === true;
|
|
520
|
+
const indentTwips = indentLevelTwips(styles);
|
|
521
|
+
const charTwipsUnit = columnUnitTwips(styles, print.digitWidthPt);
|
|
422
522
|
const textTwipsUnit = 105;
|
|
423
523
|
const rowStyleAt = /* @__PURE__ */ new Map();
|
|
424
524
|
for (const r of worksheet.rowStyles ?? []) rowStyleAt.set(r.row, r.styleIndex);
|
|
@@ -449,7 +549,7 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
449
549
|
}
|
|
450
550
|
if (usedRow >= 0 && usedCol >= 0 && print.drawingExtentPt) {
|
|
451
551
|
const wantTwips = Math.round(print.drawingExtentPt.widthPt * TWIPS_PER_POINT);
|
|
452
|
-
const defTwips = defaultColumnTwips(worksheet, charTwipsUnit
|
|
552
|
+
const defTwips = defaultColumnTwips(worksheet, charTwipsUnit);
|
|
453
553
|
const widthAt = (abs) => {
|
|
454
554
|
for (const col of worksheet.columns) {
|
|
455
555
|
if (abs < col.min - 1 || abs > col.max - 1) continue;
|
|
@@ -462,6 +562,15 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
462
562
|
acc += widthAt(col);
|
|
463
563
|
if (col > usedCol) usedCol = col;
|
|
464
564
|
}
|
|
565
|
+
const wantRowTwips = Math.round(print.drawingExtentPt.heightPt * TWIPS_PER_POINT);
|
|
566
|
+
const defRowTwips = Math.round((worksheet.defaultRowHeightPt ?? defaultRowHeightPtFor(print.defaultFontPt)) * TWIPS_PER_POINT);
|
|
567
|
+
const heightAt = new Map(worksheet.rowHeights.map((h) => [h.row, h.hidden ? 0 : Math.round(h.heightPt * TWIPS_PER_POINT)]));
|
|
568
|
+
const rowReach = usedRow + PAINT_REACH_ROWS;
|
|
569
|
+
let down = 0;
|
|
570
|
+
for (let row = 0; row <= rowReach && down <= wantRowTwips; row++) {
|
|
571
|
+
down += heightAt.get(row) ?? defRowTwips;
|
|
572
|
+
if (row > usedRow) usedRow = row;
|
|
573
|
+
}
|
|
465
574
|
}
|
|
466
575
|
if (usedRow >= 0 && usedCol >= 0) {
|
|
467
576
|
const colReach = usedCol + PAINT_REACH_COLUMNS;
|
|
@@ -476,7 +585,7 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
476
585
|
}
|
|
477
586
|
if (usedRow < 0 && usedCol < 0) {
|
|
478
587
|
const pageTwips = sheetContentWidthTwips(worksheet);
|
|
479
|
-
const defTwips = defaultColumnTwips(worksheet, charTwipsUnit
|
|
588
|
+
const defTwips = defaultColumnTwips(worksheet, charTwipsUnit);
|
|
480
589
|
let acc = 0;
|
|
481
590
|
let colLimit = 0;
|
|
482
591
|
while (colLimit < PAINT_REACH_COLUMNS && acc < pageTwips) {
|
|
@@ -501,7 +610,7 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
501
610
|
});
|
|
502
611
|
return [];
|
|
503
612
|
}
|
|
504
|
-
usedCol += overflowColumnsPastUsedRange(worksheet, usedCol, sharedStrings, styles, date1904, charTwipsUnit);
|
|
613
|
+
usedCol += overflowColumnsPastUsedRange(worksheet, usedCol, sharedStrings, styles, date1904, charTwipsUnit, print.screen === true, print.image === true);
|
|
505
614
|
let rowStart = 0;
|
|
506
615
|
let colStart = 0;
|
|
507
616
|
let rowEnd = usedRow;
|
|
@@ -569,7 +678,7 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
569
678
|
const cEnd = Math.min(m.endColumn, colWindowEnd);
|
|
570
679
|
for (let r = Math.max(m.startRow, rowStart); r <= rEnd; r++) for (let c = Math.max(m.startColumn, colStart); c <= cEnd; c++) if (!(r === m.startRow && c === m.startColumn)) insideMerge.add(key(r, c));
|
|
571
680
|
}
|
|
572
|
-
const defaultColTwips = defaultColumnTwips(worksheet, charTwipsUnit
|
|
681
|
+
const defaultColTwips = defaultColumnTwips(worksheet, charTwipsUnit);
|
|
573
682
|
const columnWidths = new Array(colCount).fill(defaultColTwips);
|
|
574
683
|
const hiddenCols = /* @__PURE__ */ new Set();
|
|
575
684
|
for (const col of worksheet.columns) {
|
|
@@ -607,7 +716,7 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
607
716
|
if (manualColBreaks.has(c + colStart)) fitColBreaks.add(i);
|
|
608
717
|
});
|
|
609
718
|
const drawing = print.drawingExtentPt;
|
|
610
|
-
const printScale = computePrintScale(worksheet, Math.max(totalGridTwips, Math.round((drawing?.widthPt ?? 0) * TWIPS_PER_POINT)), sheetContentWidthTwips(worksheet), Math.max(totalGridHeightTwips, Math.round((drawing?.heightPt ?? 0) * TWIPS_PER_POINT)), sheetContentHeightTwips(worksheet), {
|
|
719
|
+
const printScale = print.screen ? 1 : computePrintScale(worksheet, Math.max(totalGridTwips, Math.round((drawing?.widthPt ?? 0) * TWIPS_PER_POINT)), sheetContentWidthTwips(worksheet), Math.max(totalGridHeightTwips, Math.round((drawing?.heightPt ?? 0) * TWIPS_PER_POINT)), sheetContentHeightTwips(worksheet), {
|
|
611
720
|
rowTwips: fitRowTwips,
|
|
612
721
|
rowBreaks: fitRowBreaks,
|
|
613
722
|
titleTwips: fitTitleTwips,
|
|
@@ -616,7 +725,20 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
616
725
|
});
|
|
617
726
|
const scaled = printScale < .999;
|
|
618
727
|
if (print.scaleSink) print.scaleSink.value = printScale;
|
|
619
|
-
|
|
728
|
+
let sheetTopTwips = print.screen ? void 0 : tracksBeforeTwips(rowStart, defaultRowTwips, worksheet.rowHeights.map((h) => ({
|
|
729
|
+
index: h.row,
|
|
730
|
+
twips: h.hidden ? 0 : Math.round(h.heightPt * TWIPS_PER_POINT)
|
|
731
|
+
}))) * printScale;
|
|
732
|
+
const sheetLeftPt = print.screen ? void 0 : twipsToPt(Math.round(tracksBeforeTwips(colStart, defaultColTwips, worksheet.columns.flatMap((col) => {
|
|
733
|
+
const twips = col.hidden ? 0 : columnTwips(col.widthChars, charTwipsUnit);
|
|
734
|
+
const out = [];
|
|
735
|
+
for (let abs = col.min - 1; abs <= Math.min(col.max - 1, colStart - 1); abs++) out.push({
|
|
736
|
+
index: abs,
|
|
737
|
+
twips
|
|
738
|
+
});
|
|
739
|
+
return out;
|
|
740
|
+
})) * printScale));
|
|
741
|
+
const breakRows = new Set(print.screen ? [] : honouredBreaks(worksheet, "rows"));
|
|
620
742
|
let textBudget = MAX_SHEET_TEXT_CHARS;
|
|
621
743
|
let textBudgetReported = false;
|
|
622
744
|
const runPropsByXf = /* @__PURE__ */ new Map();
|
|
@@ -630,17 +752,23 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
630
752
|
return props;
|
|
631
753
|
};
|
|
632
754
|
const paraPropsByAlignment = /* @__PURE__ */ new Map();
|
|
633
|
-
const cellParaProps = (alignment) => {
|
|
634
|
-
|
|
755
|
+
const cellParaProps = (alignment, rtlText) => {
|
|
756
|
+
const memoKey = `${alignment ?? ""}|${rtlText ? "rtl" : ""}`;
|
|
757
|
+
let props = paraPropsByAlignment.get(memoKey);
|
|
635
758
|
if (props === void 0) {
|
|
636
|
-
|
|
637
|
-
|
|
759
|
+
const stored = rtlText ? crossedOver(alignment) : alignment;
|
|
760
|
+
props = {
|
|
761
|
+
...stored ? { alignment: stored } : {},
|
|
762
|
+
...rtlText ? { bidi: true } : {}
|
|
763
|
+
};
|
|
764
|
+
paraPropsByAlignment.set(memoKey, props);
|
|
638
765
|
}
|
|
639
766
|
return props;
|
|
640
767
|
};
|
|
641
768
|
const cfFormatter = buildConditionalFormatter(worksheet.conditionalFormats, styles, worksheet.cells, (cell) => resolveCellText(cell, sharedStrings, styles, date1904), date1904, print.now, print.sheetGrids, print.sheetName, print.definedNames);
|
|
642
769
|
const sparklineByCell = buildSparklineLookup(worksheet, print);
|
|
643
770
|
const tableFormatByCell = buildTableFormatLookup(worksheet);
|
|
771
|
+
const normalColorRef = styles.fonts[0]?.colorRef;
|
|
644
772
|
const dropdownRanges = listDropdownRanges(worksheet.dataValidations);
|
|
645
773
|
const bandEndOfCol = /* @__PURE__ */ new Map();
|
|
646
774
|
{
|
|
@@ -653,7 +781,7 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
653
781
|
}
|
|
654
782
|
const wide = worksheet.fitToPage ? worksheet.pageSetup?.fitToWidth ?? 1 : 1;
|
|
655
783
|
const width = sheetContentWidthTwips(worksheet);
|
|
656
|
-
if (colCount > 1 && bandsAcross(worksheet, wide) && (total > width || breaks.size > 0)) for (const band of computeColumnBands(widthsForBands, width, breaks)) for (let i = band.start; i <= band.end; i++) bandEndOfCol.set(visibleCols[i] ?? i, visibleCols[band.end] ?? band.end);
|
|
784
|
+
if (!print.screen && colCount > 1 && bandsAcross(worksheet, wide) && (total > width || breaks.size > 0)) for (const band of computeColumnBands(widthsForBands, width, breaks)) for (let i = band.start; i <= band.end; i++) bandEndOfCol.set(visibleCols[i] ?? i, visibleCols[band.end] ?? band.end);
|
|
657
785
|
}
|
|
658
786
|
const rows = [];
|
|
659
787
|
const rowNumbers = [];
|
|
@@ -685,12 +813,23 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
685
813
|
}
|
|
686
814
|
const ws = cellMatrix[r]?.[c];
|
|
687
815
|
let text = ws ? resolveCellText(ws, sharedStrings, styles, date1904) : "";
|
|
816
|
+
let generalOverflow = false;
|
|
688
817
|
if (ws?.type === "n" && ws.rawValue.length > 0 && (styles.cellXfs[ws.styleIndex ?? 0]?.numFmtId ?? 0) === 0) {
|
|
689
818
|
const unit = charTwips(styles.cellXfs[ws.styleIndex ?? 0], styles, textTwipsUnit);
|
|
690
819
|
const digit = charWidthUnits("0");
|
|
691
820
|
if (unit > 0 && digit > 0) {
|
|
692
|
-
|
|
693
|
-
|
|
821
|
+
let widthTwips = columnWidths[c];
|
|
822
|
+
if (merge) {
|
|
823
|
+
widthTwips = 0;
|
|
824
|
+
for (let a = merge.startColumn; a <= Math.min(merge.endColumn, colWindowEnd); a++) {
|
|
825
|
+
const i = a - colStart;
|
|
826
|
+
if (i >= 0 && i < colCount && !hiddenCols.has(i)) widthTwips += columnWidths[i];
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
const room = (widthTwips - 75) / unit;
|
|
830
|
+
const fits = (candidate) => estimateChars(candidate) / digit <= room;
|
|
831
|
+
text = generalToWidth(ws.rawValue, fits);
|
|
832
|
+
generalOverflow = !fits(text);
|
|
694
833
|
}
|
|
695
834
|
}
|
|
696
835
|
const cfText = text.length > 0 ? text : void 0;
|
|
@@ -709,22 +848,35 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
709
848
|
textBudget -= text.length;
|
|
710
849
|
const xf = ws ? styles.cellXfs[ws.styleIndex ?? 0] : defaultStyleAt(absR, absC, styles.cellXfs);
|
|
711
850
|
let runProps = cellRunProps(xf);
|
|
851
|
+
let normalColored = (xf ? styles.fonts[xf.fontId] : styles.fonts[0])?.colorRef === normalColorRef;
|
|
712
852
|
if (ws?.type === "n" && xf?.numFmtId) {
|
|
713
853
|
const fmtColor = numberFormatColorHex(ws.rawValue, xf.numFmtId, styles.numFmts);
|
|
714
|
-
if (fmtColor !== void 0 && fmtColor !== runProps.colorHex)
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
854
|
+
if (fmtColor !== void 0 && fmtColor !== runProps.colorHex) {
|
|
855
|
+
runProps = {
|
|
856
|
+
...runProps,
|
|
857
|
+
colorHex: fmtColor
|
|
858
|
+
};
|
|
859
|
+
normalColored = false;
|
|
860
|
+
}
|
|
718
861
|
}
|
|
719
|
-
const alignment = alignmentFromXf(xf, ws?.type);
|
|
862
|
+
const alignment = alignmentFromXf(xf, ws?.type, text);
|
|
863
|
+
const flow = flowAlignment(alignment, rtl);
|
|
720
864
|
let shading = xf ? shadingFromXf(xf, styles) : void 0;
|
|
721
865
|
const tableFmt = tableFormatByCell.get(key(absR, absC));
|
|
722
866
|
if (!shading && tableFmt?.shading) shading = tableFmt.shading;
|
|
723
|
-
if (tableFmt?.fontColorHex) runProps = {
|
|
867
|
+
if (tableFmt?.fontColorHex && normalColored) runProps = {
|
|
724
868
|
...runProps,
|
|
725
869
|
colorHex: tableFmt.fontColorHex
|
|
726
870
|
};
|
|
871
|
+
if (tableFmt?.bold && !runProps.bold) runProps = {
|
|
872
|
+
...runProps,
|
|
873
|
+
bold: true
|
|
874
|
+
};
|
|
727
875
|
let borders = xf ? scaleBorders(bordersFromXf(xf, styles), printScale) : void 0;
|
|
876
|
+
if (tableFmt?.borders) borders = {
|
|
877
|
+
...scaleBorders(mapXlsxBorder(tableFmt.borders), printScale),
|
|
878
|
+
...borders
|
|
879
|
+
};
|
|
728
880
|
let dataBar;
|
|
729
881
|
let icon;
|
|
730
882
|
const sparkline = sparklineByCell.get(key(absR, absC));
|
|
@@ -751,7 +903,7 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
751
903
|
const rotation = xf?.alignment?.textRotation;
|
|
752
904
|
const rotated = rotation !== void 0 && rotation !== 0 && text.length > 0;
|
|
753
905
|
const shrinkToFit = xf?.alignment?.shrinkToFit === true && !wrapText && !rotated;
|
|
754
|
-
if (text.length > 0 && !merge && !wrapText && !rotated && !shrinkToFit && ws && (ws.type === "s" || ws.type === "str" || ws.type === "inlineStr") && (
|
|
906
|
+
if (text.length > 0 && !merge && !wrapText && !rotated && !shrinkToFit && ws && (ws.type === "s" || ws.type === "str" || ws.type === "inlineStr") && (flow === "left" || flow === "center") && estimateChars(text) * charTwips(xf, styles, textTwipsUnit) > columnWidths[c]) {
|
|
755
907
|
let availTwips = columnWidths[c];
|
|
756
908
|
let cc = c + 1;
|
|
757
909
|
const neighbourIsFree = (col) => !cellHasContent(cellMatrix[r]?.[col]) && !insideMerge.has(key(absR, col + colStart)) && !mergeOrigins.has(key(absR, col + colStart)) && (!cellPaintsSomething(cellMatrix[r]?.[col], styles) || spanPreservesPaint(cellMatrix[r]?.[col], styles, shading, borders)) && !sparklineByCell.has(key(absR, col + colStart)) && !(dropdownRanges.length > 0 && rangesCover(dropdownRanges, absR, col + colStart));
|
|
@@ -798,6 +950,7 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
798
950
|
};
|
|
799
951
|
}
|
|
800
952
|
}
|
|
953
|
+
const noteFlag = print.noteFlags?.get(noteKey(absR, absC));
|
|
801
954
|
const dropdown = dropdownRanges.length > 0 && rangesCover(dropdownRanges, absR, absC);
|
|
802
955
|
const href = print.hyperlinks && print.hyperlinks.length > 0 ? hyperlinkUrlAt(print.hyperlinks, absR, absC) : void 0;
|
|
803
956
|
const visibleEndCol = merge ? Math.min(merge.endColumn, colWindowEnd) : 0;
|
|
@@ -820,15 +973,19 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
820
973
|
...overflowRightRule ? { right: overflowRightRule } : {}
|
|
821
974
|
} } : {},
|
|
822
975
|
...dropdown ? { dropdown: true } : {},
|
|
976
|
+
...noteFlag ? { noteFlag } : {},
|
|
823
977
|
...!wrapText && !rotated ? { noWrap: true } : {},
|
|
824
|
-
...!wrapText && !rotated && !shrinkToFit && !merge && ws?.type === "n" && (xf?.numFmtId ?? 0) !== 0 &&
|
|
978
|
+
...!wrapText && !rotated && !shrinkToFit && !merge && ws?.type === "n" && text.length > 0 && (generalOverflow || (xf?.numFmtId ?? 0) !== 0 && tooWideToShow(text, charTwips(xf, styles, textTwipsUnit), columnWidths[c])) ? { hashOnOverflow: true } : {},
|
|
825
979
|
verticalAlign: verticalAlignOf(xf)
|
|
826
980
|
};
|
|
827
981
|
const indentLevels = xf?.alignment?.indent ?? 0;
|
|
828
|
-
const
|
|
829
|
-
const
|
|
982
|
+
const rtlText = textDirection(xf, text) === "rtl";
|
|
983
|
+
const baseParaProps = cellParaProps(alignment, rtlText);
|
|
984
|
+
const indentPt = twipsToPt(indentLevels * indentTwips);
|
|
985
|
+
const indentAtRight = alignment === "right" !== rtlText;
|
|
986
|
+
const paragraphProps = indentLevels > 0 && alignment !== "center" ? {
|
|
830
987
|
...baseParaProps,
|
|
831
|
-
|
|
988
|
+
...indentAtRight ? { indentRight: indentPt } : { indentLeft: indentPt }
|
|
832
989
|
} : baseParaProps;
|
|
833
990
|
const richRuns = ws && ws.type === "s" && print.sharedStringRuns ? print.sharedStringRuns[Number(ws.rawValue)] : void 0;
|
|
834
991
|
const cellRuns = richRuns && richRuns.length > 0 ? richRuns.map((rr) => ({
|
|
@@ -847,7 +1004,7 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
847
1004
|
runs
|
|
848
1005
|
}
|
|
849
1006
|
}));
|
|
850
|
-
if (text.length > 0 && !merge && !wrapText && !rotated && !shrinkToFit && c > 0 &&
|
|
1007
|
+
if (text.length > 0 && !merge && !wrapText && !rotated && !shrinkToFit && c > 0 && flow === "right" && estimateChars(text) * charTwips(xf, styles, textTwipsUnit) > columnWidths[c]) leftOverflow.push({
|
|
851
1008
|
index: cells.length,
|
|
852
1009
|
column: c,
|
|
853
1010
|
needTwips: estimateChars(text) * charTwips(xf, styles, textTwipsUnit) - columnWidths[c],
|
|
@@ -884,17 +1041,27 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
884
1041
|
};
|
|
885
1042
|
if (isTitleRow && titleRowIndex < 0) titleRowIndex = rows.length;
|
|
886
1043
|
rowNumbers.push(absR + 1);
|
|
887
|
-
rows.push({
|
|
1044
|
+
if (sheetTopTwips === void 0) rows.push({
|
|
888
1045
|
properties: rowProps,
|
|
889
1046
|
cells
|
|
890
1047
|
});
|
|
1048
|
+
else {
|
|
1049
|
+
rows.push({
|
|
1050
|
+
properties: {
|
|
1051
|
+
...rowProps,
|
|
1052
|
+
sheetTopPt: twipsToPt(sheetTopTwips)
|
|
1053
|
+
},
|
|
1054
|
+
cells
|
|
1055
|
+
});
|
|
1056
|
+
sheetTopTwips += rowHeightTwips ?? defaultRowTwips;
|
|
1057
|
+
}
|
|
891
1058
|
}
|
|
892
1059
|
const thin = {
|
|
893
1060
|
style: "single",
|
|
894
1061
|
width: eighthPtToPt(2),
|
|
895
1062
|
colorHex: PRINT_GRIDLINE_HEX
|
|
896
1063
|
};
|
|
897
|
-
const centered = worksheet.printOptions?.horizontalCentered === true;
|
|
1064
|
+
const centered = !print.screen && worksheet.printOptions?.horizontalCentered === true;
|
|
898
1065
|
const tableProperties = {
|
|
899
1066
|
defaultCellMargins: {
|
|
900
1067
|
left: pt(EXCEL_CELL_INSET_PT * printScale),
|
|
@@ -903,7 +1070,8 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
903
1070
|
bottom: pt(0)
|
|
904
1071
|
},
|
|
905
1072
|
layout: "fixed",
|
|
906
|
-
...print.gridLines ? {
|
|
1073
|
+
...print.gridLines && print.screen ? { gridlines: SCREEN_GRIDLINE } : {},
|
|
1074
|
+
...print.gridLines && !print.screen ? { borders: {
|
|
907
1075
|
top: thin,
|
|
908
1076
|
bottom: thin,
|
|
909
1077
|
left: thin,
|
|
@@ -914,6 +1082,23 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
914
1082
|
...centered ? { alignment: "center" } : {}
|
|
915
1083
|
};
|
|
916
1084
|
const contentWidthTwips = sheetContentWidthTwips(worksheet);
|
|
1085
|
+
const headingColTwips = scaled ? Math.max(1, Math.round(460 * printScale)) : 460;
|
|
1086
|
+
const headings = !print.screen && worksheet.printOptions?.headings ? {
|
|
1087
|
+
dxPt: twipsToPt(headingColTwips),
|
|
1088
|
+
dyPt: (worksheet.defaultRowHeightPt ?? defaultRowHeightPtFor(print.defaultFontPt)) * printScale,
|
|
1089
|
+
band: {
|
|
1090
|
+
colTwips: headingColTwips,
|
|
1091
|
+
...scaled ? {
|
|
1092
|
+
fontPt: (print.defaultFontPt ?? DEFAULT_FONT_PT) * printScale,
|
|
1093
|
+
lineWidthPt: .5 * printScale
|
|
1094
|
+
} : {}
|
|
1095
|
+
}
|
|
1096
|
+
} : void 0;
|
|
1097
|
+
const reportHeadings = () => {
|
|
1098
|
+
if (!headings || !print.headingSink) return;
|
|
1099
|
+
print.headingSink.dxPt = headings.dxPt;
|
|
1100
|
+
print.headingSink.dyPt = headings.dyPt;
|
|
1101
|
+
};
|
|
917
1102
|
const colBreaksLocal = /* @__PURE__ */ new Set();
|
|
918
1103
|
for (const brk of worksheet.colBreaks ?? []) {
|
|
919
1104
|
const local = brk - colStart;
|
|
@@ -922,14 +1107,23 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
922
1107
|
const fitWide = worksheet.fitToPage ? worksheet.pageSetup?.fitToWidth ?? 1 : 1;
|
|
923
1108
|
const bandWidths = scaledColumnWidths(visibleWidths, printScale, scaled);
|
|
924
1109
|
const bandTotal = bandWidths.reduce((sum, w) => sum + w, 0);
|
|
925
|
-
if (colCount > 1 && bandsAcross(worksheet, fitWide) && (bandTotal > contentWidthTwips || colBreaksLocal.size > 0)) {
|
|
1110
|
+
if (!print.screen && colCount > 1 && bandsAcross(worksheet, fitWide) && (bandTotal > contentWidthTwips || colBreaksLocal.size > 0)) {
|
|
926
1111
|
const bands = computeColumnBands(bandWidths, contentWidthTwips, colBreaksLocal);
|
|
927
1112
|
if (bands.length > 1) {
|
|
928
1113
|
if (print.bandSink) print.bandSink.lefts = bands.map((band) => twipsToPt(bandWidths.slice(0, band.start).reduce((sum, w) => sum + w, 0)));
|
|
929
|
-
|
|
930
|
-
colStart,
|
|
931
|
-
rowNumbers
|
|
1114
|
+
const banded = bandedTables(rows, bandWidths, bands, tableProperties, titleRowIndex, Math.round((print.drawingExtentPt?.widthPt ?? 0) * TWIPS_PER_POINT * printScale), headings ? {
|
|
1115
|
+
columns: visibleCols.map((c) => c + colStart),
|
|
1116
|
+
rowNumbers,
|
|
1117
|
+
band: {
|
|
1118
|
+
...headings.band,
|
|
1119
|
+
lettersPt: headings.dyPt
|
|
1120
|
+
}
|
|
1121
|
+
} : void 0, sheetLeftPt !== void 0 ? {
|
|
1122
|
+
sheetLeftPt,
|
|
1123
|
+
drawings: scaledBoxes(print.drawingBoxesPt, printScale)
|
|
932
1124
|
} : void 0);
|
|
1125
|
+
reportHeadings();
|
|
1126
|
+
return banded;
|
|
933
1127
|
}
|
|
934
1128
|
}
|
|
935
1129
|
const frozen = worksheet.pane && (worksheet.pane.frozenRows > 0 || worksheet.pane.frozenCols > 0) ? {
|
|
@@ -939,23 +1133,30 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
939
1133
|
if (titleRowIndex > 0 && titleRowIndex < rows.length) {
|
|
940
1134
|
const titleStart = titleRowIndex;
|
|
941
1135
|
const grid = bandWidths.map((w) => twipsToPt(w));
|
|
1136
|
+
const overlay = sheetFrame(sheetLeftPt, grid, 0);
|
|
942
1137
|
return [{
|
|
943
1138
|
kind: "table",
|
|
944
1139
|
table: {
|
|
945
1140
|
properties: tableProperties,
|
|
946
1141
|
grid,
|
|
947
|
-
rows: rows.slice(0, titleStart)
|
|
1142
|
+
rows: rows.slice(0, titleStart),
|
|
1143
|
+
...overlay
|
|
948
1144
|
}
|
|
949
1145
|
}, {
|
|
950
1146
|
kind: "table",
|
|
951
1147
|
table: {
|
|
952
1148
|
properties: tableProperties,
|
|
953
1149
|
grid,
|
|
954
|
-
rows: rows.slice(titleStart)
|
|
1150
|
+
rows: rows.slice(titleStart),
|
|
1151
|
+
...overlay
|
|
955
1152
|
}
|
|
956
1153
|
}];
|
|
957
1154
|
}
|
|
958
|
-
const headed =
|
|
1155
|
+
const headed = headings ? withHeadingBand(rows, bandWidths, visibleCols.map((c) => c + colStart), rowNumbers, {
|
|
1156
|
+
...headings.band,
|
|
1157
|
+
lettersPt: headings.dyPt
|
|
1158
|
+
}) : void 0;
|
|
1159
|
+
if (headed) reportHeadings();
|
|
959
1160
|
return [{
|
|
960
1161
|
kind: "table",
|
|
961
1162
|
table: {
|
|
@@ -964,7 +1165,8 @@ function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
|
964
1165
|
frozen
|
|
965
1166
|
} : tableProperties,
|
|
966
1167
|
grid: (headed?.widths ?? bandWidths).map((w) => twipsToPt(w)),
|
|
967
|
-
rows: headed?.rows ?? rows
|
|
1168
|
+
rows: headed?.rows ?? rows,
|
|
1169
|
+
...sheetFrame(sheetLeftPt, bandWidths.map((w) => twipsToPt(w)), headed ? twipsToPt(headingColTwips) : 0)
|
|
968
1170
|
}
|
|
969
1171
|
}];
|
|
970
1172
|
}
|
|
@@ -1070,20 +1272,49 @@ function applyCfOverride(base, o) {
|
|
|
1070
1272
|
* the sheets where it matters most, since a column of figures is the common
|
|
1071
1273
|
* case.
|
|
1072
1274
|
*/
|
|
1073
|
-
function alignmentFromXf(xf, type) {
|
|
1275
|
+
function alignmentFromXf(xf, type, text = "") {
|
|
1074
1276
|
const explicit = xf?.alignment ? mapAlignment(xf.alignment.horizontal) : void 0;
|
|
1075
1277
|
if (explicit) return explicit;
|
|
1076
|
-
return generalAlignment(type);
|
|
1278
|
+
return generalAlignment(type, textDirection(xf, text));
|
|
1077
1279
|
}
|
|
1078
|
-
|
|
1280
|
+
/**
|
|
1281
|
+
* §18.8.1 General: numbers to the right, logical values centred, and text to
|
|
1282
|
+
* the side it STARTS from — the left for a word that reads from the left, the
|
|
1283
|
+
* right for one that reads from the right. Excel sets "שלום" against the right
|
|
1284
|
+
* edge of a General cell on any sheet, and the sheet's own direction does not
|
|
1285
|
+
* enter into it: the numbers on a right-to-left sheet still sit at the right.
|
|
1286
|
+
*/
|
|
1287
|
+
function generalAlignment(type, direction) {
|
|
1079
1288
|
switch (type) {
|
|
1080
1289
|
case "n":
|
|
1081
1290
|
case "d": return "right";
|
|
1082
1291
|
case "b":
|
|
1083
1292
|
case "e": return "center";
|
|
1084
|
-
default: return "left";
|
|
1293
|
+
default: return direction === "rtl" ? "right" : "left";
|
|
1085
1294
|
}
|
|
1086
1295
|
}
|
|
1296
|
+
/**
|
|
1297
|
+
* The direction a cell's text reads in: its own §18.8.1 `readingOrder`, or
|
|
1298
|
+
* else "context" — that of its first strong character.
|
|
1299
|
+
*/
|
|
1300
|
+
function textDirection(xf, text) {
|
|
1301
|
+
return xf?.alignment?.readingOrder ?? firstStrongDirection(text) ?? "ltr";
|
|
1302
|
+
}
|
|
1303
|
+
/**
|
|
1304
|
+
* The side a cell's text runs ON to, in the file's own column order. The grid
|
|
1305
|
+
* is built A first whatever the sheet's direction and turned round at the end
|
|
1306
|
+
* (mirrorTable), so on a sheet that reads from the right a cell set against
|
|
1307
|
+
* its right edge is one whose text runs FORWARD — into B, which stands to the
|
|
1308
|
+
* left of A — and the overflow has to reason about the mirror of what the
|
|
1309
|
+
* cell shows.
|
|
1310
|
+
*/
|
|
1311
|
+
function flowAlignment(alignment, rtl) {
|
|
1312
|
+
return rtl ? crossedOver(alignment) : alignment;
|
|
1313
|
+
}
|
|
1314
|
+
/** Left for right and right for left; every other alignment is its own mirror. */
|
|
1315
|
+
function crossedOver(alignment) {
|
|
1316
|
+
return alignment === "left" ? "right" : alignment === "right" ? "left" : alignment;
|
|
1317
|
+
}
|
|
1087
1318
|
function mapAlignment(h) {
|
|
1088
1319
|
if (!h) return void 0;
|
|
1089
1320
|
if (h === "left") return "left";
|
|
@@ -1268,6 +1499,10 @@ function mapBorderStyle(style) {
|
|
|
1268
1499
|
function key(row, col) {
|
|
1269
1500
|
return `${row},${col}`;
|
|
1270
1501
|
}
|
|
1502
|
+
/** The key {@link PrintModelOptions.noteFlags} is looked up by: absolute row and column. */
|
|
1503
|
+
function noteKey(row, col) {
|
|
1504
|
+
return key(row, col);
|
|
1505
|
+
}
|
|
1271
1506
|
function listDropdownRanges(dvs) {
|
|
1272
1507
|
if (!dvs || dvs.length === 0) return [];
|
|
1273
1508
|
const out = [];
|
|
@@ -1345,6 +1580,147 @@ function collectSeriesValues(cells, area, print) {
|
|
|
1345
1580
|
for (let r = area.startRow; r <= area.endRow; r++) for (let col = area.startColumn; col <= area.endColumn; col++) out.push(byKey.get(key(r, col)) ?? null);
|
|
1346
1581
|
return out;
|
|
1347
1582
|
}
|
|
1583
|
+
/** §18.8.41 — the order a table style's regions apply in: a later one wins. */
|
|
1584
|
+
var TABLE_STYLE_ORDER = [
|
|
1585
|
+
"wholeTable",
|
|
1586
|
+
"firstColumnStripe",
|
|
1587
|
+
"secondColumnStripe",
|
|
1588
|
+
"firstRowStripe",
|
|
1589
|
+
"secondRowStripe",
|
|
1590
|
+
"lastColumn",
|
|
1591
|
+
"firstColumn",
|
|
1592
|
+
"headerRow",
|
|
1593
|
+
"totalRow",
|
|
1594
|
+
"firstHeaderCell",
|
|
1595
|
+
"lastHeaderCell",
|
|
1596
|
+
"firstTotalCell",
|
|
1597
|
+
"lastTotalCell"
|
|
1598
|
+
];
|
|
1599
|
+
/**
|
|
1600
|
+
* §18.8.40 — what a table's style makes of each of its cells. Each region
|
|
1601
|
+
* the style formats is laid over the table in the order §18.8.41 gives —
|
|
1602
|
+
* the whole table, its column and row stripes, its last and first columns,
|
|
1603
|
+
* its header and total rows, their corner cells — and a later region's fill,
|
|
1604
|
+
* weight, colour and edges win over an earlier one's. A region's `left`,
|
|
1605
|
+
* `right`, `top` and `bottom` rule its own outer edges, its `vertical` and
|
|
1606
|
+
* `horizontal` the lines between its cells. Stripes run through the data rows
|
|
1607
|
+
* only, in bands of their own size, the first band at the first data row;
|
|
1608
|
+
* the first and last columns, and the stripes, only where the table turns them
|
|
1609
|
+
* on.
|
|
1610
|
+
*
|
|
1611
|
+
* @param t The table, its style resolved.
|
|
1612
|
+
* @param out Where each cell's format goes, by absolute key.
|
|
1613
|
+
*/
|
|
1614
|
+
function styledTableFormats(t, out) {
|
|
1615
|
+
const style = t.style;
|
|
1616
|
+
if (!style) return;
|
|
1617
|
+
const { startRow: r0, endRow: r1, startColumn: c0, endColumn: c1 } = t.ref;
|
|
1618
|
+
const dataTop = r0 + t.headerRowCount;
|
|
1619
|
+
const dataBottom = r1 - (t.totalsRowCount ?? 0);
|
|
1620
|
+
const bands = (from, to, first, second, which) => {
|
|
1621
|
+
const spans = [];
|
|
1622
|
+
let at = from;
|
|
1623
|
+
for (let i = 0; at <= to; i++) {
|
|
1624
|
+
const size = i % 2 === 0 ? first : second;
|
|
1625
|
+
if (i % 2 === which) spans.push([at, Math.min(to, at + size - 1)]);
|
|
1626
|
+
at += size;
|
|
1627
|
+
}
|
|
1628
|
+
return spans;
|
|
1629
|
+
};
|
|
1630
|
+
const rowSize = [style.firstRowStripe?.size ?? 1, style.secondRowStripe?.size ?? 1];
|
|
1631
|
+
const colSize = [style.firstColumnStripe?.size ?? 1, style.secondColumnStripe?.size ?? 1];
|
|
1632
|
+
const regionsOf = (type) => {
|
|
1633
|
+
const whole = {
|
|
1634
|
+
top: r0,
|
|
1635
|
+
bottom: r1,
|
|
1636
|
+
left: c0,
|
|
1637
|
+
right: c1
|
|
1638
|
+
};
|
|
1639
|
+
switch (type) {
|
|
1640
|
+
case "wholeTable": return [whole];
|
|
1641
|
+
case "firstRowStripe":
|
|
1642
|
+
case "secondRowStripe": return t.showRowStripes && dataBottom >= dataTop ? bands(dataTop, dataBottom, rowSize[0], rowSize[1], type === "firstRowStripe" ? 0 : 1).map(([top, bottom]) => ({
|
|
1643
|
+
top,
|
|
1644
|
+
bottom,
|
|
1645
|
+
left: c0,
|
|
1646
|
+
right: c1
|
|
1647
|
+
})) : [];
|
|
1648
|
+
case "firstColumnStripe":
|
|
1649
|
+
case "secondColumnStripe": return t.showColumnStripes && dataBottom >= dataTop ? bands(c0, c1, colSize[0], colSize[1], type === "firstColumnStripe" ? 0 : 1).map(([left, right]) => ({
|
|
1650
|
+
top: dataTop,
|
|
1651
|
+
bottom: dataBottom,
|
|
1652
|
+
left,
|
|
1653
|
+
right
|
|
1654
|
+
})) : [];
|
|
1655
|
+
case "lastColumn": return t.showLastColumn ? [{
|
|
1656
|
+
...whole,
|
|
1657
|
+
left: c1
|
|
1658
|
+
}] : [];
|
|
1659
|
+
case "firstColumn": return t.showFirstColumn ? [{
|
|
1660
|
+
...whole,
|
|
1661
|
+
right: c0
|
|
1662
|
+
}] : [];
|
|
1663
|
+
case "headerRow": return t.headerRowCount > 0 ? [{
|
|
1664
|
+
...whole,
|
|
1665
|
+
bottom: dataTop - 1
|
|
1666
|
+
}] : [];
|
|
1667
|
+
case "totalRow": return dataBottom < r1 ? [{
|
|
1668
|
+
...whole,
|
|
1669
|
+
top: dataBottom + 1
|
|
1670
|
+
}] : [];
|
|
1671
|
+
case "firstHeaderCell": return t.headerRowCount > 0 && t.showFirstColumn ? [{
|
|
1672
|
+
top: r0,
|
|
1673
|
+
bottom: dataTop - 1,
|
|
1674
|
+
left: c0,
|
|
1675
|
+
right: c0
|
|
1676
|
+
}] : [];
|
|
1677
|
+
case "lastHeaderCell": return t.headerRowCount > 0 && t.showLastColumn ? [{
|
|
1678
|
+
top: r0,
|
|
1679
|
+
bottom: dataTop - 1,
|
|
1680
|
+
left: c1,
|
|
1681
|
+
right: c1
|
|
1682
|
+
}] : [];
|
|
1683
|
+
case "firstTotalCell": return dataBottom < r1 && t.showFirstColumn ? [{
|
|
1684
|
+
top: dataBottom + 1,
|
|
1685
|
+
bottom: r1,
|
|
1686
|
+
left: c0,
|
|
1687
|
+
right: c0
|
|
1688
|
+
}] : [];
|
|
1689
|
+
case "lastTotalCell": return dataBottom < r1 && t.showLastColumn ? [{
|
|
1690
|
+
top: dataBottom + 1,
|
|
1691
|
+
bottom: r1,
|
|
1692
|
+
left: c1,
|
|
1693
|
+
right: c1
|
|
1694
|
+
}] : [];
|
|
1695
|
+
}
|
|
1696
|
+
};
|
|
1697
|
+
for (const type of TABLE_STYLE_ORDER) {
|
|
1698
|
+
const dxf = style[type]?.dxf;
|
|
1699
|
+
if (!dxf) continue;
|
|
1700
|
+
const fill = dxf.fill?.patternType === "none" ? void 0 : dxf.fill?.bgColorHex ?? dxf.fill?.fgColorHex;
|
|
1701
|
+
const b = dxf.border;
|
|
1702
|
+
for (const region of regionsOf(type)) for (let r = region.top; r <= region.bottom; r++) for (let c = region.left; c <= region.right; c++) {
|
|
1703
|
+
const k = key(r, c);
|
|
1704
|
+
const was = out.get(k);
|
|
1705
|
+
const edges = { ...was?.borders };
|
|
1706
|
+
const top = r === region.top ? b?.top : b?.horizontal;
|
|
1707
|
+
const bottom = r === region.bottom ? b?.bottom : b?.horizontal;
|
|
1708
|
+
const left = c === region.left ? b?.left : b?.vertical;
|
|
1709
|
+
const right = c === region.right ? b?.right : b?.vertical;
|
|
1710
|
+
if (top) edges.top = top;
|
|
1711
|
+
if (bottom) edges.bottom = bottom;
|
|
1712
|
+
if (left) edges.left = left;
|
|
1713
|
+
if (right) edges.right = right;
|
|
1714
|
+
out.set(k, {
|
|
1715
|
+
...was,
|
|
1716
|
+
...fill !== void 0 ? { shading: { colorHex: fill } } : {},
|
|
1717
|
+
...dxf.font?.colorHex !== void 0 ? { fontColorHex: dxf.font.colorHex } : {},
|
|
1718
|
+
...dxf.font?.bold !== void 0 ? { bold: dxf.font.bold } : {},
|
|
1719
|
+
...Object.keys(edges).length > 0 ? { borders: edges } : {}
|
|
1720
|
+
});
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1348
1724
|
function isPivotTotal(t) {
|
|
1349
1725
|
return t !== void 0 && t !== "data" && t !== "blank";
|
|
1350
1726
|
}
|
|
@@ -1370,7 +1746,8 @@ function buildTableFormatLookup(worksheet) {
|
|
|
1370
1746
|
for (let c = ref.startColumn; c <= ref.endColumn; c++) out.set(key(r, c), fmt);
|
|
1371
1747
|
}
|
|
1372
1748
|
};
|
|
1373
|
-
for (const t of worksheet.tables ?? [])
|
|
1749
|
+
for (const t of worksheet.tables ?? []) if (t.style) styledTableFormats(t, out);
|
|
1750
|
+
else band(t.ref, t.headerRowCount, t);
|
|
1374
1751
|
for (const p of worksheet.pivotTables ?? []) band(p.ref, p.firstDataRow, p, (off) => isPivotTotal(p.rowItemTypes?.[off]));
|
|
1375
1752
|
for (const p of worksheet.pivotTables ?? []) {
|
|
1376
1753
|
if (!p.colItemTypes || p.headerHex === void 0) continue;
|
|
@@ -1466,14 +1843,17 @@ function cellPaintsSomething(cell, styles) {
|
|
|
1466
1843
|
}
|
|
1467
1844
|
/**
|
|
1468
1845
|
* How many empty columns past the used range the last column's text needs to
|
|
1469
|
-
* run into, bounded by the printable width (Excel stops at the page edge too)
|
|
1846
|
+
* run into, bounded by the printable width (Excel stops at the page edge too)
|
|
1847
|
+
* — or, on a `screen`, which has no edge, only by the column cap; an `image`
|
|
1848
|
+
* of the sheet gives it none, its edge being the used range's.
|
|
1470
1849
|
*
|
|
1471
1850
|
* Only the last used column can want them — anywhere else the grid already has
|
|
1472
1851
|
* neighbours. Zero for the overwhelming majority of sheets, which keeps their
|
|
1473
1852
|
* projection exactly as it was.
|
|
1474
1853
|
*/
|
|
1475
|
-
function overflowColumnsPastUsedRange(worksheet, usedCol, sharedStrings, styles, date1904, charTwipsUnit) {
|
|
1476
|
-
|
|
1854
|
+
function overflowColumnsPastUsedRange(worksheet, usedCol, sharedStrings, styles, date1904, charTwipsUnit, screen, image) {
|
|
1855
|
+
if (image) return 0;
|
|
1856
|
+
const defaultTwips = defaultColumnTwips(worksheet, charTwipsUnit);
|
|
1477
1857
|
const widthOf = (abs) => {
|
|
1478
1858
|
for (const col of worksheet.columns) {
|
|
1479
1859
|
if (abs < col.min - 1 || abs > col.max - 1) continue;
|
|
@@ -1493,16 +1873,16 @@ function overflowColumnsPastUsedRange(worksheet, usedCol, sharedStrings, styles,
|
|
|
1493
1873
|
const xf = styles.cellXfs[cell.styleIndex ?? 0];
|
|
1494
1874
|
const align = xf?.alignment;
|
|
1495
1875
|
if (align?.wrapText || align?.shrinkToFit || align?.textRotation) continue;
|
|
1496
|
-
|
|
1876
|
+
const text = resolveCellText(cell, sharedStrings, styles, date1904);
|
|
1877
|
+
if (flowAlignment(alignmentFromXf(xf, cell.type, text), worksheet.rightToLeft === true) !== "left") continue;
|
|
1497
1878
|
let room = 0;
|
|
1498
1879
|
for (let abs = cell.column; abs <= usedCol; abs++) room += widthOf(abs);
|
|
1499
|
-
const text = resolveCellText(cell, sharedStrings, styles, date1904);
|
|
1500
1880
|
needTwips = Math.max(needTwips, estimateChars(text) * charTwips(xf, styles, 105) - room);
|
|
1501
1881
|
}
|
|
1502
1882
|
if (needTwips <= 0) return 0;
|
|
1503
1883
|
let gridTwips = 0;
|
|
1504
1884
|
for (let abs = 0; abs <= usedCol; abs++) gridTwips += widthOf(abs);
|
|
1505
|
-
const limit = sheetContentWidthTwips(worksheet);
|
|
1885
|
+
const limit = screen ? Infinity : sheetContentWidthTwips(worksheet);
|
|
1506
1886
|
const MAX_OVERFLOW_COLS = 256;
|
|
1507
1887
|
let extra = 0;
|
|
1508
1888
|
while (needTwips > 0 && extra < MAX_OVERFLOW_COLS) {
|
|
@@ -1671,6 +2051,79 @@ function absorbLeftwards(cells, cellColumns, candidates, styles, neighbourAt) {
|
|
|
1671
2051
|
}
|
|
1672
2052
|
}
|
|
1673
2053
|
/**
|
|
2054
|
+
* §18.3.1.87 `rightToLeft` — the table turned round, the way Excel draws a
|
|
2055
|
+
* sheet that reads from the right: column A last in every row and so at the
|
|
2056
|
+
* right edge, and each cell's left and right borders crossed over with it
|
|
2057
|
+
* (its diagonals too). What a cell shows is untouched — its text keeps the
|
|
2058
|
+
* side its alignment names, and its overflow already runs the right way (see
|
|
2059
|
+
* flowAlignment). On paper the sheet stands against the right margin, as
|
|
2060
|
+
* Excel prints it, unless it asks to be centred.
|
|
2061
|
+
*
|
|
2062
|
+
* @param table The grid as built, column A first.
|
|
2063
|
+
* @param screen Whether it is drawn for a window, which has no margin to meet.
|
|
2064
|
+
*/
|
|
2065
|
+
function mirrorTable(table, screen) {
|
|
2066
|
+
const { frozen, ...properties } = table.properties;
|
|
2067
|
+
return {
|
|
2068
|
+
...table,
|
|
2069
|
+
properties: {
|
|
2070
|
+
...properties,
|
|
2071
|
+
...frozen && frozen.rows > 0 ? { frozen: {
|
|
2072
|
+
rows: frozen.rows,
|
|
2073
|
+
cols: 0
|
|
2074
|
+
} } : {},
|
|
2075
|
+
...!screen && properties.alignment !== "center" ? { alignment: "right" } : {}
|
|
2076
|
+
},
|
|
2077
|
+
grid: [...table.grid].reverse(),
|
|
2078
|
+
rows: table.rows.map((row) => ({
|
|
2079
|
+
...row,
|
|
2080
|
+
cells: [...row.cells].reverse().map(mirrorCell)
|
|
2081
|
+
})),
|
|
2082
|
+
...table.overlay ? { overlay: {
|
|
2083
|
+
...table.overlay,
|
|
2084
|
+
leftPt: pt(table.grid.reduce((sum, w) => sum + w, 0) - table.overlay.leftPt - table.overlay.widthPt),
|
|
2085
|
+
mirrored: true
|
|
2086
|
+
} } : {}
|
|
2087
|
+
};
|
|
2088
|
+
}
|
|
2089
|
+
function mirrorCell(cell) {
|
|
2090
|
+
const p = cell.properties;
|
|
2091
|
+
const span = p.colSpan ?? 1;
|
|
2092
|
+
const paintAtEnd = p.paintColumns !== void 0 && p.paintColumns < span;
|
|
2093
|
+
if (!p.borders && !p.dataBar && !p.noteFlag && !paintAtEnd) return cell;
|
|
2094
|
+
return {
|
|
2095
|
+
...cell,
|
|
2096
|
+
properties: {
|
|
2097
|
+
...p,
|
|
2098
|
+
...p.borders ? { borders: mirrorBorders(p.borders) } : {},
|
|
2099
|
+
...p.dataBar ? { dataBar: mirrorDataBar(p.dataBar) } : {},
|
|
2100
|
+
...p.noteFlag ? { noteFlag: {
|
|
2101
|
+
...p.noteFlag,
|
|
2102
|
+
atLeft: !p.noteFlag.atLeft
|
|
2103
|
+
} } : {},
|
|
2104
|
+
...paintAtEnd ? { paintAtEnd: true } : {}
|
|
2105
|
+
}
|
|
2106
|
+
};
|
|
2107
|
+
}
|
|
2108
|
+
function mirrorBorders(b) {
|
|
2109
|
+
const { left, right, diagonalUp, diagonalDown, ...rest } = b;
|
|
2110
|
+
return {
|
|
2111
|
+
...rest,
|
|
2112
|
+
...right ? { left: right } : {},
|
|
2113
|
+
...left ? { right: left } : {},
|
|
2114
|
+
...diagonalUp ? { diagonalDown: diagonalUp } : {},
|
|
2115
|
+
...diagonalDown ? { diagonalUp: diagonalDown } : {}
|
|
2116
|
+
};
|
|
2117
|
+
}
|
|
2118
|
+
function mirrorDataBar(bar) {
|
|
2119
|
+
const start = bar.startFraction ?? 0;
|
|
2120
|
+
return {
|
|
2121
|
+
...bar,
|
|
2122
|
+
startFraction: Math.max(0, 1 - start - bar.fraction),
|
|
2123
|
+
negative: !bar.negative
|
|
2124
|
+
};
|
|
2125
|
+
}
|
|
2126
|
+
/**
|
|
1674
2127
|
* Whether spanning a cell's overflowing text across `neighbour` would leave the
|
|
1675
2128
|
* page looking the same as drawing over it would.
|
|
1676
2129
|
*
|
|
@@ -1805,4 +2258,4 @@ function slicerParagraph(text, runProps) {
|
|
|
1805
2258
|
};
|
|
1806
2259
|
}
|
|
1807
2260
|
//#endregion
|
|
1808
|
-
export { cellPaintsVisibly, columnTwips, printableHeightPt, printableWidthPt, resolveCellText, resolvePrintArea, resolvePrintTitleRows, sectionFromWorksheet, slicerTable, worksheetToBody };
|
|
2261
|
+
export { cellPaintsVisibly, columnTwips, columnUnitTwips, defaultColumnTwips, noteKey, printableHeightPt, printableWidthPt, resolveCellText, resolvePrintArea, resolvePrintTitleRows, sectionFromWorksheet, slicerTable, worksheetToBody };
|