ooxml.js 2.5.2 → 2.6.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 +1 -1
- package/dist/index.cjs +22 -0
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/typed/docx/numbering.cjs +86 -0
- package/dist/typed/docx/numbering.d.cts +23 -0
- package/dist/typed/docx/numbering.d.ts +23 -0
- package/dist/typed/docx/numbering.js +83 -0
- package/dist/typed/docx/read.cjs +115 -15
- package/dist/typed/docx/read.d.cts +8 -0
- package/dist/typed/docx/read.d.ts +8 -0
- package/dist/typed/docx/read.js +117 -17
- package/dist/typed/docx/styles.cjs +26 -2
- package/dist/typed/docx/styles.js +26 -2
- package/dist/typed/pptx/read.cjs +5 -20
- package/dist/typed/pptx/read.js +5 -20
- package/dist/typed/shared/drawingml.cjs +112 -5
- package/dist/typed/shared/drawingml.d.cts +19 -2
- package/dist/typed/shared/drawingml.d.ts +19 -2
- package/dist/typed/shared/drawingml.js +111 -6
- package/dist/typed/shared/units.cjs +10 -0
- package/dist/typed/shared/units.d.cts +4 -1
- package/dist/typed/shared/units.d.ts +4 -1
- package/dist/typed/shared/units.js +8 -1
- package/dist/typed/xlsx/build.cjs +83 -55
- package/dist/typed/xlsx/build.js +83 -55
- package/dist/typed/xlsx/content.cjs +85 -15
- package/dist/typed/xlsx/content.js +85 -15
- package/dist/typed/xlsx/number-format.cjs +324 -0
- package/dist/typed/xlsx/number-format.d.cts +52 -0
- package/dist/typed/xlsx/number-format.d.ts +52 -0
- package/dist/typed/xlsx/number-format.js +312 -0
- package/dist/typed/xlsx/serial.cjs +109 -0
- package/dist/typed/xlsx/serial.d.cts +11 -0
- package/dist/typed/xlsx/serial.d.ts +11 -0
- package/dist/typed/xlsx/serial.js +102 -0
- package/dist/typed/xlsx/styles.cjs +73 -0
- package/dist/typed/xlsx/styles.d.cts +21 -0
- package/dist/typed/xlsx/styles.d.ts +21 -0
- package/dist/typed/xlsx/styles.js +69 -0
- package/package.json +1 -1
package/dist/typed/xlsx/build.js
CHANGED
|
@@ -4,8 +4,11 @@ import "../shared/units.js";
|
|
|
4
4
|
import { SharedStringTable } from "./shared-strings.js";
|
|
5
5
|
import { cellReference, rangeReference } from "./a1.js";
|
|
6
6
|
import { XLNM_PRINT_AREA, XLNM_PRINT_TITLES, buildPrintAreaValue, buildPrintTitlesValue } from "./defined-names.js";
|
|
7
|
+
import { BOOLEAN_NUMBER_FORMAT, DATE_NUMBER_FORMAT, DATE_TIME_NUMBER_FORMAT, PERCENTAGE_NUMBER_FORMAT, TIME_NUMBER_FORMAT, currencyNumberFormat } from "./number-format.js";
|
|
7
8
|
import { pageSizeToPaperSizeCode, ptToUniversalMeasure, writeXmlBool } from "./util.js";
|
|
8
9
|
import { DEFAULT_HEADER_FOOTER_MARGIN_PT } from "./print-settings.js";
|
|
10
|
+
import { isoDateTimeToSerial, isoDateToSerial, isoTimeToSerial } from "./serial.js";
|
|
11
|
+
import { CellFormatTable } from "./styles.js";
|
|
9
12
|
import { ptToColumnWidthChars } from "./units.js";
|
|
10
13
|
//#region src/typed/xlsx/build.ts
|
|
11
14
|
const SML_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
|
|
@@ -179,36 +182,46 @@ function buildSharedStringsPart(sharedStrings) {
|
|
|
179
182
|
uniqueCount: String(entries.length)
|
|
180
183
|
}, siElements));
|
|
181
184
|
}
|
|
182
|
-
function buildStylesPart() {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
el("
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
185
|
+
function buildStylesPart(cellFormats) {
|
|
186
|
+
const children = [];
|
|
187
|
+
const declarations = cellFormats.declarations();
|
|
188
|
+
if (declarations.length > 0) {
|
|
189
|
+
const numFmtElements = declarations.map((declaration) => el("numFmt", {
|
|
190
|
+
numFmtId: String(declaration.id),
|
|
191
|
+
formatCode: encodeXmlText(declaration.code)
|
|
192
|
+
}));
|
|
193
|
+
children.push(el("numFmts", { count: String(numFmtElements.length) }, numFmtElements));
|
|
194
|
+
}
|
|
195
|
+
children.push(el("fonts", { count: "1" }, [el("font", {}, [el("sz", { val: "11" }), el("name", { val: "Calibri" })])]), el("fills", { count: "2" }, [el("fill", {}, [el("patternFill", { patternType: "none" })]), el("fill", {}, [el("patternFill", { patternType: "gray125" })])]), el("borders", { count: "1" }, [el("border", {}, [
|
|
196
|
+
el("left"),
|
|
197
|
+
el("right"),
|
|
198
|
+
el("top"),
|
|
199
|
+
el("bottom"),
|
|
200
|
+
el("diagonal")
|
|
201
|
+
])]), el("cellStyleXfs", { count: "1" }, [el("xf", {
|
|
202
|
+
numFmtId: "0",
|
|
203
|
+
fontId: "0",
|
|
204
|
+
fillId: "0",
|
|
205
|
+
borderId: "0"
|
|
206
|
+
})]));
|
|
207
|
+
const xfElements = cellFormats.cellFormats().map((numFmtId) => {
|
|
208
|
+
const attrs = {
|
|
209
|
+
numFmtId: String(numFmtId),
|
|
201
210
|
fontId: "0",
|
|
202
211
|
fillId: "0",
|
|
203
212
|
borderId: "0",
|
|
204
213
|
xfId: "0"
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
214
|
+
};
|
|
215
|
+
if (numFmtId !== 0) attrs.applyNumberFormat = writeXmlBool(true);
|
|
216
|
+
return el("xf", attrs);
|
|
217
|
+
});
|
|
218
|
+
children.push(el("cellXfs", { count: String(xfElements.length) }, xfElements));
|
|
219
|
+
children.push(el("cellStyles", { count: "1" }, [el("cellStyle", {
|
|
220
|
+
name: "Normal",
|
|
221
|
+
xfId: "0",
|
|
222
|
+
builtinId: "0"
|
|
223
|
+
})]));
|
|
224
|
+
return xmlPart(el("styleSheet", { xmlns: SML_NS }, children));
|
|
212
225
|
}
|
|
213
226
|
function buildCorePropertiesPart(metadata) {
|
|
214
227
|
const children = [];
|
|
@@ -271,28 +284,24 @@ function buildColsElement(columns) {
|
|
|
271
284
|
}
|
|
272
285
|
function renderCellValue(value, isFormulaResult, sharedStrings) {
|
|
273
286
|
switch (value.kind) {
|
|
274
|
-
case "string":
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
case "percentage":
|
|
285
|
-
case "currency": return { content: String(value.value) };
|
|
287
|
+
case "string": return renderString(value.value, isFormulaResult, sharedStrings);
|
|
288
|
+
case "number": return { content: String(value.value) };
|
|
289
|
+
case "percentage": return {
|
|
290
|
+
content: String(value.value),
|
|
291
|
+
format: PERCENTAGE_NUMBER_FORMAT
|
|
292
|
+
};
|
|
293
|
+
case "currency": return {
|
|
294
|
+
content: String(value.value),
|
|
295
|
+
format: currencyNumberFormat(value.currency)
|
|
296
|
+
};
|
|
286
297
|
case "boolean": return {
|
|
287
298
|
type: "b",
|
|
288
|
-
content: value.value ? "1" : "0"
|
|
289
|
-
|
|
290
|
-
case "date":
|
|
291
|
-
case "time":
|
|
292
|
-
case "dateTime": return {
|
|
293
|
-
type: "d",
|
|
294
|
-
content: encodeXmlText(value.value)
|
|
299
|
+
content: value.value ? "1" : "0",
|
|
300
|
+
format: BOOLEAN_NUMBER_FORMAT
|
|
295
301
|
};
|
|
302
|
+
case "date": return renderTemporal(isoDateToSerial(value.value), value.value, DATE_NUMBER_FORMAT, isFormulaResult, sharedStrings);
|
|
303
|
+
case "time": return renderTemporal(isoTimeToSerial(value.value), value.value, TIME_NUMBER_FORMAT, isFormulaResult, sharedStrings);
|
|
304
|
+
case "dateTime": return renderTemporal(isoDateTimeToSerial(value.value), value.value, DATE_TIME_NUMBER_FORMAT, isFormulaResult, sharedStrings);
|
|
296
305
|
case "error": return {
|
|
297
306
|
type: "e",
|
|
298
307
|
content: encodeXmlText(value.value)
|
|
@@ -300,21 +309,39 @@ function renderCellValue(value, isFormulaResult, sharedStrings) {
|
|
|
300
309
|
case "empty": return;
|
|
301
310
|
}
|
|
302
311
|
}
|
|
303
|
-
function
|
|
312
|
+
function renderString(text, isFormulaResult, sharedStrings) {
|
|
313
|
+
if (isFormulaResult) return {
|
|
314
|
+
type: "str",
|
|
315
|
+
content: encodeXmlText(text)
|
|
316
|
+
};
|
|
317
|
+
return {
|
|
318
|
+
type: "s",
|
|
319
|
+
content: String(sharedStrings.intern(text))
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
function renderTemporal(serial, iso, format, isFormulaResult, sharedStrings) {
|
|
323
|
+
if (serial === void 0) return renderString(iso, isFormulaResult, sharedStrings);
|
|
324
|
+
return {
|
|
325
|
+
content: String(serial),
|
|
326
|
+
format
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function buildCellElement(cell, sharedStrings, cellFormats) {
|
|
330
|
+
const children = [];
|
|
331
|
+
const rendered = renderCellValue(cell.value, cell.formula !== void 0, sharedStrings);
|
|
332
|
+
const styleIndex = rendered?.format === void 0 ? 0 : cellFormats.intern(rendered.format);
|
|
304
333
|
const attrs = {
|
|
305
334
|
r: cellReference(cell.row, cell.column),
|
|
306
|
-
s:
|
|
335
|
+
s: String(styleIndex)
|
|
307
336
|
};
|
|
308
|
-
const children = [];
|
|
309
337
|
if (cell.formula !== void 0) children.push(el("f", {}, [txt(encodeXmlText(cell.formula))]));
|
|
310
|
-
const rendered = renderCellValue(cell.value, cell.formula !== void 0, sharedStrings);
|
|
311
338
|
if (rendered !== void 0) {
|
|
312
339
|
if (rendered.type !== void 0) attrs.t = rendered.type;
|
|
313
340
|
children.push(el("v", {}, [txt(rendered.content)]));
|
|
314
341
|
}
|
|
315
342
|
return el("c", attrs, children);
|
|
316
343
|
}
|
|
317
|
-
function buildSheetDataElement(sheet, sharedStrings) {
|
|
344
|
+
function buildSheetDataElement(sheet, sharedStrings, cellFormats) {
|
|
318
345
|
const cellsByRow = /* @__PURE__ */ new Map();
|
|
319
346
|
for (const cell of sheet.cells) {
|
|
320
347
|
const existing = cellsByRow.get(cell.row);
|
|
@@ -334,7 +361,7 @@ function buildSheetDataElement(sheet, sharedStrings) {
|
|
|
334
361
|
}
|
|
335
362
|
if (rowInfo.hidden === true) attrs.hidden = "true";
|
|
336
363
|
}
|
|
337
|
-
return el("row", attrs, cells.map((cell) => buildCellElement(cell, sharedStrings)));
|
|
364
|
+
return el("row", attrs, cells.map((cell) => buildCellElement(cell, sharedStrings, cellFormats)));
|
|
338
365
|
}));
|
|
339
366
|
}
|
|
340
367
|
function buildMergeCellsElement(cells) {
|
|
@@ -420,11 +447,11 @@ function buildBreaksElements(settings) {
|
|
|
420
447
|
}
|
|
421
448
|
return result;
|
|
422
449
|
}
|
|
423
|
-
function buildWorksheetPart(sheet, sharedStrings) {
|
|
450
|
+
function buildWorksheetPart(sheet, sharedStrings, cellFormats) {
|
|
424
451
|
const children = [buildSheetPrElement(sheet.printSettings), el("dimension", { ref: computeDimension(sheet) })];
|
|
425
452
|
const colsElement = buildColsElement(sheet.columns);
|
|
426
453
|
if (colsElement !== void 0) children.push(colsElement);
|
|
427
|
-
children.push(buildSheetDataElement(sheet, sharedStrings));
|
|
454
|
+
children.push(buildSheetDataElement(sheet, sharedStrings, cellFormats));
|
|
428
455
|
const mergeCellsElement = buildMergeCellsElement(sheet.cells);
|
|
429
456
|
if (mergeCellsElement !== void 0) children.push(mergeCellsElement);
|
|
430
457
|
children.push(buildPrintOptionsElement(sheet.printSettings), buildPageMarginsElement(sheet.printSettings), buildPageSetupElement(sheet.printSettings));
|
|
@@ -440,13 +467,14 @@ function buildXlsxPackage(document) {
|
|
|
440
467
|
if (document.kind !== "spreadsheet") throw new Error(`buildXlsxPackage: expected a ContentDocument of kind "spreadsheet", got "${document.kind}"`);
|
|
441
468
|
const sheets = document.sheets;
|
|
442
469
|
const sharedStrings = new SharedStringTable();
|
|
443
|
-
const
|
|
470
|
+
const cellFormats = new CellFormatTable();
|
|
471
|
+
const worksheetParts = sheets.map((sheet) => buildWorksheetPart(sheet, sharedStrings, cellFormats));
|
|
444
472
|
const parts = {
|
|
445
473
|
"[Content_Types].xml": buildContentTypesPart(sheets.length),
|
|
446
474
|
"_rels/.rels": buildPackageRelsPart(),
|
|
447
475
|
"xl/workbook.xml": buildWorkbookPart(sheets),
|
|
448
476
|
"xl/_rels/workbook.xml.rels": buildWorkbookRelsPart(sheets.length),
|
|
449
|
-
"xl/styles.xml": buildStylesPart(),
|
|
477
|
+
"xl/styles.xml": buildStylesPart(cellFormats),
|
|
450
478
|
"xl/sharedStrings.xml": buildSharedStringsPart(sharedStrings),
|
|
451
479
|
"docProps/core.xml": buildCorePropertiesPart(document.metadata),
|
|
452
480
|
"docProps/app.xml": buildAppPropertiesPart(document.metadata)
|
|
@@ -4,8 +4,11 @@ const require_typed_shared_metadata = require("../shared/metadata.cjs");
|
|
|
4
4
|
const require_typed_xlsx_shared_strings = require("./shared-strings.cjs");
|
|
5
5
|
const require_typed_xlsx_a1 = require("./a1.cjs");
|
|
6
6
|
const require_typed_xlsx_defined_names = require("./defined-names.cjs");
|
|
7
|
+
const require_typed_xlsx_number_format = require("./number-format.cjs");
|
|
7
8
|
const require_typed_xlsx_util = require("./util.cjs");
|
|
8
9
|
const require_typed_xlsx_print_settings = require("./print-settings.cjs");
|
|
10
|
+
const require_typed_xlsx_serial = require("./serial.cjs");
|
|
11
|
+
const require_typed_xlsx_styles = require("./styles.cjs");
|
|
9
12
|
const require_typed_xlsx_units = require("./units.cjs");
|
|
10
13
|
let document_schema_js = require("document-schema.js");
|
|
11
14
|
//#region src/typed/xlsx/content.ts
|
|
@@ -81,19 +84,88 @@ function readInlineOrSharedStringText(container) {
|
|
|
81
84
|
}
|
|
82
85
|
function deriveDisplayText(value) {
|
|
83
86
|
switch (value.kind) {
|
|
84
|
-
case "number":
|
|
87
|
+
case "number":
|
|
88
|
+
case "percentage":
|
|
89
|
+
case "currency": return String(value.value);
|
|
85
90
|
case "boolean": return value.value ? "TRUE" : "FALSE";
|
|
86
91
|
case "string":
|
|
87
92
|
case "error":
|
|
88
93
|
case "date":
|
|
89
94
|
case "time":
|
|
90
95
|
case "dateTime": return value.value;
|
|
91
|
-
case "percentage":
|
|
92
|
-
case "currency": return String(value.value);
|
|
93
96
|
case "empty": return "";
|
|
94
97
|
}
|
|
95
98
|
}
|
|
96
|
-
|
|
99
|
+
const DEFAULT_CELL_STYLE_INDEX = 0;
|
|
100
|
+
const PLAIN_NUMBER = { kind: "number" };
|
|
101
|
+
function readNumericFormatContext(pkg) {
|
|
102
|
+
return {
|
|
103
|
+
classes: require_typed_xlsx_styles.readCellFormatCodes(pkg).map((code) => code === void 0 ? PLAIN_NUMBER : require_typed_xlsx_number_format.classifyNumberFormat(code)),
|
|
104
|
+
date1904: require_typed_xlsx_serial.readDate1904(pkg)
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function numberFormatOf(cell, context) {
|
|
108
|
+
const raw = require_typed_util.attr(cell, "s");
|
|
109
|
+
const index = raw === void 0 ? DEFAULT_CELL_STYLE_INDEX : Number.parseInt(raw, 10);
|
|
110
|
+
return (Number.isInteger(index) ? context.classes[index] : void 0) ?? PLAIN_NUMBER;
|
|
111
|
+
}
|
|
112
|
+
function resolveNumericValue(num, cell, context) {
|
|
113
|
+
const format = numberFormatOf(cell, context);
|
|
114
|
+
switch (format.kind) {
|
|
115
|
+
case "percentage": return {
|
|
116
|
+
kind: "percentage",
|
|
117
|
+
value: num
|
|
118
|
+
};
|
|
119
|
+
case "currency": return format.code === void 0 ? {
|
|
120
|
+
kind: "currency",
|
|
121
|
+
value: num
|
|
122
|
+
} : {
|
|
123
|
+
kind: "currency",
|
|
124
|
+
value: num,
|
|
125
|
+
currency: format.code
|
|
126
|
+
};
|
|
127
|
+
case "date": {
|
|
128
|
+
const iso = require_typed_xlsx_serial.serialToIsoDate(num, context.date1904);
|
|
129
|
+
return iso === void 0 ? {
|
|
130
|
+
kind: "number",
|
|
131
|
+
value: num
|
|
132
|
+
} : {
|
|
133
|
+
kind: "date",
|
|
134
|
+
value: iso
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
case "time": {
|
|
138
|
+
const iso = require_typed_xlsx_serial.serialToIsoTime(num);
|
|
139
|
+
return iso === void 0 ? {
|
|
140
|
+
kind: "number",
|
|
141
|
+
value: num
|
|
142
|
+
} : {
|
|
143
|
+
kind: "time",
|
|
144
|
+
value: iso
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
case "dateTime": {
|
|
148
|
+
const iso = require_typed_xlsx_serial.serialToIsoDateTime(num, context.date1904);
|
|
149
|
+
return iso === void 0 ? {
|
|
150
|
+
kind: "number",
|
|
151
|
+
value: num
|
|
152
|
+
} : {
|
|
153
|
+
kind: "dateTime",
|
|
154
|
+
value: iso
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
case "elapsedTime": return {
|
|
158
|
+
kind: "number",
|
|
159
|
+
value: num
|
|
160
|
+
};
|
|
161
|
+
case "text":
|
|
162
|
+
case "number": return {
|
|
163
|
+
kind: "number",
|
|
164
|
+
value: num
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function readCellValue(cell, sharedStrings, numericFormats) {
|
|
97
169
|
const type = require_typed_util.attr(cell, "t");
|
|
98
170
|
if (type === "inlineStr") {
|
|
99
171
|
const is = require_typed_util.childrenWithTag(cell, "is")[0];
|
|
@@ -153,22 +225,19 @@ function readCellValue(cell, sharedStrings) {
|
|
|
153
225
|
};
|
|
154
226
|
const num = Number(raw);
|
|
155
227
|
if (Number.isNaN(num)) return;
|
|
156
|
-
const value =
|
|
157
|
-
kind: "number",
|
|
158
|
-
value: num
|
|
159
|
-
};
|
|
228
|
+
const value = resolveNumericValue(num, cell, numericFormats);
|
|
160
229
|
return {
|
|
161
230
|
value,
|
|
162
231
|
displayText: deriveDisplayText(value)
|
|
163
232
|
};
|
|
164
233
|
}
|
|
165
|
-
function readCell(cell, sharedStrings) {
|
|
234
|
+
function readCell(cell, sharedStrings, numericFormats) {
|
|
166
235
|
const reference = require_typed_util.attr(cell, "r");
|
|
167
236
|
const position = reference === void 0 ? void 0 : require_typed_xlsx_a1.parseCellReference(reference);
|
|
168
237
|
if (position === void 0) return;
|
|
169
238
|
const formulaEl = require_typed_util.childrenWithTag(cell, "f")[0];
|
|
170
239
|
const formula = formulaEl === void 0 ? void 0 : require_typed_util.textContent(formulaEl);
|
|
171
|
-
const resolved = readCellValue(cell, sharedStrings);
|
|
240
|
+
const resolved = readCellValue(cell, sharedStrings, numericFormats);
|
|
172
241
|
if (resolved === void 0) {
|
|
173
242
|
if (formula === void 0) return;
|
|
174
243
|
return {
|
|
@@ -205,18 +274,18 @@ function applyMergedRanges(worksheet, cells) {
|
|
|
205
274
|
if (rowSpan > 1) anchor.rowSpan = rowSpan;
|
|
206
275
|
}
|
|
207
276
|
}
|
|
208
|
-
function readCells(worksheet, sharedStrings) {
|
|
277
|
+
function readCells(worksheet, sharedStrings, numericFormats) {
|
|
209
278
|
const sheetData = require_typed_util.childrenWithTag(worksheet, "sheetData")[0];
|
|
210
279
|
if (sheetData === void 0) return [];
|
|
211
280
|
const cells = [];
|
|
212
281
|
for (const row of require_typed_util.childrenWithTag(sheetData, "row")) for (const cell of require_typed_util.childrenWithTag(row, "c")) {
|
|
213
|
-
const read = readCell(cell, sharedStrings);
|
|
282
|
+
const read = readCell(cell, sharedStrings, numericFormats);
|
|
214
283
|
if (read !== void 0) cells.push(read);
|
|
215
284
|
}
|
|
216
285
|
applyMergedRanges(worksheet, cells);
|
|
217
286
|
return cells;
|
|
218
287
|
}
|
|
219
|
-
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet) {
|
|
288
|
+
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, numericFormats) {
|
|
220
289
|
const worksheet = require_typed_util.rootElement(pkg.parts[entry.path]);
|
|
221
290
|
if (worksheet === void 0) return {
|
|
222
291
|
name: entry.name,
|
|
@@ -228,7 +297,7 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet) {
|
|
|
228
297
|
};
|
|
229
298
|
return {
|
|
230
299
|
name: entry.name,
|
|
231
|
-
cells: readCells(worksheet, sharedStrings),
|
|
300
|
+
cells: readCells(worksheet, sharedStrings, numericFormats),
|
|
232
301
|
columns: readColumns(worksheet),
|
|
233
302
|
rows: readRows(worksheet),
|
|
234
303
|
images: [],
|
|
@@ -246,7 +315,8 @@ function fallbackEmptyWorksheet() {
|
|
|
246
315
|
function readXlsxContent(pkg) {
|
|
247
316
|
const sharedStrings = require_typed_xlsx_shared_strings.loadSharedStrings(pkg);
|
|
248
317
|
const definedNamesBySheet = require_typed_xlsx_defined_names.readDefinedNamesBySheet(pkg);
|
|
249
|
-
const
|
|
318
|
+
const numericFormats = readNumericFormatContext(pkg);
|
|
319
|
+
const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, numericFormats));
|
|
250
320
|
return {
|
|
251
321
|
kind: "spreadsheet",
|
|
252
322
|
formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
|
|
@@ -3,8 +3,11 @@ import { readCoreProperties } from "../shared/metadata.js";
|
|
|
3
3
|
import { loadSharedStrings } from "./shared-strings.js";
|
|
4
4
|
import { parseCellReference, parseRangeReference } from "./a1.js";
|
|
5
5
|
import { readDefinedNamesBySheet } from "./defined-names.js";
|
|
6
|
+
import { classifyNumberFormat } from "./number-format.js";
|
|
6
7
|
import { readXmlBool } from "./util.js";
|
|
7
8
|
import { readPrintSettings } from "./print-settings.js";
|
|
9
|
+
import { readDate1904, serialToIsoDate, serialToIsoDateTime, serialToIsoTime } from "./serial.js";
|
|
10
|
+
import { readCellFormatCodes } from "./styles.js";
|
|
8
11
|
import { columnWidthCharsToPt } from "./units.js";
|
|
9
12
|
import { CONTENT_FORMAT_VERSION } from "document-schema.js";
|
|
10
13
|
//#region src/typed/xlsx/content.ts
|
|
@@ -80,19 +83,88 @@ function readInlineOrSharedStringText(container) {
|
|
|
80
83
|
}
|
|
81
84
|
function deriveDisplayText(value) {
|
|
82
85
|
switch (value.kind) {
|
|
83
|
-
case "number":
|
|
86
|
+
case "number":
|
|
87
|
+
case "percentage":
|
|
88
|
+
case "currency": return String(value.value);
|
|
84
89
|
case "boolean": return value.value ? "TRUE" : "FALSE";
|
|
85
90
|
case "string":
|
|
86
91
|
case "error":
|
|
87
92
|
case "date":
|
|
88
93
|
case "time":
|
|
89
94
|
case "dateTime": return value.value;
|
|
90
|
-
case "percentage":
|
|
91
|
-
case "currency": return String(value.value);
|
|
92
95
|
case "empty": return "";
|
|
93
96
|
}
|
|
94
97
|
}
|
|
95
|
-
|
|
98
|
+
const DEFAULT_CELL_STYLE_INDEX = 0;
|
|
99
|
+
const PLAIN_NUMBER = { kind: "number" };
|
|
100
|
+
function readNumericFormatContext(pkg) {
|
|
101
|
+
return {
|
|
102
|
+
classes: readCellFormatCodes(pkg).map((code) => code === void 0 ? PLAIN_NUMBER : classifyNumberFormat(code)),
|
|
103
|
+
date1904: readDate1904(pkg)
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function numberFormatOf(cell, context) {
|
|
107
|
+
const raw = attr(cell, "s");
|
|
108
|
+
const index = raw === void 0 ? DEFAULT_CELL_STYLE_INDEX : Number.parseInt(raw, 10);
|
|
109
|
+
return (Number.isInteger(index) ? context.classes[index] : void 0) ?? PLAIN_NUMBER;
|
|
110
|
+
}
|
|
111
|
+
function resolveNumericValue(num, cell, context) {
|
|
112
|
+
const format = numberFormatOf(cell, context);
|
|
113
|
+
switch (format.kind) {
|
|
114
|
+
case "percentage": return {
|
|
115
|
+
kind: "percentage",
|
|
116
|
+
value: num
|
|
117
|
+
};
|
|
118
|
+
case "currency": return format.code === void 0 ? {
|
|
119
|
+
kind: "currency",
|
|
120
|
+
value: num
|
|
121
|
+
} : {
|
|
122
|
+
kind: "currency",
|
|
123
|
+
value: num,
|
|
124
|
+
currency: format.code
|
|
125
|
+
};
|
|
126
|
+
case "date": {
|
|
127
|
+
const iso = serialToIsoDate(num, context.date1904);
|
|
128
|
+
return iso === void 0 ? {
|
|
129
|
+
kind: "number",
|
|
130
|
+
value: num
|
|
131
|
+
} : {
|
|
132
|
+
kind: "date",
|
|
133
|
+
value: iso
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
case "time": {
|
|
137
|
+
const iso = serialToIsoTime(num);
|
|
138
|
+
return iso === void 0 ? {
|
|
139
|
+
kind: "number",
|
|
140
|
+
value: num
|
|
141
|
+
} : {
|
|
142
|
+
kind: "time",
|
|
143
|
+
value: iso
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
case "dateTime": {
|
|
147
|
+
const iso = serialToIsoDateTime(num, context.date1904);
|
|
148
|
+
return iso === void 0 ? {
|
|
149
|
+
kind: "number",
|
|
150
|
+
value: num
|
|
151
|
+
} : {
|
|
152
|
+
kind: "dateTime",
|
|
153
|
+
value: iso
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
case "elapsedTime": return {
|
|
157
|
+
kind: "number",
|
|
158
|
+
value: num
|
|
159
|
+
};
|
|
160
|
+
case "text":
|
|
161
|
+
case "number": return {
|
|
162
|
+
kind: "number",
|
|
163
|
+
value: num
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function readCellValue(cell, sharedStrings, numericFormats) {
|
|
96
168
|
const type = attr(cell, "t");
|
|
97
169
|
if (type === "inlineStr") {
|
|
98
170
|
const is = childrenWithTag(cell, "is")[0];
|
|
@@ -152,22 +224,19 @@ function readCellValue(cell, sharedStrings) {
|
|
|
152
224
|
};
|
|
153
225
|
const num = Number(raw);
|
|
154
226
|
if (Number.isNaN(num)) return;
|
|
155
|
-
const value =
|
|
156
|
-
kind: "number",
|
|
157
|
-
value: num
|
|
158
|
-
};
|
|
227
|
+
const value = resolveNumericValue(num, cell, numericFormats);
|
|
159
228
|
return {
|
|
160
229
|
value,
|
|
161
230
|
displayText: deriveDisplayText(value)
|
|
162
231
|
};
|
|
163
232
|
}
|
|
164
|
-
function readCell(cell, sharedStrings) {
|
|
233
|
+
function readCell(cell, sharedStrings, numericFormats) {
|
|
165
234
|
const reference = attr(cell, "r");
|
|
166
235
|
const position = reference === void 0 ? void 0 : parseCellReference(reference);
|
|
167
236
|
if (position === void 0) return;
|
|
168
237
|
const formulaEl = childrenWithTag(cell, "f")[0];
|
|
169
238
|
const formula = formulaEl === void 0 ? void 0 : textContent(formulaEl);
|
|
170
|
-
const resolved = readCellValue(cell, sharedStrings);
|
|
239
|
+
const resolved = readCellValue(cell, sharedStrings, numericFormats);
|
|
171
240
|
if (resolved === void 0) {
|
|
172
241
|
if (formula === void 0) return;
|
|
173
242
|
return {
|
|
@@ -204,18 +273,18 @@ function applyMergedRanges(worksheet, cells) {
|
|
|
204
273
|
if (rowSpan > 1) anchor.rowSpan = rowSpan;
|
|
205
274
|
}
|
|
206
275
|
}
|
|
207
|
-
function readCells(worksheet, sharedStrings) {
|
|
276
|
+
function readCells(worksheet, sharedStrings, numericFormats) {
|
|
208
277
|
const sheetData = childrenWithTag(worksheet, "sheetData")[0];
|
|
209
278
|
if (sheetData === void 0) return [];
|
|
210
279
|
const cells = [];
|
|
211
280
|
for (const row of childrenWithTag(sheetData, "row")) for (const cell of childrenWithTag(row, "c")) {
|
|
212
|
-
const read = readCell(cell, sharedStrings);
|
|
281
|
+
const read = readCell(cell, sharedStrings, numericFormats);
|
|
213
282
|
if (read !== void 0) cells.push(read);
|
|
214
283
|
}
|
|
215
284
|
applyMergedRanges(worksheet, cells);
|
|
216
285
|
return cells;
|
|
217
286
|
}
|
|
218
|
-
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet) {
|
|
287
|
+
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, numericFormats) {
|
|
219
288
|
const worksheet = rootElement(pkg.parts[entry.path]);
|
|
220
289
|
if (worksheet === void 0) return {
|
|
221
290
|
name: entry.name,
|
|
@@ -227,7 +296,7 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet) {
|
|
|
227
296
|
};
|
|
228
297
|
return {
|
|
229
298
|
name: entry.name,
|
|
230
|
-
cells: readCells(worksheet, sharedStrings),
|
|
299
|
+
cells: readCells(worksheet, sharedStrings, numericFormats),
|
|
231
300
|
columns: readColumns(worksheet),
|
|
232
301
|
rows: readRows(worksheet),
|
|
233
302
|
images: [],
|
|
@@ -245,7 +314,8 @@ function fallbackEmptyWorksheet() {
|
|
|
245
314
|
function readXlsxContent(pkg) {
|
|
246
315
|
const sharedStrings = loadSharedStrings(pkg);
|
|
247
316
|
const definedNamesBySheet = readDefinedNamesBySheet(pkg);
|
|
248
|
-
const
|
|
317
|
+
const numericFormats = readNumericFormatContext(pkg);
|
|
318
|
+
const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, numericFormats));
|
|
249
319
|
return {
|
|
250
320
|
kind: "spreadsheet",
|
|
251
321
|
formatVersion: CONTENT_FORMAT_VERSION,
|