@shbernal/ts-xlsx 1.0.3 → 1.2.0
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 +21 -0
- package/dist/core/address.js +0 -33
- package/dist/core/autofilter.js +0 -9
- package/dist/core/cell.d.ts +10 -0
- package/dist/core/cell.js +4 -123
- package/dist/core/color-resolution.js +0 -60
- package/dist/core/column.d.ts +9 -1
- package/dist/core/column.js +0 -52
- package/dist/core/comment-thread.js +0 -45
- package/dist/core/conditional-formatting-overlay.js +0 -11
- package/dist/core/conditional-formatting.js +0 -10
- package/dist/core/containers.js +0 -15
- package/dist/core/data-validation-overlay.js +0 -25
- package/dist/core/data-validation.js +0 -7
- package/dist/core/date.js +0 -39
- package/dist/core/formula.js +0 -117
- package/dist/core/grid-edits.js +0 -38
- package/dist/core/image.js +0 -25
- package/dist/core/internal.js +0 -27
- package/dist/core/limits.d.ts +30 -0
- package/dist/core/limits.js +2 -0
- package/dist/core/merge.d.ts +18 -0
- package/dist/core/merge.js +22 -7
- package/dist/core/modern-functions.js +0 -17
- package/dist/core/page-setup.js +0 -5
- package/dist/core/pivot-table.d.ts +1 -1
- package/dist/core/pivot-table.js +0 -44
- package/dist/core/preserved.js +0 -4
- package/dist/core/protection.js +0 -26
- package/dist/core/range.js +0 -112
- package/dist/core/row-input.d.ts +24 -0
- package/dist/core/row-input.js +29 -0
- package/dist/core/row.d.ts +9 -1
- package/dist/core/row.js +0 -58
- package/dist/core/style.js +0 -26
- package/dist/core/table-style.js +0 -28
- package/dist/core/table.js +0 -97
- package/dist/core/text-metrics.d.ts +20 -0
- package/dist/core/text-metrics.js +10 -0
- package/dist/core/theme.js +0 -85
- package/dist/core/value.d.ts +40 -0
- package/dist/core/value.js +30 -48
- package/dist/core/workbook-protection.js +0 -13
- package/dist/core/workbook.d.ts +13 -0
- package/dist/core/workbook.js +11 -368
- package/dist/core/worksheet-model.js +2 -23
- package/dist/core/worksheet.d.ts +22 -0
- package/dist/core/worksheet.js +14 -485
- package/dist/customui/errors.js +0 -10
- package/dist/customui/index.js +0 -5
- package/dist/customui/ribbon.js +0 -43
- package/dist/entries/core.d.ts +3 -1
- package/dist/entries/core.js +3 -7
- package/dist/entries/csv.js +0 -4
- package/dist/entries/customui.js +0 -2
- package/dist/entries/errors.js +0 -13
- package/dist/entries/vba.js +0 -5
- package/dist/entries/xlsb.js +0 -6
- package/dist/entries/xlsx.js +0 -13
- package/dist/errors.d.ts +14 -0
- package/dist/errors.js +5 -56
- package/dist/index.js +0 -12
- package/dist/io/csv/read.js +0 -18
- package/dist/io/csv/write.js +5 -35
- package/dist/io/opc/errors.js +0 -30
- package/dist/io/opc/inflate.js +0 -35
- package/dist/io/opc/namespaces.js +0 -15
- package/dist/io/opc/part-paths.js +0 -11
- package/dist/io/opc/read-opc.js +0 -31
- package/dist/io/opc/read-options.js +0 -6
- package/dist/io/opc/rels.js +0 -13
- package/dist/io/opc/sniff-format.js +0 -50
- package/dist/io/style/xf-style.js +0 -31
- package/dist/io/xlsb/errors.js +0 -10
- package/dist/io/xlsb/formula.js +1 -99
- package/dist/io/xlsb/primitives.js +1 -83
- package/dist/io/xlsb/ptg-functions.js +0 -34
- package/dist/io/xlsb/read-shared-strings.js +0 -7
- package/dist/io/xlsb/read-styles.js +3 -66
- package/dist/io/xlsb/read-worksheet.js +4 -87
- package/dist/io/xlsb/read.js +2 -60
- package/dist/io/xlsb/record-stream.js +0 -28
- package/dist/io/xlsb/record-types.js +0 -19
- package/dist/io/xlsx/cell-accumulator.js +0 -32
- package/dist/io/xlsx/cell-value.js +0 -29
- package/dist/io/xlsx/color-xml.d.ts +6 -0
- package/dist/io/xlsx/color-xml.js +42 -0
- package/dist/io/xlsx/comments.js +0 -84
- package/dist/io/xlsx/conditional-formatting.d.ts +1 -1
- package/dist/io/xlsx/conditional-formatting.js +1 -97
- package/dist/io/xlsx/data-validation.js +0 -56
- package/dist/io/xlsx/edit-vba.js +0 -54
- package/dist/io/xlsx/errors.js +0 -12
- package/dist/io/xlsx/hyperlinks.js +0 -40
- package/dist/io/xlsx/images.js +0 -32
- package/dist/io/xlsx/namespaces.js +0 -42
- package/dist/io/xlsx/package-plan.js +0 -47
- package/dist/io/xlsx/pivot.js +0 -22
- package/dist/io/xlsx/{pivot-read.js → read-pivot.js} +0 -30
- package/dist/io/xlsx/read-rows.js +1 -83
- package/dist/io/xlsx/{shared-strings-read.js → read-shared-strings.js} +0 -11
- package/dist/io/xlsx/read-styles.d.ts +25 -1
- package/dist/io/xlsx/read-styles.js +61 -108
- package/dist/io/xlsx/read-worksheet.js +1 -88
- package/dist/io/xlsx/read.js +3 -211
- package/dist/io/xlsx/relationships.js +0 -11
- package/dist/io/xlsx/rich-runs.js +0 -16
- package/dist/io/xlsx/rich-text.js +0 -12
- package/dist/io/xlsx/shared-formulas.js +0 -7
- package/dist/io/xlsx/shared-strings.js +0 -21
- package/dist/io/xlsx/sheet-properties.js +1 -64
- package/dist/io/xlsx/styles.d.ts +1 -29
- package/dist/io/xlsx/styles.js +2 -366
- package/dist/io/xlsx/tables.js +5 -52
- package/dist/io/xlsx/threaded-comments.js +0 -103
- package/dist/io/xlsx/workbook-xml.js +0 -94
- package/dist/io/xlsx/worksheet-xml.js +0 -174
- package/dist/io/xlsx/write-stream.js +0 -137
- package/dist/io/xlsx/write.js +1 -134
- package/dist/io/xlsx/x14-ext.js +0 -8
- package/dist/vba/cfb-writer.js +12 -59
- package/dist/vba/cfb.js +2 -32
- package/dist/vba/codepage.js +1 -23
- package/dist/vba/errors.js +0 -15
- package/dist/vba/index.js +0 -10
- package/dist/vba/ms-ovba.js +3 -46
- package/dist/vba/project-editor.js +4 -89
- package/dist/vba/project.js +2 -34
- package/dist/vba/vba-encoding.js +1 -17
- package/dist/xml/errors.js +0 -10
- package/dist/xml/xml-read.js +3 -82
- package/dist/xml/xml.js +0 -39
- package/package.json +9 -10
- package/skills/ts-xlsx-upstream/SKILL.md +178 -0
- /package/dist/io/xlsx/{pivot-read.d.ts → read-pivot.d.ts} +0 -0
- /package/dist/io/xlsx/{shared-strings-read.d.ts → read-shared-strings.d.ts} +0 -0
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
// The worksheet-body reader: one `xl/worksheets/sheetN.xml` in, its cells/columns/rows/print-setup
|
|
2
|
-
// applied onto a {@link Worksheet}. It is a single streaming pass driving a handful of accumulators
|
|
3
|
-
// (the cell being read, shared-formula masters, an autofilter draft, the current page-break axis) so
|
|
4
|
-
// each element commits its state as it closes. Style indices resolve through the parsed style table.
|
|
5
1
|
import { decodeRange } from '../../core/address.js';
|
|
6
2
|
import { isCustomFilterOperator, } from '../../core/autofilter.js';
|
|
7
3
|
import { INTERNAL } from '../../core/internal.js';
|
|
@@ -9,15 +5,9 @@ import { SHEET_PROTECTION_FLAGS, } from '../../core/protection.js';
|
|
|
9
5
|
import { assignStyleFacets } from '../../core/style.js';
|
|
10
6
|
import { boolPresent, boolStrict, boolTristate, localName, parseXml, } from '../../xml/xml-read.js';
|
|
11
7
|
import { CellAccumulator } from './cell-accumulator.js';
|
|
12
|
-
import { parseColor } from './
|
|
8
|
+
import { parseColor } from './color-xml.js';
|
|
13
9
|
const MARGIN_SIDES = ['left', 'right', 'top', 'bottom', 'header', 'footer'];
|
|
14
|
-
// Worksheet elements that commit on their close: a formatted-but-empty `<c/>` and a criteria-free
|
|
15
|
-
// self-closing `<autoFilter/>` are expanded to open+close so each finalises once in onClose. The
|
|
16
|
-
// text-bearing `<f/>`/`<v/>`/`<t/>` are deliberately excluded — an empty one must not commit.
|
|
17
10
|
const WORKSHEET_EMPTY_CLOSES = new Set(['c', 'autoFilter']);
|
|
18
|
-
// Fold a filter column's accumulated `<filters>` or `<customFilters>` state into one criteria value,
|
|
19
|
-
// or null when it carried nothing filterable. A `<filters>` block with no values and no blank flag,
|
|
20
|
-
// or a `<customFilters>` with no predicates, is a no-op that would round-trip as noise, so it drops.
|
|
21
11
|
function pendingFilterCriteria(values, blank, predicates, and) {
|
|
22
12
|
if (values !== null && (values.length > 0 || blank)) {
|
|
23
13
|
return { kind: 'values', values, blank };
|
|
@@ -27,12 +17,6 @@ function pendingFilterCriteria(values, blank, predicates, and) {
|
|
|
27
17
|
}
|
|
28
18
|
return null;
|
|
29
19
|
}
|
|
30
|
-
// Read a <sheetProtection> element back into a SheetProtection — the deserialization mirror of the
|
|
31
|
-
// writer. `sheet="0"` (or "false") means the element records an *un*protected sheet, so nothing is
|
|
32
|
-
// restored. Each flag attribute is the INVERSE of the author's allow-flag ("1" forbids, "0" permits),
|
|
33
|
-
// and only attributes actually present are carried, so an omitted (default-valued) flag stays absent —
|
|
34
|
-
// exactly what the writer emitted. A password credential is preserved verbatim in its agile form
|
|
35
|
-
// (algorithm, hash, salt, spin count); there is no plaintext password to recover, so it is not re-hashed.
|
|
36
20
|
function parseSheetProtection(attrs) {
|
|
37
21
|
if (attrs.sheet === '0' || attrs.sheet === 'false')
|
|
38
22
|
return undefined;
|
|
@@ -60,9 +44,6 @@ function parseSheetProtection(attrs) {
|
|
|
60
44
|
}
|
|
61
45
|
return { flags };
|
|
62
46
|
}
|
|
63
|
-
// Autofilter accumulation. The sheet `<autoFilter ref>` seeds a draft; each `<filterColumn colId>`
|
|
64
|
-
// opens a column whose criteria (`<filters>` values or `<customFilters>` predicates) stream into the
|
|
65
|
-
// draft until `</filterColumn>`, and `</autoFilter>` commits the whole thing to the sheet.
|
|
66
47
|
class AutoFilterAccumulator {
|
|
67
48
|
#ref = null;
|
|
68
49
|
#columns = [];
|
|
@@ -71,14 +52,10 @@ class AutoFilterAccumulator {
|
|
|
71
52
|
#blank = false;
|
|
72
53
|
#predicates = null;
|
|
73
54
|
#and = false;
|
|
74
|
-
// Seed a draft from the range. (A table's own `<autoFilter>` also matches, but table sheets route
|
|
75
|
-
// through parseTable, so this only ever sees the sheet-level one.)
|
|
76
55
|
begin(attrs) {
|
|
77
56
|
this.#ref = attrs.ref !== undefined && attrs.ref !== '' ? attrs.ref : null;
|
|
78
57
|
this.#columns = [];
|
|
79
58
|
}
|
|
80
|
-
// Open a criteria block for one column, offset `colId` from the range's left edge. Reset the
|
|
81
|
-
// per-column accumulators; whichever child (`<filters>`/`<customFilters>`) opens fills one.
|
|
82
59
|
beginColumn(attrs) {
|
|
83
60
|
this.#colId = attrs.colId !== undefined ? Number(attrs.colId) : -1;
|
|
84
61
|
this.#values = null;
|
|
@@ -88,8 +65,6 @@ class AutoFilterAccumulator {
|
|
|
88
65
|
}
|
|
89
66
|
beginValues(attrs) {
|
|
90
67
|
this.#values = [];
|
|
91
|
-
// `blank` defaults off when absent, so presence is required first — then it reads as an
|
|
92
|
-
// on-when-present flag. (`boolPresent` alone would treat the absent attribute as on.)
|
|
93
68
|
this.#blank = attrs.blank !== undefined && boolPresent(attrs.blank);
|
|
94
69
|
}
|
|
95
70
|
addValue(attrs) {
|
|
@@ -100,8 +75,6 @@ class AutoFilterAccumulator {
|
|
|
100
75
|
this.#predicates = [];
|
|
101
76
|
this.#and = attrs.and !== undefined && boolPresent(attrs.and);
|
|
102
77
|
}
|
|
103
|
-
// The operator attribute defaults to `equal` when absent (per CT_CustomFilter); an operand is
|
|
104
|
-
// likewise optional. An unrecognised operator drops the predicate rather than guessing.
|
|
105
78
|
addCustom(attrs) {
|
|
106
79
|
if (this.#predicates === null)
|
|
107
80
|
return;
|
|
@@ -110,18 +83,12 @@ class AutoFilterAccumulator {
|
|
|
110
83
|
this.#predicates.push({ operator, val: attrs.val ?? '' });
|
|
111
84
|
}
|
|
112
85
|
}
|
|
113
|
-
// Assemble this column's criteria from whichever accumulator filled. A column whose colId is
|
|
114
|
-
// negative, or whose criteria are empty (no values, no blank, no predicates), carries nothing
|
|
115
|
-
// filterable and is dropped so a re-write stays clean — load-repair, not authoring.
|
|
116
86
|
endColumn() {
|
|
117
87
|
const criteria = pendingFilterCriteria(this.#values, this.#blank, this.#predicates, this.#and);
|
|
118
88
|
if (this.#colId >= 0 && criteria !== null) {
|
|
119
89
|
this.#columns.push({ colId: this.#colId, criteria });
|
|
120
90
|
}
|
|
121
91
|
}
|
|
122
|
-
// Commit the accumulated autofilter to the sheet. Runs on `</autoFilter>` — including the synthesized
|
|
123
|
-
// close of a criteria-free self-closing `<autoFilter/>`. Columns whose colId falls outside the range
|
|
124
|
-
// are dropped here so the strict setter never trips on hostile input.
|
|
125
92
|
commit(sheet) {
|
|
126
93
|
if (this.#ref === null)
|
|
127
94
|
return;
|
|
@@ -131,16 +98,11 @@ class AutoFilterAccumulator {
|
|
|
131
98
|
sheet.autoFilter = { ref: this.#ref, columns: this.#columns.filter((c) => c.colId < width) };
|
|
132
99
|
}
|
|
133
100
|
catch {
|
|
134
|
-
// unbounded or malformed autofilter range in the source file — ignore it
|
|
135
101
|
}
|
|
136
102
|
this.#ref = null;
|
|
137
103
|
this.#columns = [];
|
|
138
104
|
}
|
|
139
105
|
}
|
|
140
|
-
// Page-break accumulation. `<brk>` elements appear under both `<rowBreaks>` and `<colBreaks>`; a break
|
|
141
|
-
// container's open points the accumulator at that axis's list (null outside any container), so a
|
|
142
|
-
// `<brk>` lands on the right axis, and the matching close clears it. A self-closing
|
|
143
|
-
// `<rowBreaks/>`/`<colBreaks/>` fires no close, so a new open simply reassigns the target.
|
|
144
106
|
class PageBreakAccumulator {
|
|
145
107
|
#target = null;
|
|
146
108
|
begin(target) {
|
|
@@ -149,8 +111,6 @@ class PageBreakAccumulator {
|
|
|
149
111
|
end() {
|
|
150
112
|
this.#target = null;
|
|
151
113
|
}
|
|
152
|
-
// `id` is the row/column the layout splits before; a non-positive or non-integer id is hostile input
|
|
153
|
-
// and dropped rather than trusted. A `<brk>` outside any break container has no axis and is ignored.
|
|
154
114
|
add(attrs) {
|
|
155
115
|
if (this.#target === null)
|
|
156
116
|
return;
|
|
@@ -167,24 +127,15 @@ class PageBreakAccumulator {
|
|
|
167
127
|
}
|
|
168
128
|
}
|
|
169
129
|
export function parseWorksheet(xml, sheet, sharedStrings, xfStyles) {
|
|
170
|
-
// The one `<c>` currently being read: its address/type/style, formula, value, inline text, rich
|
|
171
|
-
// runs, and the sheet-spanning shared-formula master map. Each `<c>` resets it and commits it.
|
|
172
130
|
const cell = new CellAccumulator();
|
|
173
131
|
let inInlineString = false;
|
|
174
132
|
let capture = false;
|
|
175
133
|
let text = '';
|
|
176
|
-
// A row with customFormat="1" supplies a default style for its cells that carry no `s`.
|
|
177
134
|
let rowStyle = -1;
|
|
178
135
|
let rowCustomFormat = false;
|
|
179
136
|
const autoFilter = new AutoFilterAccumulator();
|
|
180
137
|
const pageBreaks = new PageBreakAccumulator();
|
|
181
|
-
// A column's `style` is the default for its cells that carry no style of their own; this
|
|
182
|
-
// maps a column index to that style index so a bare cell can inherit it (as Excel does,
|
|
183
|
-
// without stamping every cell). Columns are parsed before any cell references them.
|
|
184
138
|
const columnStyle = new Map();
|
|
185
|
-
// Commit the cell held in the accumulator, resolving its style from its own `s`, then its row's
|
|
186
|
-
// (when customFormat), then its column's default — the order Excel applies. Runs on `</c>` close,
|
|
187
|
-
// including the synthesized close of a self-closing `<c/>` formatted-but-empty cell.
|
|
188
139
|
const finalizeCellFromState = () => {
|
|
189
140
|
const styleIndex = cell.styleIndex >= 0
|
|
190
141
|
? cell.styleIndex
|
|
@@ -216,12 +167,10 @@ export function parseWorksheet(xml, sheet, sharedStrings, xfStyles) {
|
|
|
216
167
|
cell.beginInlineString();
|
|
217
168
|
break;
|
|
218
169
|
case 'r':
|
|
219
|
-
// A run inside a rich inline string. Its `<rPr>` (if any) and `<t>` follow.
|
|
220
170
|
if (inInlineString)
|
|
221
171
|
cell.runs.beginRun();
|
|
222
172
|
break;
|
|
223
173
|
case 'rPr':
|
|
224
|
-
// The run's formatting bundle; its self-closing children stream into the default branch.
|
|
225
174
|
cell.runs.beginProperties();
|
|
226
175
|
break;
|
|
227
176
|
case 'f':
|
|
@@ -238,21 +187,14 @@ export function parseWorksheet(xml, sheet, sharedStrings, xfStyles) {
|
|
|
238
187
|
case 'evenFooter':
|
|
239
188
|
case 'firstHeader':
|
|
240
189
|
case 'firstFooter':
|
|
241
|
-
// A `<headerFooter>` child carries its header/footer definition as text (the `&`-prefixed
|
|
242
|
-
// section/format tokens, e.g. `&C&"Arial"&G`). Capture it verbatim so a round-trip preserves
|
|
243
|
-
// a header image's `&G` picture token and every other formatting directive.
|
|
244
190
|
capture = true;
|
|
245
191
|
break;
|
|
246
192
|
case 'mergeCell':
|
|
247
|
-
// A well-formed file never declares overlapping merges; a corrupt one might. Reject the
|
|
248
|
-
// bad range at the model boundary, but don't let one abort the whole parse — drop it and
|
|
249
|
-
// keep reading the valid geometry.
|
|
250
193
|
if (attrs.ref !== undefined && attrs.ref !== '') {
|
|
251
194
|
try {
|
|
252
195
|
sheet.mergeCells(attrs.ref);
|
|
253
196
|
}
|
|
254
197
|
catch {
|
|
255
|
-
// overlapping/malformed merge in the source file — skip it
|
|
256
198
|
}
|
|
257
199
|
}
|
|
258
200
|
break;
|
|
@@ -299,8 +241,6 @@ export function parseWorksheet(xml, sheet, sharedStrings, xfStyles) {
|
|
|
299
241
|
autoFilter.addCustom(attrs);
|
|
300
242
|
break;
|
|
301
243
|
default:
|
|
302
|
-
// A run's `<rPr>` child (`<b/>`, `<sz>`, `<color>`, `<rFont>`, …) sets one font facet; it
|
|
303
|
-
// is self-closing, so it is read here on open. Nothing else uses the default branch.
|
|
304
244
|
cell.runs.applyProperty(local, attrs);
|
|
305
245
|
break;
|
|
306
246
|
}
|
|
@@ -321,8 +261,6 @@ export function parseWorksheet(xml, sheet, sharedStrings, xfStyles) {
|
|
|
321
261
|
cell.setValue(text);
|
|
322
262
|
break;
|
|
323
263
|
case 't':
|
|
324
|
-
// A `<t>` inside a run is that run's text; a bare `<t>` directly in the `<is>` is a plain
|
|
325
|
-
// inline string. A run takes precedence — a run is also inside the inline string.
|
|
326
264
|
cell.appendText(text, inInlineString);
|
|
327
265
|
break;
|
|
328
266
|
case 'r':
|
|
@@ -363,27 +301,18 @@ export function parseWorksheet(xml, sheet, sharedStrings, xfStyles) {
|
|
|
363
301
|
},
|
|
364
302
|
}, { closeEmptyElements: WORKSHEET_EMPTY_CLOSES });
|
|
365
303
|
}
|
|
366
|
-
// Apply one `<sheetPr>` / `<sheetView>` / print-setup child to the sheet. These are the worksheet's
|
|
367
|
-
// layout and print metadata; grouping them here keeps the cell-reading switch a pure dispatch. Each
|
|
368
|
-
// records only what the source carried, so a file missing a facet leaves it unset and a re-write
|
|
369
|
-
// stays byte-clean. Every element here is self-closing (its state is all in attributes), so it is
|
|
370
|
-
// read on open.
|
|
371
304
|
function applySheetProperties(local, attrs, sheet) {
|
|
372
305
|
switch (local) {
|
|
373
306
|
case 'tabColor':
|
|
374
|
-
// A `<sheetPr>` child.
|
|
375
307
|
sheet.tabColor = parseColor(attrs);
|
|
376
308
|
break;
|
|
377
309
|
case 'outlinePr':
|
|
378
|
-
// A `<sheetPr>` child.
|
|
379
310
|
if (attrs.summaryBelow !== undefined)
|
|
380
311
|
sheet.outline.summaryBelow = boolPresent(attrs.summaryBelow);
|
|
381
312
|
if (attrs.summaryRight !== undefined)
|
|
382
313
|
sheet.outline.summaryRight = boolPresent(attrs.summaryRight);
|
|
383
314
|
break;
|
|
384
315
|
case 'pane':
|
|
385
|
-
// A `<sheetView>` child recording a frozen (or split) pane. Only a frozen pane maps onto the
|
|
386
|
-
// model's view; a source without one leaves `view` empty, so a re-write emits no pane.
|
|
387
316
|
if (attrs.state === 'frozen' || attrs.state === 'frozenSplit') {
|
|
388
317
|
sheet.view.state = 'frozen';
|
|
389
318
|
if (attrs.xSplit !== undefined)
|
|
@@ -395,8 +324,6 @@ function applySheetProperties(local, attrs, sheet) {
|
|
|
395
324
|
}
|
|
396
325
|
break;
|
|
397
326
|
case 'pageSetUpPr':
|
|
398
|
-
// The fit-to-page flag, a `<sheetPr>` child. Recorded only when the attribute is present, so a
|
|
399
|
-
// `<pageSetUpPr>` present for other reasons (e.g. `autoPageBreaks`) leaves `fitToPage` unset.
|
|
400
327
|
if (attrs.fitToPage !== undefined)
|
|
401
328
|
sheet.pageSetup.fitToPage = boolPresent(attrs.fitToPage);
|
|
402
329
|
break;
|
|
@@ -419,8 +346,6 @@ function applyColumn(sheet, attrs, xfStyles, columnStyle) {
|
|
|
419
346
|
const width = attrs.width !== undefined ? Number(attrs.width) : undefined;
|
|
420
347
|
const hidden = boolStrict(attrs.hidden);
|
|
421
348
|
const styleIndex = attrs.style !== undefined ? Number(attrs.style) : -1;
|
|
422
|
-
// The column's style resolves to the same facet bundle a cell's does; mirror all of it onto the
|
|
423
|
-
// column model so `getColumn(i)` reflects the declared default, not just its number format.
|
|
424
349
|
const style = styleIndex >= 0 ? xfStyles[styleIndex] : undefined;
|
|
425
350
|
for (let index = min; index <= max; index++) {
|
|
426
351
|
const column = sheet.getColumn(index);
|
|
@@ -437,7 +362,6 @@ function applyColumn(sheet, attrs, xfStyles, columnStyle) {
|
|
|
437
362
|
column.collapsed = true;
|
|
438
363
|
if (style !== undefined)
|
|
439
364
|
assignStyleFacets(column, style);
|
|
440
|
-
// Record the column's style so a bare cell in it can inherit the full column format on read.
|
|
441
365
|
if (styleIndex >= 0)
|
|
442
366
|
columnStyle.set(index, styleIndex);
|
|
443
367
|
}
|
|
@@ -446,10 +370,6 @@ function applyRow(sheet, attrs) {
|
|
|
446
370
|
const number = Number(attrs.r);
|
|
447
371
|
if (!Number.isInteger(number) || number < 1)
|
|
448
372
|
return;
|
|
449
|
-
// A `<row>` that states no attribute at all leaves no format record behind — the handle creates
|
|
450
|
-
// one only when something is written through it. That is the right reading: a bare `<row r="5"/>`
|
|
451
|
-
// carries no formatting to round-trip, and fabricating an empty record for it would put row 5 in
|
|
452
|
-
// the used range on the strength of an element that says nothing.
|
|
453
373
|
const row = sheet.getRow(number);
|
|
454
374
|
if (attrs.ht !== undefined && attrs.customHeight !== '0') {
|
|
455
375
|
const height = Number(attrs.ht);
|
|
@@ -466,9 +386,6 @@ function applyRow(sheet, attrs) {
|
|
|
466
386
|
if (boolStrict(attrs.collapsed))
|
|
467
387
|
row.collapsed = true;
|
|
468
388
|
}
|
|
469
|
-
// Read the `<printOptions>` boolean toggles back onto the model, storing only the ones the source
|
|
470
|
-
// carried so a re-write stays byte-clean. An OOXML boolean is `1`/`true` for on and `0`/`false` for
|
|
471
|
-
// off; a present-but-unrecognised token is dropped rather than coerced.
|
|
472
389
|
function applyPrintOptions(printOptions, attrs) {
|
|
473
390
|
const horizontalCentered = boolTristate(attrs.horizontalCentered);
|
|
474
391
|
if (horizontalCentered !== undefined)
|
|
@@ -496,10 +413,6 @@ function applyMargins(margins, attrs) {
|
|
|
496
413
|
margins[side] = value;
|
|
497
414
|
}
|
|
498
415
|
}
|
|
499
|
-
// Read the `<pageSetup>` print-scaling attributes back onto the model, setting only those the
|
|
500
|
-
// source carried so a re-write stays byte-clean. Numeric attributes that fail to parse are
|
|
501
|
-
// dropped rather than stored as NaN; the enumerated ones are trusted verbatim (an unexpected token
|
|
502
|
-
// round-trips harmlessly as an unknown string).
|
|
503
416
|
function applyPageSetup(pageSetup, attrs) {
|
|
504
417
|
const num = (raw) => {
|
|
505
418
|
if (raw === undefined)
|