@shbernal/ts-xlsx 3.1.0 → 3.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 +30 -23
- package/dist/bytes.d.ts +3 -2
- package/dist/core/address.d.ts +36 -0
- package/dist/core/address.js +47 -9
- package/dist/core/array-formula-ranges.d.ts +33 -0
- package/dist/core/array-formula-ranges.js +62 -0
- package/dist/core/color-resolution.js +2 -2
- package/dist/core/column.js +3 -2
- package/dist/core/comment-thread.d.ts +7 -3
- package/dist/core/conditional-formatting-overlay.d.ts +9 -0
- package/dist/core/conditional-formatting-overlay.js +28 -1
- package/dist/core/conditional-formatting.d.ts +98 -10
- package/dist/core/conditional-formatting.js +42 -1
- package/dist/core/data-validation-overlay.d.ts +5 -0
- package/dist/core/data-validation-overlay.js +15 -0
- package/dist/core/data-validation.d.ts +16 -0
- package/dist/core/data-validation.js +15 -0
- package/dist/core/date-format.js +14 -4
- package/dist/core/date.js +1 -1
- package/dist/core/formula-references.d.ts +26 -0
- package/dist/core/formula-references.js +173 -0
- package/dist/core/formula-scan.d.ts +2 -0
- package/dist/core/formula-scan.js +58 -0
- package/dist/core/formula.d.ts +51 -18
- package/dist/core/formula.js +77 -86
- package/dist/core/function-values.d.ts +4 -0
- package/dist/core/function-values.js +58 -0
- package/dist/core/future-functions.d.ts +3 -0
- package/dist/core/{modern-functions.js → future-functions.js} +119 -88
- package/dist/core/grid-edits.d.ts +28 -0
- package/dist/core/grid-edits.js +193 -25
- package/dist/core/hyperlink.d.ts +39 -0
- package/dist/core/hyperlink.js +88 -0
- package/dist/core/image.d.ts +36 -5
- package/dist/core/image.js +9 -0
- package/dist/core/internal.d.ts +3 -1
- package/dist/core/limits.d.ts +5 -3
- package/dist/core/merge.d.ts +13 -0
- package/dist/core/merge.js +15 -1
- package/dist/core/page-setup.d.ts +26 -11
- package/dist/core/pivot-table.d.ts +49 -10
- package/dist/core/pivot-table.js +55 -21
- package/dist/core/protection.d.ts +66 -4
- package/dist/core/protection.js +4 -0
- package/dist/core/row.js +3 -2
- package/dist/core/structured-reference.d.ts +7 -0
- package/dist/core/structured-reference.js +7 -0
- package/dist/core/table.d.ts +38 -8
- package/dist/core/table.js +37 -7
- package/dist/core/theme.d.ts +2 -0
- package/dist/core/theme.js +4 -1
- package/dist/core/value.d.ts +51 -28
- package/dist/core/value.js +15 -12
- package/dist/core/workbook-styles.d.ts +17 -1
- package/dist/core/workbook-styles.js +4 -0
- package/dist/core/workbook-theme.js +5 -3
- package/dist/core/workbook.d.ts +20 -3
- package/dist/core/workbook.js +26 -5
- package/dist/core/worksheet-merges.d.ts +9 -4
- package/dist/core/worksheet-merges.js +17 -11
- package/dist/core/worksheet-model.d.ts +1 -1
- package/dist/core/worksheet-model.js +4 -0
- package/dist/core/worksheet-pictures.d.ts +3 -3
- package/dist/core/worksheet-pictures.js +7 -6
- package/dist/core/worksheet.d.ts +110 -21
- package/dist/core/worksheet.js +174 -49
- package/dist/entries/core.d.ts +7 -5
- package/dist/entries/core.js +4 -3
- package/dist/entries/errors.d.ts +1 -0
- package/dist/entries/errors.js +1 -0
- package/dist/errors.js +1 -1
- package/dist/io/cell-metadata/metadata.d.ts +42 -0
- package/dist/io/cell-metadata/metadata.js +35 -0
- package/dist/io/cell-metadata/rich-values.d.ts +11 -0
- package/dist/io/cell-metadata/rich-values.js +80 -0
- package/dist/io/csv/delimiter.d.ts +14 -2
- package/dist/io/csv/delimiter.js +12 -0
- package/dist/io/csv/errors.d.ts +14 -0
- package/dist/io/csv/errors.js +5 -0
- package/dist/io/csv/read.d.ts +6 -1
- package/dist/io/csv/read.js +46 -24
- package/dist/io/csv/write.d.ts +10 -3
- package/dist/io/csv/write.js +16 -7
- package/dist/io/opc/part-paths.js +4 -4
- package/dist/io/opc/read-opc.d.ts +4 -0
- package/dist/io/opc/read-opc.js +10 -4
- package/dist/io/opc/strict-relationships.d.ts +2 -0
- package/dist/io/opc/strict-relationships.js +12 -0
- package/dist/io/read-policy/column-budget.d.ts +26 -0
- package/dist/io/{xlsx → read-policy}/column-budget.js +4 -8
- package/dist/io/read-policy/read-repair.d.ts +74 -0
- package/dist/io/read-policy/read-repair.js +119 -0
- package/dist/io/style/cell-style-resolution.d.ts +25 -0
- package/dist/io/style/cell-style-resolution.js +30 -0
- package/dist/io/xlsb/formula.js +4 -2
- package/dist/io/xlsb/ptg-functions.js +110 -0
- package/dist/io/xlsb/read-metadata.d.ts +7 -0
- package/dist/io/xlsb/read-metadata.js +69 -0
- package/dist/io/xlsb/read-worksheet.d.ts +6 -0
- package/dist/io/xlsb/read-worksheet.js +95 -37
- package/dist/io/xlsb/read.js +26 -8
- package/dist/io/xlsb/record-types.d.ts +13 -0
- package/dist/io/xlsb/record-types.js +13 -0
- package/dist/io/xlsb/sheet-protection.d.ts +20 -0
- package/dist/io/xlsb/sheet-protection.js +60 -0
- package/dist/io/xlsx/cell-accumulator.d.ts +20 -12
- package/dist/io/xlsx/cell-accumulator.js +49 -19
- package/dist/io/xlsx/cell-metadata.d.ts +39 -0
- package/dist/io/xlsx/cell-metadata.js +162 -0
- package/dist/io/xlsx/cell-value.d.ts +16 -4
- package/dist/io/xlsx/cell-value.js +38 -21
- package/dist/io/xlsx/color-xml.js +1 -1
- package/dist/io/xlsx/column-span.d.ts +11 -0
- package/dist/io/xlsx/column-span.js +9 -0
- package/dist/io/xlsx/comments.d.ts +3 -28
- package/dist/io/xlsx/comments.js +3 -65
- package/dist/io/xlsx/conditional-formatting.d.ts +42 -25
- package/dist/io/xlsx/conditional-formatting.js +424 -129
- package/dist/io/xlsx/data-validation.d.ts +12 -7
- package/dist/io/xlsx/data-validation.js +41 -29
- package/dist/io/xlsx/edit-vba.js +43 -36
- package/dist/io/xlsx/hyperlinks.d.ts +16 -50
- package/dist/io/xlsx/hyperlinks.js +8 -37
- package/dist/io/xlsx/images.d.ts +49 -16
- package/dist/io/xlsx/images.js +145 -44
- package/dist/io/xlsx/namespaces.d.ts +8 -0
- package/dist/io/xlsx/namespaces.js +4 -0
- package/dist/io/xlsx/package-plan.d.ts +48 -15
- package/dist/io/xlsx/package-plan.js +46 -9
- package/dist/io/xlsx/part-names.d.ts +6 -8
- package/dist/io/xlsx/part-names.js +3 -7
- package/dist/io/xlsx/pivot.d.ts +5 -5
- package/dist/io/xlsx/pivot.js +23 -22
- package/dist/io/xlsx/preserved-splices.d.ts +6 -0
- package/dist/io/xlsx/preserved-splices.js +74 -0
- package/dist/io/xlsx/read-comments.d.ts +29 -0
- package/dist/io/xlsx/read-comments.js +75 -0
- package/dist/io/xlsx/read-parts.d.ts +2 -2
- package/dist/io/xlsx/read-parts.js +44 -37
- package/dist/io/xlsx/read-pivot.js +9 -3
- package/dist/io/xlsx/read-rich-runs.d.ts +8 -5
- package/dist/io/xlsx/read-rich-runs.js +18 -1
- package/dist/io/xlsx/read-rows.d.ts +18 -7
- package/dist/io/xlsx/read-rows.js +47 -37
- package/dist/io/xlsx/read-styles.d.ts +0 -25
- package/dist/io/xlsx/read-styles.js +39 -34
- package/dist/io/xlsx/read-workbook-xml.d.ts +6 -0
- package/dist/io/xlsx/read-workbook-xml.js +9 -4
- package/dist/io/xlsx/read-worksheet.d.ts +8 -3
- package/dist/io/xlsx/read-worksheet.js +45 -23
- package/dist/io/xlsx/read.d.ts +0 -4
- package/dist/io/xlsx/read.js +17 -21
- package/dist/io/xlsx/relationships.d.ts +3 -0
- package/dist/io/xlsx/relationships.js +4 -0
- package/dist/io/xlsx/row-position.d.ts +3 -1
- package/dist/io/xlsx/row-xml.d.ts +18 -7
- package/dist/io/xlsx/row-xml.js +54 -35
- package/dist/io/xlsx/sheet-properties.js +68 -42
- package/dist/io/xlsx/strict-parts.d.ts +7 -0
- package/dist/io/xlsx/strict-parts.js +171 -0
- package/dist/io/xlsx/style-elements.d.ts +0 -2
- package/dist/io/xlsx/style-elements.js +9 -29
- package/dist/io/xlsx/styles.d.ts +5 -0
- package/dist/io/xlsx/styles.js +11 -5
- package/dist/io/xlsx/tables.d.ts +10 -2
- package/dist/io/xlsx/tables.js +49 -42
- package/dist/io/xlsx/theme-xml.d.ts +6 -0
- package/dist/io/xlsx/theme-xml.js +16 -19
- package/dist/io/xlsx/threaded-comments.d.ts +6 -1
- package/dist/io/xlsx/threaded-comments.js +14 -7
- package/dist/io/xlsx/workbook-xml.d.ts +13 -24
- package/dist/io/xlsx/workbook-xml.js +15 -33
- package/dist/io/xlsx/worksheet-xml.d.ts +5 -2
- package/dist/io/xlsx/worksheet-xml.js +37 -69
- package/dist/io/xlsx/write-stream.d.ts +28 -6
- package/dist/io/xlsx/write-stream.js +42 -17
- package/dist/io/xlsx/write.d.ts +11 -4
- package/dist/io/xlsx/write.js +153 -90
- package/dist/rel-type.d.ts +9 -0
- package/dist/rel-type.js +3 -0
- package/dist/vba/bytes.d.ts +2 -0
- package/dist/vba/bytes.js +11 -0
- package/dist/vba/cfb-format.d.ts +47 -0
- package/dist/vba/cfb-format.js +34 -0
- package/dist/vba/cfb-writer.d.ts +1 -2
- package/dist/vba/cfb-writer.js +33 -36
- package/dist/vba/cfb.d.ts +9 -4
- package/dist/vba/cfb.js +55 -43
- package/dist/vba/dir-records.d.ts +6 -0
- package/dist/vba/dir-records.js +10 -2
- package/dist/vba/errors.d.ts +4 -4
- package/dist/vba/index.d.ts +0 -2
- package/dist/vba/index.js +0 -2
- package/dist/vba/ms-ovba.d.ts +6 -2
- package/dist/vba/ms-ovba.js +15 -6
- package/dist/vba/project-editor.js +102 -87
- package/dist/vba/project.d.ts +4 -0
- package/dist/vba/project.js +12 -6
- package/dist/vba/vba-encoding.d.ts +4 -10
- package/dist/vba/vba-encoding.js +2 -15
- package/dist/xml/xml-read.d.ts +29 -1
- package/dist/xml/xml-read.js +56 -0
- package/dist/xml/xml-scan.d.ts +13 -0
- package/dist/xml/xml-scan.js +58 -7
- package/dist/xml/xml.d.ts +33 -1
- package/dist/xml/xml.js +22 -0
- package/package.json +5 -4
- package/skills/ts-xlsx-upstream/SKILL.md +21 -13
- package/dist/core/modern-functions.d.ts +0 -1
- package/dist/io/xlsx/cell-style-resolution.d.ts +0 -25
- package/dist/io/xlsx/cell-style-resolution.js +0 -29
- package/dist/io/xlsx/column-budget.d.ts +0 -26
- package/dist/io/xlsx/read-repair.d.ts +0 -26
- package/dist/io/xlsx/read-repair.js +0 -39
package/dist/io/xlsx/read.js
CHANGED
|
@@ -3,20 +3,19 @@ import { Workbook } from '../../core/workbook.js';
|
|
|
3
3
|
import { parseXmlPasses } from '../../xml/xml-read.js';
|
|
4
4
|
import { UnsupportedFormatError } from '../opc/errors.js';
|
|
5
5
|
import { contentTypeResolver, openSpreadsheetPackage, readPartRelationships, } from '../opc/read-opc.js';
|
|
6
|
+
import { admitArrayRanges, admitting, repairedSheetNames } from '../read-policy/read-repair.js';
|
|
6
7
|
import { readXlsbPackage } from '../xlsb/read.js';
|
|
7
|
-
import {
|
|
8
|
-
import { conditionalFormattingPass } from './conditional-formatting.js';
|
|
8
|
+
import { readCellMetadata } from './cell-metadata.js';
|
|
9
|
+
import { applyConditionalFormattings, conditionalFormattingPass } from './conditional-formatting.js';
|
|
9
10
|
import { applyDataValidations, dataValidationPass, extendedDataValidationPass, } from './data-validation.js';
|
|
10
11
|
import { applyHyperlinks, sheetHyperlinkPass } from './hyperlinks.js';
|
|
11
12
|
import { SHARED_STRINGS_PART, STYLES_PART } from './part-names.js';
|
|
13
|
+
import { applyNotes } from './read-comments.js';
|
|
12
14
|
import { readRootPreservedReferences, readSheetBackground, readSheetComments, readSheetCommentThreads, readSheetImages, readSheetPivotTables, readSheetPreservedReferences, readSheetPrinterSettings, readSheetTables, readWorkbookPersons, externalReferenceRegistrationsPass, pivotCacheRegistrationsPass, readWorkbookPreservedReferences, readWorkbookTheme, worksheetReferencePass, } from './read-parts.js';
|
|
13
|
-
import { admitting, repairSheetName } from './read-repair.js';
|
|
14
15
|
import { parseSharedStrings } from './read-shared-strings.js';
|
|
15
16
|
import { parseStyleTable } from './read-styles.js';
|
|
16
17
|
import { applyAppProperties, applyCoreProperties, definedNamesPass, workbookPropertiesPass, workbookProtectionPass, workbookSheetsPass, workbookViewPass, } from './read-workbook-xml.js';
|
|
17
18
|
import { worksheetPass } from './read-worksheet.js';
|
|
18
|
-
export { parseStyleTable } from './read-styles.js';
|
|
19
|
-
export { workbookPropertiesPass, workbookSheetsPass, workbookViewPass, } from './read-workbook-xml.js';
|
|
20
19
|
export function readXlsx(data, options = {}) {
|
|
21
20
|
const { files, pkg, documentPath, workbookXml } = openSpreadsheetPackage(data, options.maxUncompressedBytes);
|
|
22
21
|
const { partText, partBytes } = pkg;
|
|
@@ -37,6 +36,7 @@ export function readXlsx(data, options = {}) {
|
|
|
37
36
|
contentTypeOf,
|
|
38
37
|
sharedStrings,
|
|
39
38
|
xfStyles,
|
|
39
|
+
cellMetadata: readCellMetadata(workbookRels),
|
|
40
40
|
imageIdByMediaPath: new Map(),
|
|
41
41
|
};
|
|
42
42
|
workbook[INTERNAL].restoreDifferentialStyles([...preserved.dxfs]);
|
|
@@ -69,14 +69,13 @@ export function readXlsx(data, options = {}) {
|
|
|
69
69
|
]);
|
|
70
70
|
workbook.protection = protection.result();
|
|
71
71
|
readWorkbookPersons(context, workbookRels);
|
|
72
|
+
const sheetContext = { ...context, definedNames: definedNames.spellings() };
|
|
72
73
|
const sheetOrder = [];
|
|
73
|
-
const
|
|
74
|
-
for (const { name, relId, state } of sheets.result()) {
|
|
74
|
+
for (const { name, relId, state } of repairedSheetNames(sheets.result())) {
|
|
75
75
|
const target = workbookRels.byId(relId)?.target;
|
|
76
|
-
const sheet = workbook.addWorksheet(
|
|
77
|
-
takenSheetNames.add(sheet.name.toLowerCase());
|
|
76
|
+
const sheet = workbook.addWorksheet(name, state === undefined ? undefined : { state });
|
|
78
77
|
sheetOrder.push(sheet.name);
|
|
79
|
-
readSheet(sheet, target === undefined ? undefined : workbookRels.pathOf(target),
|
|
78
|
+
readSheet(sheet, target === undefined ? undefined : workbookRels.pathOf(target), sheetContext);
|
|
80
79
|
}
|
|
81
80
|
readWorkbookPreservedReferences(context, workbookRels, {
|
|
82
81
|
cacheIdByRelId: pivotCaches.result(),
|
|
@@ -91,23 +90,24 @@ export function readXlsx(data, options = {}) {
|
|
|
91
90
|
return workbook;
|
|
92
91
|
}
|
|
93
92
|
function readSheet(sheet, path, context) {
|
|
94
|
-
const { pkg, workbook, sharedStrings, xfStyles } = context;
|
|
93
|
+
const { pkg, workbook, sharedStrings, xfStyles, definedNames, cellMetadata } = context;
|
|
95
94
|
const { partText } = pkg;
|
|
96
95
|
const sheetXml = path === undefined ? undefined : partText(path);
|
|
97
96
|
const hyperlinks = sheetHyperlinkPass();
|
|
98
|
-
const validations = dataValidationPass();
|
|
99
|
-
const extendedValidations = extendedDataValidationPass();
|
|
100
|
-
const formattings = conditionalFormattingPass();
|
|
97
|
+
const validations = dataValidationPass(definedNames);
|
|
98
|
+
const extendedValidations = extendedDataValidationPass(definedNames);
|
|
99
|
+
const formattings = conditionalFormattingPass(definedNames, (fragment) => workbook[INTERNAL].adoptDifferentialStyle(fragment));
|
|
101
100
|
const references = worksheetReferencePass();
|
|
102
101
|
if (sheetXml !== undefined) {
|
|
103
102
|
parseXmlPasses(sheetXml, [
|
|
104
|
-
worksheetPass(sheet, sharedStrings, xfStyles, workbook.dateEpoch),
|
|
103
|
+
worksheetPass(sheet, sharedStrings, xfStyles, workbook.dateEpoch, definedNames, cellMetadata),
|
|
105
104
|
hyperlinks,
|
|
106
105
|
validations,
|
|
107
106
|
extendedValidations,
|
|
108
107
|
formattings,
|
|
109
108
|
references,
|
|
110
109
|
]);
|
|
110
|
+
admitArrayRanges(sheet);
|
|
111
111
|
}
|
|
112
112
|
if (path === undefined)
|
|
113
113
|
return;
|
|
@@ -115,11 +115,7 @@ function readSheet(sheet, path, context) {
|
|
|
115
115
|
if (sheetXml !== undefined) {
|
|
116
116
|
applyHyperlinks(sheet, hyperlinks.result(), (id) => sheetRels.byId(id)?.target);
|
|
117
117
|
applyDataValidations(sheet, [...validations.result(), ...extendedValidations.result()]);
|
|
118
|
-
|
|
119
|
-
admitting(() => {
|
|
120
|
-
sheet.addConditionalFormatting(cf);
|
|
121
|
-
});
|
|
122
|
-
}
|
|
118
|
+
applyConditionalFormattings(sheet, formattings.result());
|
|
123
119
|
}
|
|
124
120
|
const threads = readSheetCommentThreads(context, sheetRels);
|
|
125
121
|
if (threads.length > 0)
|
|
@@ -132,7 +128,7 @@ function readSheet(sheet, path, context) {
|
|
|
132
128
|
if (sheetXml !== undefined) {
|
|
133
129
|
readSheetPreservedReferences(context, sheetRels, references.result(), sheet);
|
|
134
130
|
}
|
|
135
|
-
readSheetTables(context, sheetRels, sheet);
|
|
131
|
+
readSheetTables(context, sheetRels, sheet, definedNames);
|
|
136
132
|
readSheetPivotTables(context, sheetRels, sheet);
|
|
137
133
|
const printerSettings = readSheetPrinterSettings(sheetRels);
|
|
138
134
|
if (printerSettings !== undefined)
|
|
@@ -28,6 +28,9 @@ export declare const REL: {
|
|
|
28
28
|
readonly pivotTable: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable";
|
|
29
29
|
readonly pivotCacheDefinition: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition";
|
|
30
30
|
readonly pivotCacheRecords: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheRecords";
|
|
31
|
+
readonly sheetMetadata: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata";
|
|
32
|
+
readonly rdRichValue: "http://schemas.microsoft.com/office/2017/06/relationships/rdRichValue";
|
|
33
|
+
readonly rdRichValueStructure: "http://schemas.microsoft.com/office/2017/06/relationships/rdRichValueStructure";
|
|
31
34
|
readonly threadedComment: "http://schemas.microsoft.com/office/2017/10/relationships/threadedComment";
|
|
32
35
|
readonly person: "http://schemas.microsoft.com/office/2017/10/relationships/person";
|
|
33
36
|
};
|
|
@@ -13,6 +13,7 @@ export const NS = {
|
|
|
13
13
|
xsi: 'http://www.w3.org/2001/XMLSchema-instance',
|
|
14
14
|
};
|
|
15
15
|
const MS_OFFICE_2017_RELS_NS = 'http://schemas.microsoft.com/office/2017/10/relationships';
|
|
16
|
+
const RICH_DATA_RELS_NS = 'http://schemas.microsoft.com/office/2017/06/relationships';
|
|
16
17
|
export const REL = {
|
|
17
18
|
worksheet: `${NS.docRels}/worksheet`,
|
|
18
19
|
styles: `${NS.docRels}/styles`,
|
|
@@ -31,6 +32,9 @@ export const REL = {
|
|
|
31
32
|
pivotTable: `${NS.docRels}/pivotTable`,
|
|
32
33
|
pivotCacheDefinition: `${NS.docRels}/pivotCacheDefinition`,
|
|
33
34
|
pivotCacheRecords: `${NS.docRels}/pivotCacheRecords`,
|
|
35
|
+
sheetMetadata: `${NS.docRels}/sheetMetadata`,
|
|
36
|
+
rdRichValue: `${RICH_DATA_RELS_NS}/rdRichValue`,
|
|
37
|
+
rdRichValueStructure: `${RICH_DATA_RELS_NS}/rdRichValueStructure`,
|
|
34
38
|
threadedComment: `${MS_OFFICE_2017_RELS_NS}/threadedComment`,
|
|
35
39
|
person: `${MS_OFFICE_2017_RELS_NS}/person`,
|
|
36
40
|
};
|
|
@@ -6,7 +6,9 @@ export interface RowPosition {
|
|
|
6
6
|
/**
|
|
7
7
|
* Whether that number names a row the grid has. A row past the ceiling is dropped whole by both
|
|
8
8
|
* readers rather than clamped: an `r` names one row, so there is nothing to fold it onto, and
|
|
9
|
-
* clamping would silently move its formatting to the last row of the sheet.
|
|
9
|
+
* clamping would silently move its formatting to the last row of the sheet. Its cells go with it,
|
|
10
|
+
* even one whose own `r` is in the grid, because `CellAccumulator` places no cell outside an
|
|
11
|
+
* in-grid row.
|
|
10
12
|
*/
|
|
11
13
|
readonly inGrid: boolean;
|
|
12
14
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { FormulaPlacement } from '../../core/array-formula-ranges.ts';
|
|
1
2
|
import { type Cell } from '../../core/cell.ts';
|
|
2
3
|
import { type DateEpoch } from '../../core/date.ts';
|
|
3
4
|
import type { ColumnProperties, RowProperties, Worksheet } from '../../core/worksheet.ts';
|
|
5
|
+
import type { WorkbookMetadataTable } from './cell-metadata.ts';
|
|
4
6
|
import type { CommentCell } from './comments.ts';
|
|
5
|
-
import type { CollectedHyperlink } from './hyperlinks.ts';
|
|
6
7
|
import type { SharedFormulaRole } from './shared-formulas.ts';
|
|
7
8
|
import type { SharedStringTable } from './shared-strings.ts';
|
|
8
9
|
import type { StyleRegistry } from './styles.ts';
|
|
@@ -63,14 +64,18 @@ export interface FlushedSheet {
|
|
|
63
64
|
readonly hidden: boolean;
|
|
64
65
|
}>;
|
|
65
66
|
/**
|
|
66
|
-
* The
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* been evicted, so a streamed row's link kept its visible label and silently lost its destination.
|
|
67
|
+
* The notes the flushed rows carried, on the same terms and for the same reason. A note is
|
|
68
|
+
* serialised outside the `<row>`, into the comments and VML parts, and the buffered pass gathers
|
|
69
|
+
* notes by walking the sheet's rows at commit time, which finds nothing on a row whose cells have
|
|
70
|
+
* already been evicted. A hyperlink needs no such record: it lives beside the grid, on the sheet.
|
|
71
71
|
*/
|
|
72
|
-
readonly hyperlinks: readonly CollectedHyperlink[];
|
|
73
72
|
readonly notes: readonly CommentCell[];
|
|
73
|
+
/**
|
|
74
|
+
* The formulas the flushed rows carried, on the same terms again: whether an array formula's range
|
|
75
|
+
* holds another formula, or shares a cell with another's, is a question about other rows, and the
|
|
76
|
+
* writer asks it of the whole sheet at commit.
|
|
77
|
+
*/
|
|
78
|
+
readonly formulas: readonly FormulaPlacement[];
|
|
74
79
|
}
|
|
75
80
|
/**
|
|
76
81
|
* A column's style facets are defaults its cells inherit unless they override them; the writer
|
|
@@ -91,6 +96,12 @@ export interface RowRenderContext {
|
|
|
91
96
|
readonly collapsedSummaries: ReadonlySet<number>;
|
|
92
97
|
/** The workbook's date system, which is what a `Date` cell's serial counts from. */
|
|
93
98
|
readonly dateEpoch: DateEpoch;
|
|
99
|
+
/** The defined names a bare name in this sheet's formulas resolves to, as `formulaNamesInScope`
|
|
100
|
+
* gives them: a function passed as a value is written bare where one of them captures its name. */
|
|
101
|
+
readonly formulaNames: ReadonlySet<string>;
|
|
102
|
+
/** The workbook's metadata, which a dynamic-array formula's cell and a rich-value error's cell point
|
|
103
|
+
* into. Shared by every row of every sheet, since the parts it becomes are the workbook's. */
|
|
104
|
+
readonly cellMetadata: WorkbookMetadataTable;
|
|
94
105
|
}
|
|
95
106
|
/**
|
|
96
107
|
* Serialise one row to its `<row>` element, or '' when the row has neither data nor its own
|
package/dist/io/xlsx/row-xml.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { encodeRange, tryDecodeAnchoredRange } from '../../core/address.js';
|
|
1
2
|
import { cellHasOwnStyle } from '../../core/cell.js';
|
|
2
3
|
import { DEFAULT_DATE_NUMFMT, dateToSerial } from '../../core/date.js';
|
|
3
4
|
import { mangleFormula } from '../../core/formula.js';
|
|
4
5
|
import { NAMED_STYLE_ID } from '../../core/internal.js';
|
|
5
6
|
import { CELL_STYLE_FACETS } from '../../core/style.js';
|
|
6
|
-
import { detectValueType, isDataTableFormulaValue, isErrorValue, isFormulaValue,
|
|
7
|
-
import { AuthoringError, InternalError } from '../../errors.js';
|
|
8
|
-
import { boolAttr, escapeAttr, escapeSpreadsheetText, escapeText, numberText, textAttr, textElement, } from '../../xml/xml.js';
|
|
7
|
+
import { detectValueType, isArrayFormulaValue, isDataTableFormulaValue, isErrorCode, isErrorValue, isFormulaValue, isRichTextValue, isSharedFormulaValue, } from '../../core/value.js';
|
|
8
|
+
import { AuthoringError, InternalError, quoted } from '../../errors.js';
|
|
9
|
+
import { boolAttr, checkedToken, escapeAttr, escapeSpreadsheetText, escapeText, numberText, nonDefaultNumAttr, textAttr, textElement, } from '../../xml/xml.js';
|
|
9
10
|
import { richTextRunsXml } from './rich-text.js';
|
|
10
11
|
export class Extent {
|
|
11
12
|
top = Infinity;
|
|
@@ -53,7 +54,7 @@ export function renderRow(entry, ctx) {
|
|
|
53
54
|
const cellsXml = rendered
|
|
54
55
|
.map((cell) => {
|
|
55
56
|
const style = ctx.styles.styleId(composeCellStyle(cell, rowFill, ctx.columnDefaults.get(cell.col)));
|
|
56
|
-
return cellXml(cell, style, ctx.sharedRoles.get(cell.address), ctx
|
|
57
|
+
return cellXml(cell, style, ctx.sharedRoles.get(cell.address), ctx);
|
|
57
58
|
})
|
|
58
59
|
.join('');
|
|
59
60
|
let minCol = Infinity;
|
|
@@ -104,18 +105,19 @@ function rowAttrs(properties, styles, collapsedSummary) {
|
|
|
104
105
|
function dateDefaultNumFmt(value) {
|
|
105
106
|
const date = value instanceof Date
|
|
106
107
|
? value
|
|
107
|
-
: (isFormulaValue(value) || isSharedFormulaValue(value)
|
|
108
|
+
: (isFormulaValue(value) || isSharedFormulaValue(value) || isArrayFormulaValue(value)) &&
|
|
109
|
+
value.result instanceof Date
|
|
108
110
|
? value.result
|
|
109
111
|
: undefined;
|
|
110
112
|
return date !== undefined && !Number.isNaN(date.getTime()) ? DEFAULT_DATE_NUMFMT : undefined;
|
|
111
113
|
}
|
|
112
|
-
function cellElement(ref, s, type, body) {
|
|
113
|
-
const
|
|
114
|
-
return body === '' ? `<c r="${ref}"${
|
|
114
|
+
function cellElement(ref, s, type, body, cm = '', vm = '') {
|
|
115
|
+
const attrs = `${s}${type === '' ? '' : ` t="${type}"`}${cm}${vm}`;
|
|
116
|
+
return body === '' ? `<c r="${ref}"${attrs}/>` : `<c r="${ref}"${attrs}>${body}</c>`;
|
|
115
117
|
}
|
|
116
118
|
const UNWRITABLE = { type: '', v: null };
|
|
117
119
|
const vElement = (v) => (v === null ? '' : `<v>${v}</v>`);
|
|
118
|
-
function valueBody(value,
|
|
120
|
+
function valueBody(value, ctx) {
|
|
119
121
|
if (typeof value === 'number') {
|
|
120
122
|
return Number.isFinite(value) ? { type: '', v: numberText(value) } : UNWRITABLE;
|
|
121
123
|
}
|
|
@@ -124,22 +126,28 @@ function valueBody(value, epoch) {
|
|
|
124
126
|
if (value instanceof Date) {
|
|
125
127
|
return Number.isNaN(value.getTime())
|
|
126
128
|
? UNWRITABLE
|
|
127
|
-
: { type: '', v: numberText(dateToSerial(value,
|
|
129
|
+
: { type: '', v: numberText(dateToSerial(value, ctx.dateEpoch)) };
|
|
130
|
+
}
|
|
131
|
+
if (isErrorValue(value)) {
|
|
132
|
+
checkedToken(value.error, isErrorCode, 'cell error value');
|
|
133
|
+
const vm = ctx.cellMetadata.markRichValueError(value.error);
|
|
134
|
+
return vm === undefined
|
|
135
|
+
? { type: 'e', v: value.error }
|
|
136
|
+
: { type: 'e', v: '#VALUE!', vm: ` vm="${vm}"` };
|
|
128
137
|
}
|
|
129
|
-
if (isErrorValue(value))
|
|
130
|
-
return { type: 'e', v: value.error };
|
|
131
138
|
return undefined;
|
|
132
139
|
}
|
|
133
|
-
function cellXml(cell, style, shared,
|
|
140
|
+
function cellXml(cell, style, shared, ctx) {
|
|
141
|
+
const { sharedStrings } = ctx;
|
|
134
142
|
const ref = cell.address;
|
|
135
143
|
const value = cell.value;
|
|
136
144
|
const s = style !== 0 ? ` s="${style}"` : '';
|
|
137
|
-
const formula = cellFormulaXml(
|
|
145
|
+
const formula = cellFormulaXml(cell, s, shared, ctx);
|
|
138
146
|
if (formula !== undefined)
|
|
139
147
|
return formula;
|
|
140
|
-
const body = valueBody(value,
|
|
148
|
+
const body = valueBody(value, ctx);
|
|
141
149
|
if (body !== undefined)
|
|
142
|
-
return cellElement(ref, s, body.type, vElement(body.v));
|
|
150
|
+
return cellElement(ref, s, body.type, vElement(body.v), '', body.vm);
|
|
143
151
|
if (typeof value === 'string' || isRichTextValue(value)) {
|
|
144
152
|
if (sharedStrings !== null) {
|
|
145
153
|
return cellElement(ref, s, 's', vElement(`${sharedStrings.intern(value)}`));
|
|
@@ -147,46 +155,57 @@ function cellXml(cell, style, shared, sharedStrings, epoch) {
|
|
|
147
155
|
const inline = typeof value === 'string' ? textElement(value) : richTextRunsXml(value.richText);
|
|
148
156
|
return cellElement(ref, s, 'inlineStr', `<is>${inline}</is>`);
|
|
149
157
|
}
|
|
150
|
-
if (isHyperlinkValue(value)) {
|
|
151
|
-
const label = typeof value.text === 'string'
|
|
152
|
-
? textElement(value.text)
|
|
153
|
-
: richTextRunsXml(value.text.richText);
|
|
154
|
-
return cellElement(ref, s, 'inlineStr', `<is>${label}</is>`);
|
|
155
|
-
}
|
|
156
158
|
if (value === null)
|
|
157
159
|
return cellElement(ref, s, '', '');
|
|
158
160
|
throw new InternalError(`writing a ${detectValueType(value)} cell value has no arm: every CellValue kind is handled above`);
|
|
159
161
|
}
|
|
160
|
-
function cellFormulaXml(
|
|
162
|
+
function cellFormulaXml(cell, s, shared, ctx) {
|
|
163
|
+
const { formulaNames } = ctx;
|
|
164
|
+
const { address: ref, value } = cell;
|
|
161
165
|
if (shared !== undefined) {
|
|
162
166
|
if (shared.ref !== undefined && isFormulaValue(value)) {
|
|
163
|
-
const f = `<f t="shared" ref="${shared.ref}" si="${shared.si}">${escapeText(mangleFormula(value.formula))}</f>`;
|
|
164
|
-
return formulaBodyXml(ref, s, f, value.result,
|
|
167
|
+
const f = `<f t="shared" ref="${shared.ref}" si="${shared.si}">${escapeText(mangleFormula(value.formula, formulaNames))}</f>`;
|
|
168
|
+
return formulaBodyXml(ref, s, f, value.result, ctx);
|
|
165
169
|
}
|
|
166
170
|
const result = isSharedFormulaValue(value) ? value.result : undefined;
|
|
167
|
-
return formulaBodyXml(ref, s, `<f t="shared" si="${shared.si}"/>`, result,
|
|
171
|
+
return formulaBodyXml(ref, s, `<f t="shared" si="${shared.si}"/>`, result, ctx);
|
|
168
172
|
}
|
|
169
173
|
if (isDataTableFormulaValue(value)) {
|
|
170
174
|
const attrs = `ref="${escapeAttr(value.ref)}"` +
|
|
171
175
|
boolAttr('dt2D', value.dataTable2D) +
|
|
172
176
|
boolAttr('dtr', value.dataTableRow) +
|
|
177
|
+
(value.r1Deleted === true ? ' del1="1"' : '') +
|
|
178
|
+
(value.r2Deleted === true ? ' del2="1"' : '') +
|
|
173
179
|
textAttr('r1', value.r1) +
|
|
174
180
|
textAttr('r2', value.r2);
|
|
175
|
-
return formulaBodyXml(ref, s, `<f t="dataTable" ${attrs}/>`, value.result,
|
|
181
|
+
return formulaBodyXml(ref, s, `<f t="dataTable" ${attrs}/>`, value.result, ctx);
|
|
182
|
+
}
|
|
183
|
+
if (isArrayFormulaValue(value)) {
|
|
184
|
+
const cm = value.dynamic === true ? ` cm="${ctx.cellMetadata.markDynamicArray()}"` : '';
|
|
185
|
+
const f = `<f t="array" ref="${arrayFormulaRange(cell, value.ref)}">${escapeText(mangleFormula(value.formula, formulaNames))}</f>`;
|
|
186
|
+
return formulaBodyXml(ref, s, f, value.result, ctx, cm);
|
|
176
187
|
}
|
|
177
188
|
if (isFormulaValue(value)) {
|
|
178
|
-
return formulaBodyXml(ref, s, `<f>${escapeText(mangleFormula(value.formula))}</f>`, value.result,
|
|
189
|
+
return formulaBodyXml(ref, s, `<f>${escapeText(mangleFormula(value.formula, formulaNames))}</f>`, value.result, ctx);
|
|
179
190
|
}
|
|
180
191
|
return undefined;
|
|
181
192
|
}
|
|
182
|
-
function
|
|
193
|
+
function arrayFormulaRange(cell, ref) {
|
|
194
|
+
const range = tryDecodeAnchoredRange(ref, cell.col, cell.row);
|
|
195
|
+
if (range === undefined) {
|
|
196
|
+
throw new AuthoringError(`the array formula in ${cell.address} fills ${quoted(ref)}, which is not a range starting at ${cell.address}`);
|
|
197
|
+
}
|
|
198
|
+
return encodeRange(range);
|
|
199
|
+
}
|
|
200
|
+
function formulaBodyXml(ref, s, f, result, ctx, cm = '') {
|
|
183
201
|
if (result === undefined)
|
|
184
|
-
return cellElement(ref, s, '', f);
|
|
185
|
-
const body = valueBody(result,
|
|
186
|
-
if (body !== undefined)
|
|
187
|
-
return cellElement(ref, s, body.type, f + vElement(body.v));
|
|
202
|
+
return cellElement(ref, s, '', f, cm);
|
|
203
|
+
const body = valueBody(result, ctx);
|
|
204
|
+
if (body !== undefined) {
|
|
205
|
+
return cellElement(ref, s, body.type, f + vElement(body.v), cm, body.vm);
|
|
206
|
+
}
|
|
188
207
|
if (typeof result === 'string') {
|
|
189
|
-
return cellElement(ref, s, 'str', f + vElement(escapeSpreadsheetText(result)));
|
|
208
|
+
return cellElement(ref, s, 'str', f + vElement(escapeSpreadsheetText(result)), cm);
|
|
190
209
|
}
|
|
191
210
|
throw new InternalError('writing a non-primitive formula result has no arm: every FormulaResult kind is handled above');
|
|
192
211
|
}
|
|
@@ -199,5 +218,5 @@ export function outlineAttr(name, level) {
|
|
|
199
218
|
if (level === undefined)
|
|
200
219
|
return '';
|
|
201
220
|
assertWritableLevel(name, level);
|
|
202
|
-
return level
|
|
221
|
+
return nonDefaultNumAttr(name, level, 0);
|
|
203
222
|
}
|
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import { encodeAddress } from '../../core/address.js';
|
|
1
|
+
import { encodeAddress, MAX_COLUMN, MAX_ROW } from '../../core/address.js';
|
|
2
2
|
import { isCustomFilterOperator, } from '../../core/autofilter.js';
|
|
3
3
|
import { HEADER_FOOTER_ELEMENTS, MARGIN_SIDES, PAGE_SETUP_FACETS, PRINT_OPTION_FLAGS, } from '../../core/page-setup.js';
|
|
4
|
-
import { SHEET_PROTECTION_FLAGS, } from '../../core/protection.js';
|
|
4
|
+
import { isLegacyPasswordHash, SHEET_PROTECTION_FLAGS, } from '../../core/protection.js';
|
|
5
|
+
import { assertWritableNumber, AuthoringError } from '../../errors.js';
|
|
5
6
|
import { numFinite, numInteger } from '../../xml/xml-attrs.js';
|
|
6
|
-
import {
|
|
7
|
+
import { boolStrict, boolTristate } from '../../xml/xml-scan.js';
|
|
7
8
|
import { boolAttr, checkedToken, escapeAttr, escapeSpreadsheetText, numAttr, numberText, } from '../../xml/xml.js';
|
|
8
9
|
import { colorAttrs, parseColor } from './color-xml.js';
|
|
9
10
|
export function sheetViewsXml(view, active) {
|
|
10
11
|
const selected = active ? ' tabSelected="1"' : '';
|
|
11
12
|
const gridLines = view.showGridLines === false ? ' showGridLines="0"' : '';
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const normal = `<sheetViews><sheetView${gridLines}${selected} workbookViewId="0"/></sheetViews>`;
|
|
14
|
+
if (view.state !== 'frozen')
|
|
15
|
+
return normal;
|
|
16
|
+
const xSplit = frozenSplit('xSplit', view.xSplit, MAX_COLUMN);
|
|
17
|
+
const ySplit = frozenSplit('ySplit', view.ySplit, MAX_ROW);
|
|
18
|
+
if (xSplit === 0 && ySplit === 0)
|
|
19
|
+
return normal;
|
|
17
20
|
const topLeftCell = view.topLeftCell ?? encodeAddress(xSplit + 1, ySplit + 1);
|
|
18
21
|
const activePane = xSplit > 0 && ySplit > 0 ? 'bottomRight' : xSplit > 0 ? 'topRight' : 'bottomLeft';
|
|
19
22
|
const pane = '<pane' +
|
|
@@ -23,6 +26,15 @@ export function sheetViewsXml(view, active) {
|
|
|
23
26
|
const selection = `<selection pane="${activePane}" activeCell="${escapeAttr(topLeftCell)}" sqref="${escapeAttr(topLeftCell)}"/>`;
|
|
24
27
|
return `<sheetViews><sheetView${gridLines}${selected} workbookViewId="0">${pane}${selection}</sheetView></sheetViews>`;
|
|
25
28
|
}
|
|
29
|
+
function frozenSplit(name, value, lines) {
|
|
30
|
+
if (value === undefined)
|
|
31
|
+
return 0;
|
|
32
|
+
assertWritableNumber(value);
|
|
33
|
+
if (!Number.isInteger(value) || value < 0 || value >= lines) {
|
|
34
|
+
throw new AuthoringError(`cannot write ${name}="${value}": a frozen split is a whole count from 0 to ${lines - 1}`);
|
|
35
|
+
}
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
26
38
|
export function sheetPrXml(sheet) {
|
|
27
39
|
const attrs = sheet.codeName === undefined ? '' : ` codeName="${escapeAttr(sheet.codeName)}"`;
|
|
28
40
|
const children = (sheet.tabColor !== undefined ? `<tabColor ${colorAttrs(sheet.tabColor)}/>` : '') +
|
|
@@ -42,8 +54,11 @@ function outlinePrXml(outline) {
|
|
|
42
54
|
export function sheetProtectionXml(protection) {
|
|
43
55
|
if (protection === undefined)
|
|
44
56
|
return '';
|
|
45
|
-
const { flags, credential } = protection;
|
|
57
|
+
const { flags, credential, legacyPasswordHash } = protection;
|
|
46
58
|
let attrs = '';
|
|
59
|
+
if (legacyPasswordHash !== undefined) {
|
|
60
|
+
attrs += ` password="${checkedToken(legacyPasswordHash, isLegacyPasswordHash, 'legacy sheet password hash')}"`;
|
|
61
|
+
}
|
|
47
62
|
if (credential !== undefined) {
|
|
48
63
|
attrs +=
|
|
49
64
|
` algorithmName="${escapeAttr(credential.algorithmName)}"` +
|
|
@@ -143,15 +158,15 @@ export function pageSetupXml(pageSetup, printerSettingsRelId) {
|
|
|
143
158
|
export function pageBreaksXml(breaks, element) {
|
|
144
159
|
if (breaks.length === 0)
|
|
145
160
|
return '';
|
|
161
|
+
const manual = breaks.filter((brk) => brk.man !== false).length;
|
|
146
162
|
const brks = breaks
|
|
147
|
-
.map((brk) => {
|
|
148
|
-
|
|
149
|
-
})
|
|
163
|
+
.map((brk) => `<brk${numAttr('id', brk.id)}${numAttr('min', brk.min)}${numAttr('max', brk.max)}` +
|
|
164
|
+
`${brk.man === false ? '' : ' man="1"'}/>`)
|
|
150
165
|
.join('');
|
|
151
|
-
return `<${element} count="${breaks.length}" manualBreakCount="${
|
|
166
|
+
return `<${element} count="${breaks.length}" manualBreakCount="${manual}">${brks}</${element}>`;
|
|
152
167
|
}
|
|
153
168
|
export function parseSheetProtection(attrs) {
|
|
154
|
-
if (
|
|
169
|
+
if (!boolStrict(attrs.sheet))
|
|
155
170
|
return undefined;
|
|
156
171
|
const flags = {};
|
|
157
172
|
for (const { key } of SHEET_PROTECTION_FLAGS) {
|
|
@@ -171,9 +186,14 @@ export function parseSheetProtection(attrs) {
|
|
|
171
186
|
saltValue,
|
|
172
187
|
spinCount: spin,
|
|
173
188
|
};
|
|
174
|
-
return { flags, credential };
|
|
189
|
+
return { flags, credential, ...legacyHash(attrs.password) };
|
|
175
190
|
}
|
|
176
|
-
return { flags };
|
|
191
|
+
return { flags, ...legacyHash(attrs.password) };
|
|
192
|
+
}
|
|
193
|
+
function legacyHash(password) {
|
|
194
|
+
return password !== undefined && isLegacyPasswordHash(password)
|
|
195
|
+
? { legacyPasswordHash: password }
|
|
196
|
+
: {};
|
|
177
197
|
}
|
|
178
198
|
export class PageBreakAccumulator {
|
|
179
199
|
#target = null;
|
|
@@ -189,12 +209,16 @@ export class PageBreakAccumulator {
|
|
|
189
209
|
const id = numInteger(attrs.id, 1);
|
|
190
210
|
if (id === undefined)
|
|
191
211
|
return;
|
|
192
|
-
const brk = {
|
|
212
|
+
const brk = {
|
|
213
|
+
id,
|
|
214
|
+
man: boolStrict(attrs.man),
|
|
215
|
+
};
|
|
216
|
+
const min = numInteger(attrs.min, 0);
|
|
217
|
+
if (min !== undefined)
|
|
218
|
+
brk.min = min;
|
|
193
219
|
const max = numInteger(attrs.max, 0);
|
|
194
220
|
if (max !== undefined)
|
|
195
221
|
brk.max = max;
|
|
196
|
-
if (boolStrict(attrs.man))
|
|
197
|
-
brk.man = true;
|
|
198
222
|
this.#target.push(brk);
|
|
199
223
|
}
|
|
200
224
|
}
|
|
@@ -208,13 +232,14 @@ export function applySheetProperties(local, attrs, sheet) {
|
|
|
208
232
|
sheet.tabColor = parseColor(attrs);
|
|
209
233
|
break;
|
|
210
234
|
case 'outlinePr':
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
235
|
+
for (const flag of ['summaryBelow', 'summaryRight']) {
|
|
236
|
+
const value = boolTristate(attrs[flag]);
|
|
237
|
+
if (value !== undefined)
|
|
238
|
+
sheet.outline[flag] = value;
|
|
239
|
+
}
|
|
215
240
|
break;
|
|
216
241
|
case 'sheetView':
|
|
217
|
-
if (attrs.showGridLines
|
|
242
|
+
if (boolTristate(attrs.showGridLines) === false) {
|
|
218
243
|
sheet.view.showGridLines = false;
|
|
219
244
|
}
|
|
220
245
|
break;
|
|
@@ -223,17 +248,18 @@ export function applySheetProperties(local, attrs, sheet) {
|
|
|
223
248
|
sheet.view.state = 'frozen';
|
|
224
249
|
const xSplit = numInteger(attrs.xSplit, 0);
|
|
225
250
|
const ySplit = numInteger(attrs.ySplit, 0);
|
|
226
|
-
if (xSplit !== undefined)
|
|
251
|
+
if (xSplit !== undefined && xSplit < MAX_COLUMN)
|
|
227
252
|
sheet.view.xSplit = xSplit;
|
|
228
|
-
if (ySplit !== undefined)
|
|
253
|
+
if (ySplit !== undefined && ySplit < MAX_ROW)
|
|
229
254
|
sheet.view.ySplit = ySplit;
|
|
230
255
|
if (attrs.topLeftCell !== undefined)
|
|
231
256
|
sheet.view.topLeftCell = attrs.topLeftCell;
|
|
232
257
|
}
|
|
233
258
|
break;
|
|
234
259
|
case 'pageSetUpPr':
|
|
235
|
-
if (attrs.fitToPage !== undefined)
|
|
236
|
-
sheet.pageSetup.fitToPage =
|
|
260
|
+
if (boolTristate(attrs.fitToPage) !== undefined) {
|
|
261
|
+
sheet.pageSetup.fitToPage = boolStrict(attrs.fitToPage);
|
|
262
|
+
}
|
|
237
263
|
break;
|
|
238
264
|
case 'printOptions':
|
|
239
265
|
applyPrintOptions(sheet.printOptions, attrs);
|
|
@@ -263,20 +289,20 @@ function applyMargins(margins, attrs) {
|
|
|
263
289
|
function applyPageSetup(pageSetup, attrs) {
|
|
264
290
|
for (const facet of PAGE_SETUP_FACETS) {
|
|
265
291
|
const raw = attrs[facet.key];
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
292
|
+
if (facet.kind === 'count') {
|
|
293
|
+
const value = numInteger(raw, 0);
|
|
294
|
+
if (value !== undefined)
|
|
295
|
+
pageSetup[facet.key] = value;
|
|
296
|
+
}
|
|
297
|
+
else if (raw === undefined) {
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
else if (facet.key === 'pageOrder') {
|
|
301
|
+
if (facet.isValid(raw))
|
|
302
|
+
pageSetup.pageOrder = raw;
|
|
303
|
+
}
|
|
304
|
+
else if (facet.isValid(raw)) {
|
|
305
|
+
pageSetup.orientation = raw;
|
|
277
306
|
}
|
|
278
307
|
}
|
|
279
308
|
}
|
|
280
|
-
function assignPageSetupToken(pageSetup, key, raw) {
|
|
281
|
-
pageSetup[key] = raw;
|
|
282
|
-
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A package part's bytes in Transitional: an XML part declaring a Strict namespace has its
|
|
3
|
+
* declarations and its percentages translated, and any other part is handed back as the same bytes.
|
|
4
|
+
* Only the opening tags that change are re-rendered, so everything else in the part rides through byte
|
|
5
|
+
* for byte. A part the scanner cannot read is left as it came, as it would have been carried.
|
|
6
|
+
*/
|
|
7
|
+
export declare function transitionalPart(bytes: Uint8Array, contentType: string): Uint8Array;
|