ooxml.js 2.5.1 → 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.d.cts +1 -0
- package/dist/typed/pptx/read.d.ts +1 -0
- 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 +93 -60
- package/dist/typed/xlsx/build.js +93 -60
- package/dist/typed/xlsx/content.cjs +93 -22
- package/dist/typed/xlsx/content.js +93 -22
- 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/print-settings.cjs +1 -1
- package/dist/typed/xlsx/print-settings.js +1 -1
- 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 +2 -2
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 = [];
|
|
@@ -259,37 +272,36 @@ function buildColsElement(columns) {
|
|
|
259
272
|
return el("cols", {}, columns.map((column) => {
|
|
260
273
|
const attrs = {
|
|
261
274
|
min: String(column.index + 1),
|
|
262
|
-
max: String(column.index + 1)
|
|
263
|
-
width: ptToColumnWidthChars(column.widthPt).toFixed(2),
|
|
264
|
-
customWidth: "true"
|
|
275
|
+
max: String(column.index + 1)
|
|
265
276
|
};
|
|
277
|
+
if (column.widthPt !== void 0) {
|
|
278
|
+
attrs.width = ptToColumnWidthChars(column.widthPt).toFixed(2);
|
|
279
|
+
attrs.customWidth = "true";
|
|
280
|
+
}
|
|
266
281
|
if (column.hidden === true) attrs.hidden = "true";
|
|
267
282
|
return el("col", attrs);
|
|
268
283
|
}));
|
|
269
284
|
}
|
|
270
285
|
function renderCellValue(value, isFormulaResult, sharedStrings) {
|
|
271
286
|
switch (value.kind) {
|
|
272
|
-
case "string":
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
case "percentage":
|
|
283
|
-
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
|
+
};
|
|
284
297
|
case "boolean": return {
|
|
285
298
|
type: "b",
|
|
286
|
-
content: value.value ? "1" : "0"
|
|
287
|
-
|
|
288
|
-
case "date":
|
|
289
|
-
case "time": return {
|
|
290
|
-
type: "d",
|
|
291
|
-
content: encodeXmlText(value.value)
|
|
299
|
+
content: value.value ? "1" : "0",
|
|
300
|
+
format: BOOLEAN_NUMBER_FORMAT
|
|
292
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);
|
|
293
305
|
case "error": return {
|
|
294
306
|
type: "e",
|
|
295
307
|
content: encodeXmlText(value.value)
|
|
@@ -297,21 +309,39 @@ function renderCellValue(value, isFormulaResult, sharedStrings) {
|
|
|
297
309
|
case "empty": return;
|
|
298
310
|
}
|
|
299
311
|
}
|
|
300
|
-
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);
|
|
301
333
|
const attrs = {
|
|
302
334
|
r: cellReference(cell.row, cell.column),
|
|
303
|
-
s:
|
|
335
|
+
s: String(styleIndex)
|
|
304
336
|
};
|
|
305
|
-
const children = [];
|
|
306
337
|
if (cell.formula !== void 0) children.push(el("f", {}, [txt(encodeXmlText(cell.formula))]));
|
|
307
|
-
const rendered = renderCellValue(cell.value, cell.formula !== void 0, sharedStrings);
|
|
308
338
|
if (rendered !== void 0) {
|
|
309
339
|
if (rendered.type !== void 0) attrs.t = rendered.type;
|
|
310
340
|
children.push(el("v", {}, [txt(rendered.content)]));
|
|
311
341
|
}
|
|
312
342
|
return el("c", attrs, children);
|
|
313
343
|
}
|
|
314
|
-
function buildSheetDataElement(sheet, sharedStrings) {
|
|
344
|
+
function buildSheetDataElement(sheet, sharedStrings, cellFormats) {
|
|
315
345
|
const cellsByRow = /* @__PURE__ */ new Map();
|
|
316
346
|
for (const cell of sheet.cells) {
|
|
317
347
|
const existing = cellsByRow.get(cell.row);
|
|
@@ -325,11 +355,13 @@ function buildSheetDataElement(sheet, sharedStrings) {
|
|
|
325
355
|
const rowInfo = rowInfoByIndex.get(rowIndex);
|
|
326
356
|
const attrs = { r: String(rowIndex + 1) };
|
|
327
357
|
if (rowInfo !== void 0) {
|
|
328
|
-
|
|
329
|
-
|
|
358
|
+
if (rowInfo.heightPt !== void 0) {
|
|
359
|
+
attrs.ht = String(rowInfo.heightPt);
|
|
360
|
+
attrs.customHeight = "true";
|
|
361
|
+
}
|
|
330
362
|
if (rowInfo.hidden === true) attrs.hidden = "true";
|
|
331
363
|
}
|
|
332
|
-
return el("row", attrs, cells.map((cell) => buildCellElement(cell, sharedStrings)));
|
|
364
|
+
return el("row", attrs, cells.map((cell) => buildCellElement(cell, sharedStrings, cellFormats)));
|
|
333
365
|
}));
|
|
334
366
|
}
|
|
335
367
|
function buildMergeCellsElement(cells) {
|
|
@@ -378,7 +410,7 @@ function buildPageSetupElement(settings) {
|
|
|
378
410
|
attrs.paperWidth = ptToUniversalMeasure(settings.pageSize.widthPt);
|
|
379
411
|
attrs.paperHeight = ptToUniversalMeasure(settings.pageSize.heightPt);
|
|
380
412
|
}
|
|
381
|
-
attrs.scale = String(settings.
|
|
413
|
+
attrs.scale = String(settings.scalePercent ?? 100);
|
|
382
414
|
attrs.fitToWidth = String(settings.fitToPages?.width ?? 1);
|
|
383
415
|
attrs.fitToHeight = String(settings.fitToPages?.height ?? 1);
|
|
384
416
|
attrs.pageOrder = settings.pageOrder;
|
|
@@ -415,11 +447,11 @@ function buildBreaksElements(settings) {
|
|
|
415
447
|
}
|
|
416
448
|
return result;
|
|
417
449
|
}
|
|
418
|
-
function buildWorksheetPart(sheet, sharedStrings) {
|
|
450
|
+
function buildWorksheetPart(sheet, sharedStrings, cellFormats) {
|
|
419
451
|
const children = [buildSheetPrElement(sheet.printSettings), el("dimension", { ref: computeDimension(sheet) })];
|
|
420
452
|
const colsElement = buildColsElement(sheet.columns);
|
|
421
453
|
if (colsElement !== void 0) children.push(colsElement);
|
|
422
|
-
children.push(buildSheetDataElement(sheet, sharedStrings));
|
|
454
|
+
children.push(buildSheetDataElement(sheet, sharedStrings, cellFormats));
|
|
423
455
|
const mergeCellsElement = buildMergeCellsElement(sheet.cells);
|
|
424
456
|
if (mergeCellsElement !== void 0) children.push(mergeCellsElement);
|
|
425
457
|
children.push(buildPrintOptionsElement(sheet.printSettings), buildPageMarginsElement(sheet.printSettings), buildPageSetupElement(sheet.printSettings));
|
|
@@ -435,13 +467,14 @@ function buildXlsxPackage(document) {
|
|
|
435
467
|
if (document.kind !== "spreadsheet") throw new Error(`buildXlsxPackage: expected a ContentDocument of kind "spreadsheet", got "${document.kind}"`);
|
|
436
468
|
const sheets = document.sheets;
|
|
437
469
|
const sharedStrings = new SharedStringTable();
|
|
438
|
-
const
|
|
470
|
+
const cellFormats = new CellFormatTable();
|
|
471
|
+
const worksheetParts = sheets.map((sheet) => buildWorksheetPart(sheet, sharedStrings, cellFormats));
|
|
439
472
|
const parts = {
|
|
440
473
|
"[Content_Types].xml": buildContentTypesPart(sheets.length),
|
|
441
474
|
"_rels/.rels": buildPackageRelsPart(),
|
|
442
475
|
"xl/workbook.xml": buildWorkbookPart(sheets),
|
|
443
476
|
"xl/_rels/workbook.xml.rels": buildWorkbookRelsPart(sheets.length),
|
|
444
|
-
"xl/styles.xml": buildStylesPart(),
|
|
477
|
+
"xl/styles.xml": buildStylesPart(cellFormats),
|
|
445
478
|
"xl/sharedStrings.xml": buildSharedStringsPart(sharedStrings),
|
|
446
479
|
"docProps/core.xml": buildCorePropertiesPart(document.metadata),
|
|
447
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
|
|
@@ -43,12 +46,12 @@ function readColumns(worksheet) {
|
|
|
43
46
|
const minRaw = require_typed_util.attr(col, "min");
|
|
44
47
|
const min = minRaw === void 0 ? void 0 : Number.parseInt(minRaw, 10);
|
|
45
48
|
if (min === void 0 || !Number.isInteger(min) || min < 1) continue;
|
|
49
|
+
const column = { index: min - 1 };
|
|
46
50
|
const widthRaw = require_typed_util.attr(col, "width");
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
};
|
|
51
|
+
if (widthRaw !== void 0) {
|
|
52
|
+
const widthPt = require_typed_xlsx_units.columnWidthCharsToPt(Number(widthRaw));
|
|
53
|
+
if (Number.isFinite(widthPt)) column.widthPt = widthPt;
|
|
54
|
+
}
|
|
52
55
|
if (require_typed_xlsx_util.readXmlBool(require_typed_util.attr(col, "hidden"))) column.hidden = true;
|
|
53
56
|
columns.push(column);
|
|
54
57
|
}
|
|
@@ -81,18 +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
|
-
case "time":
|
|
90
|
-
case "
|
|
91
|
-
case "currency": return String(value.value);
|
|
94
|
+
case "time":
|
|
95
|
+
case "dateTime": return value.value;
|
|
92
96
|
case "empty": return "";
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
|
-
|
|
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) {
|
|
96
169
|
const type = require_typed_util.attr(cell, "t");
|
|
97
170
|
if (type === "inlineStr") {
|
|
98
171
|
const is = require_typed_util.childrenWithTag(cell, "is")[0];
|
|
@@ -145,29 +218,26 @@ function readCellValue(cell, sharedStrings) {
|
|
|
145
218
|
};
|
|
146
219
|
if (type === "d") return {
|
|
147
220
|
value: {
|
|
148
|
-
kind: "
|
|
221
|
+
kind: "dateTime",
|
|
149
222
|
value: raw
|
|
150
223
|
},
|
|
151
224
|
displayText: raw
|
|
152
225
|
};
|
|
153
226
|
const num = Number(raw);
|
|
154
227
|
if (Number.isNaN(num)) return;
|
|
155
|
-
const value =
|
|
156
|
-
kind: "number",
|
|
157
|
-
value: num
|
|
158
|
-
};
|
|
228
|
+
const value = resolveNumericValue(num, cell, numericFormats);
|
|
159
229
|
return {
|
|
160
230
|
value,
|
|
161
231
|
displayText: deriveDisplayText(value)
|
|
162
232
|
};
|
|
163
233
|
}
|
|
164
|
-
function readCell(cell, sharedStrings) {
|
|
234
|
+
function readCell(cell, sharedStrings, numericFormats) {
|
|
165
235
|
const reference = require_typed_util.attr(cell, "r");
|
|
166
236
|
const position = reference === void 0 ? void 0 : require_typed_xlsx_a1.parseCellReference(reference);
|
|
167
237
|
if (position === void 0) return;
|
|
168
238
|
const formulaEl = require_typed_util.childrenWithTag(cell, "f")[0];
|
|
169
239
|
const formula = formulaEl === void 0 ? void 0 : require_typed_util.textContent(formulaEl);
|
|
170
|
-
const resolved = readCellValue(cell, sharedStrings);
|
|
240
|
+
const resolved = readCellValue(cell, sharedStrings, numericFormats);
|
|
171
241
|
if (resolved === void 0) {
|
|
172
242
|
if (formula === void 0) return;
|
|
173
243
|
return {
|
|
@@ -204,18 +274,18 @@ function applyMergedRanges(worksheet, cells) {
|
|
|
204
274
|
if (rowSpan > 1) anchor.rowSpan = rowSpan;
|
|
205
275
|
}
|
|
206
276
|
}
|
|
207
|
-
function readCells(worksheet, sharedStrings) {
|
|
277
|
+
function readCells(worksheet, sharedStrings, numericFormats) {
|
|
208
278
|
const sheetData = require_typed_util.childrenWithTag(worksheet, "sheetData")[0];
|
|
209
279
|
if (sheetData === void 0) return [];
|
|
210
280
|
const cells = [];
|
|
211
281
|
for (const row of require_typed_util.childrenWithTag(sheetData, "row")) for (const cell of require_typed_util.childrenWithTag(row, "c")) {
|
|
212
|
-
const read = readCell(cell, sharedStrings);
|
|
282
|
+
const read = readCell(cell, sharedStrings, numericFormats);
|
|
213
283
|
if (read !== void 0) cells.push(read);
|
|
214
284
|
}
|
|
215
285
|
applyMergedRanges(worksheet, cells);
|
|
216
286
|
return cells;
|
|
217
287
|
}
|
|
218
|
-
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet) {
|
|
288
|
+
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, numericFormats) {
|
|
219
289
|
const worksheet = require_typed_util.rootElement(pkg.parts[entry.path]);
|
|
220
290
|
if (worksheet === void 0) return {
|
|
221
291
|
name: entry.name,
|
|
@@ -227,7 +297,7 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet) {
|
|
|
227
297
|
};
|
|
228
298
|
return {
|
|
229
299
|
name: entry.name,
|
|
230
|
-
cells: readCells(worksheet, sharedStrings),
|
|
300
|
+
cells: readCells(worksheet, sharedStrings, numericFormats),
|
|
231
301
|
columns: readColumns(worksheet),
|
|
232
302
|
rows: readRows(worksheet),
|
|
233
303
|
images: [],
|
|
@@ -245,7 +315,8 @@ function fallbackEmptyWorksheet() {
|
|
|
245
315
|
function readXlsxContent(pkg) {
|
|
246
316
|
const sharedStrings = require_typed_xlsx_shared_strings.loadSharedStrings(pkg);
|
|
247
317
|
const definedNamesBySheet = require_typed_xlsx_defined_names.readDefinedNamesBySheet(pkg);
|
|
248
|
-
const
|
|
318
|
+
const numericFormats = readNumericFormatContext(pkg);
|
|
319
|
+
const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, numericFormats));
|
|
249
320
|
return {
|
|
250
321
|
kind: "spreadsheet",
|
|
251
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
|
|
@@ -42,12 +45,12 @@ function readColumns(worksheet) {
|
|
|
42
45
|
const minRaw = attr(col, "min");
|
|
43
46
|
const min = minRaw === void 0 ? void 0 : Number.parseInt(minRaw, 10);
|
|
44
47
|
if (min === void 0 || !Number.isInteger(min) || min < 1) continue;
|
|
48
|
+
const column = { index: min - 1 };
|
|
45
49
|
const widthRaw = attr(col, "width");
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
};
|
|
50
|
+
if (widthRaw !== void 0) {
|
|
51
|
+
const widthPt = columnWidthCharsToPt(Number(widthRaw));
|
|
52
|
+
if (Number.isFinite(widthPt)) column.widthPt = widthPt;
|
|
53
|
+
}
|
|
51
54
|
if (readXmlBool(attr(col, "hidden"))) column.hidden = true;
|
|
52
55
|
columns.push(column);
|
|
53
56
|
}
|
|
@@ -80,18 +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
|
-
case "time":
|
|
89
|
-
case "
|
|
90
|
-
case "currency": return String(value.value);
|
|
93
|
+
case "time":
|
|
94
|
+
case "dateTime": return value.value;
|
|
91
95
|
case "empty": return "";
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
|
-
|
|
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) {
|
|
95
168
|
const type = attr(cell, "t");
|
|
96
169
|
if (type === "inlineStr") {
|
|
97
170
|
const is = childrenWithTag(cell, "is")[0];
|
|
@@ -144,29 +217,26 @@ function readCellValue(cell, sharedStrings) {
|
|
|
144
217
|
};
|
|
145
218
|
if (type === "d") return {
|
|
146
219
|
value: {
|
|
147
|
-
kind: "
|
|
220
|
+
kind: "dateTime",
|
|
148
221
|
value: raw
|
|
149
222
|
},
|
|
150
223
|
displayText: raw
|
|
151
224
|
};
|
|
152
225
|
const num = Number(raw);
|
|
153
226
|
if (Number.isNaN(num)) return;
|
|
154
|
-
const value =
|
|
155
|
-
kind: "number",
|
|
156
|
-
value: num
|
|
157
|
-
};
|
|
227
|
+
const value = resolveNumericValue(num, cell, numericFormats);
|
|
158
228
|
return {
|
|
159
229
|
value,
|
|
160
230
|
displayText: deriveDisplayText(value)
|
|
161
231
|
};
|
|
162
232
|
}
|
|
163
|
-
function readCell(cell, sharedStrings) {
|
|
233
|
+
function readCell(cell, sharedStrings, numericFormats) {
|
|
164
234
|
const reference = attr(cell, "r");
|
|
165
235
|
const position = reference === void 0 ? void 0 : parseCellReference(reference);
|
|
166
236
|
if (position === void 0) return;
|
|
167
237
|
const formulaEl = childrenWithTag(cell, "f")[0];
|
|
168
238
|
const formula = formulaEl === void 0 ? void 0 : textContent(formulaEl);
|
|
169
|
-
const resolved = readCellValue(cell, sharedStrings);
|
|
239
|
+
const resolved = readCellValue(cell, sharedStrings, numericFormats);
|
|
170
240
|
if (resolved === void 0) {
|
|
171
241
|
if (formula === void 0) return;
|
|
172
242
|
return {
|
|
@@ -203,18 +273,18 @@ function applyMergedRanges(worksheet, cells) {
|
|
|
203
273
|
if (rowSpan > 1) anchor.rowSpan = rowSpan;
|
|
204
274
|
}
|
|
205
275
|
}
|
|
206
|
-
function readCells(worksheet, sharedStrings) {
|
|
276
|
+
function readCells(worksheet, sharedStrings, numericFormats) {
|
|
207
277
|
const sheetData = childrenWithTag(worksheet, "sheetData")[0];
|
|
208
278
|
if (sheetData === void 0) return [];
|
|
209
279
|
const cells = [];
|
|
210
280
|
for (const row of childrenWithTag(sheetData, "row")) for (const cell of childrenWithTag(row, "c")) {
|
|
211
|
-
const read = readCell(cell, sharedStrings);
|
|
281
|
+
const read = readCell(cell, sharedStrings, numericFormats);
|
|
212
282
|
if (read !== void 0) cells.push(read);
|
|
213
283
|
}
|
|
214
284
|
applyMergedRanges(worksheet, cells);
|
|
215
285
|
return cells;
|
|
216
286
|
}
|
|
217
|
-
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet) {
|
|
287
|
+
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, numericFormats) {
|
|
218
288
|
const worksheet = rootElement(pkg.parts[entry.path]);
|
|
219
289
|
if (worksheet === void 0) return {
|
|
220
290
|
name: entry.name,
|
|
@@ -226,7 +296,7 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet) {
|
|
|
226
296
|
};
|
|
227
297
|
return {
|
|
228
298
|
name: entry.name,
|
|
229
|
-
cells: readCells(worksheet, sharedStrings),
|
|
299
|
+
cells: readCells(worksheet, sharedStrings, numericFormats),
|
|
230
300
|
columns: readColumns(worksheet),
|
|
231
301
|
rows: readRows(worksheet),
|
|
232
302
|
images: [],
|
|
@@ -244,7 +314,8 @@ function fallbackEmptyWorksheet() {
|
|
|
244
314
|
function readXlsxContent(pkg) {
|
|
245
315
|
const sharedStrings = loadSharedStrings(pkg);
|
|
246
316
|
const definedNamesBySheet = readDefinedNamesBySheet(pkg);
|
|
247
|
-
const
|
|
317
|
+
const numericFormats = readNumericFormatContext(pkg);
|
|
318
|
+
const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, numericFormats));
|
|
248
319
|
return {
|
|
249
320
|
kind: "spreadsheet",
|
|
250
321
|
formatVersion: CONTENT_FORMAT_VERSION,
|