@cj-tech-master/excelts 5.0.0 → 5.0.1-canary.20260123024428.98c7ee0
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/dist/browser/modules/excel/column.d.ts +5 -0
- package/dist/browser/modules/excel/column.js +10 -2
- package/dist/browser/modules/excel/row.d.ts +2 -0
- package/dist/browser/modules/excel/row.js +3 -1
- package/dist/browser/modules/excel/workbook.d.ts +4 -0
- package/dist/browser/modules/excel/workbook.js +4 -1
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +1 -0
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +17 -10
- package/dist/browser/modules/excel/xlsx/xform/sheet/row-xform.d.ts +1 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/row-xform.js +7 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.d.ts +1 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +9 -4
- package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +4 -2
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +2 -1
- package/dist/browser/modules/excel/xlsx/xform/style/style-xform.d.ts +7 -0
- package/dist/browser/modules/excel/xlsx/xform/style/style-xform.js +26 -6
- package/dist/browser/modules/excel/xlsx/xform/style/styles-xform.d.ts +6 -0
- package/dist/browser/modules/excel/xlsx/xform/style/styles-xform.js +52 -4
- package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +9 -1
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +24 -10
- package/dist/cjs/modules/excel/column.js +10 -2
- package/dist/cjs/modules/excel/row.js +3 -1
- package/dist/cjs/modules/excel/workbook.js +4 -1
- package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +17 -10
- package/dist/cjs/modules/excel/xlsx/xform/sheet/row-xform.js +7 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +9 -4
- package/dist/cjs/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +4 -2
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +2 -1
- package/dist/cjs/modules/excel/xlsx/xform/style/style-xform.js +26 -6
- package/dist/cjs/modules/excel/xlsx/xform/style/styles-xform.js +52 -4
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +24 -10
- package/dist/esm/modules/excel/column.js +10 -2
- package/dist/esm/modules/excel/row.js +3 -1
- package/dist/esm/modules/excel/workbook.js +4 -1
- package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +17 -10
- package/dist/esm/modules/excel/xlsx/xform/sheet/row-xform.js +7 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +9 -4
- package/dist/esm/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +4 -2
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +2 -1
- package/dist/esm/modules/excel/xlsx/xform/style/style-xform.js +26 -6
- package/dist/esm/modules/excel/xlsx/xform/style/styles-xform.js +52 -4
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +24 -10
- package/dist/iife/excelts.iife.js +463 -400
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +7 -7
- package/dist/types/modules/excel/column.d.ts +5 -0
- package/dist/types/modules/excel/row.d.ts +2 -0
- package/dist/types/modules/excel/workbook.d.ts +4 -0
- package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +1 -0
- package/dist/types/modules/excel/xlsx/xform/sheet/row-xform.d.ts +1 -0
- package/dist/types/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.d.ts +1 -0
- package/dist/types/modules/excel/xlsx/xform/style/style-xform.d.ts +7 -0
- package/dist/types/modules/excel/xlsx/xform/style/styles-xform.d.ts +6 -0
- package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +9 -1
- package/package.json +14 -14
|
@@ -24,24 +24,27 @@ class StyleXform extends BaseXform {
|
|
|
24
24
|
if (this.xfId) {
|
|
25
25
|
xmlStream.addAttribute("xfId", model.xfId || 0);
|
|
26
26
|
}
|
|
27
|
-
if (model.numFmtId) {
|
|
27
|
+
if (model.applyNumberFormat || model.numFmtId) {
|
|
28
28
|
xmlStream.addAttribute("applyNumberFormat", "1");
|
|
29
29
|
}
|
|
30
|
-
if (model.fontId) {
|
|
30
|
+
if (model.applyFont || model.fontId) {
|
|
31
31
|
xmlStream.addAttribute("applyFont", "1");
|
|
32
32
|
}
|
|
33
|
-
if (model.fillId) {
|
|
33
|
+
if (model.applyFill || model.fillId) {
|
|
34
34
|
xmlStream.addAttribute("applyFill", "1");
|
|
35
35
|
}
|
|
36
|
-
if (model.borderId) {
|
|
36
|
+
if (model.applyBorder || model.borderId) {
|
|
37
37
|
xmlStream.addAttribute("applyBorder", "1");
|
|
38
38
|
}
|
|
39
|
-
if (model.alignment) {
|
|
39
|
+
if (model.applyAlignment || model.alignment) {
|
|
40
40
|
xmlStream.addAttribute("applyAlignment", "1");
|
|
41
41
|
}
|
|
42
|
-
if (model.protection) {
|
|
42
|
+
if (model.applyProtection || model.protection) {
|
|
43
43
|
xmlStream.addAttribute("applyProtection", "1");
|
|
44
44
|
}
|
|
45
|
+
if (model.pivotButton) {
|
|
46
|
+
xmlStream.addAttribute("pivotButton", "1");
|
|
47
|
+
}
|
|
45
48
|
/**
|
|
46
49
|
* Rendering tags causes close of XML stream.
|
|
47
50
|
* Therefore adding attributes must be done before rendering tags.
|
|
@@ -82,6 +85,23 @@ class StyleXform extends BaseXform {
|
|
|
82
85
|
if (this.xfId) {
|
|
83
86
|
this.model.xfId = parseInt(node.attributes.xfId, 10);
|
|
84
87
|
}
|
|
88
|
+
if (node.attributes.pivotButton === "1") {
|
|
89
|
+
this.model.pivotButton = true;
|
|
90
|
+
}
|
|
91
|
+
// Preserve apply* flags from original file
|
|
92
|
+
const applyFlags = [
|
|
93
|
+
"applyNumberFormat",
|
|
94
|
+
"applyFont",
|
|
95
|
+
"applyFill",
|
|
96
|
+
"applyBorder",
|
|
97
|
+
"applyAlignment",
|
|
98
|
+
"applyProtection"
|
|
99
|
+
];
|
|
100
|
+
for (const flag of applyFlags) {
|
|
101
|
+
if (node.attributes[flag] === "1") {
|
|
102
|
+
this.model[flag] = true;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
85
105
|
return true;
|
|
86
106
|
case "alignment":
|
|
87
107
|
this.parser = this.map.alignment;
|
|
@@ -84,6 +84,13 @@ class StylesXform extends BaseXform {
|
|
|
84
84
|
this.weakMap = new WeakMap();
|
|
85
85
|
this._hasCheckboxes = false;
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Set the default font to use when no font is explicitly specified.
|
|
89
|
+
* This preserves the original file's default font during round-trip.
|
|
90
|
+
*/
|
|
91
|
+
setDefaultFont(font) {
|
|
92
|
+
this.defaultFont = font;
|
|
93
|
+
}
|
|
87
94
|
render(xmlStream, model) {
|
|
88
95
|
const renderModel = model || this.model;
|
|
89
96
|
//
|
|
@@ -100,8 +107,8 @@ class StylesXform extends BaseXform {
|
|
|
100
107
|
xmlStream.closeNode();
|
|
101
108
|
}
|
|
102
109
|
if (!renderModel.fonts.length) {
|
|
103
|
-
// default (zero) font
|
|
104
|
-
this._addFont({
|
|
110
|
+
// default (zero) font - use preserved font or fallback to Calibri
|
|
111
|
+
this._addFont(this.defaultFont || {
|
|
105
112
|
size: 11,
|
|
106
113
|
color: { theme: 1 },
|
|
107
114
|
name: "Calibri",
|
|
@@ -193,6 +200,10 @@ class StylesXform extends BaseXform {
|
|
|
193
200
|
add("borders", this.map.borders);
|
|
194
201
|
add("styles", this.map.cellXfs);
|
|
195
202
|
add("dxfs", this.map.dxfs);
|
|
203
|
+
// preserve the default (first) font from the original file
|
|
204
|
+
if (this.map.fonts.model && this.map.fonts.model.length > 0) {
|
|
205
|
+
this.defaultFont = this.map.fonts.model[0];
|
|
206
|
+
}
|
|
196
207
|
// index numFmts
|
|
197
208
|
this.index = {
|
|
198
209
|
model: [],
|
|
@@ -220,8 +231,14 @@ class StylesXform extends BaseXform {
|
|
|
220
231
|
}
|
|
221
232
|
// if we have no default font, add it here now
|
|
222
233
|
if (!this.model.fonts.length) {
|
|
223
|
-
// default (zero) font
|
|
224
|
-
this._addFont(
|
|
234
|
+
// default (zero) font - use preserved font or fallback to Calibri
|
|
235
|
+
this._addFont(this.defaultFont || {
|
|
236
|
+
size: 11,
|
|
237
|
+
color: { theme: 1 },
|
|
238
|
+
name: "Calibri",
|
|
239
|
+
family: 2,
|
|
240
|
+
scheme: "minor"
|
|
241
|
+
});
|
|
225
242
|
}
|
|
226
243
|
const type = cellType || Enums.ValueType.Number;
|
|
227
244
|
// If we have seen this style object before, assume it has the same styleId.
|
|
@@ -262,6 +279,21 @@ class StylesXform extends BaseXform {
|
|
|
262
279
|
if (model.protection) {
|
|
263
280
|
style.protection = model.protection;
|
|
264
281
|
}
|
|
282
|
+
// Preserve xf-level attributes (pivotButton, apply* flags)
|
|
283
|
+
const xfFlags = [
|
|
284
|
+
"pivotButton",
|
|
285
|
+
"applyNumberFormat",
|
|
286
|
+
"applyFont",
|
|
287
|
+
"applyFill",
|
|
288
|
+
"applyBorder",
|
|
289
|
+
"applyAlignment",
|
|
290
|
+
"applyProtection"
|
|
291
|
+
];
|
|
292
|
+
for (const flag of xfFlags) {
|
|
293
|
+
if (model[flag]) {
|
|
294
|
+
style[flag] = true;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
265
297
|
if (type === Enums.ValueType.Checkbox) {
|
|
266
298
|
// Checkbox rendering relies on style extensions (extLst) and workbook-level parts.
|
|
267
299
|
// Force applyAlignment="1" (without emitting an <alignment/> node) by providing
|
|
@@ -322,6 +354,22 @@ class StylesXform extends BaseXform {
|
|
|
322
354
|
if (style.protection) {
|
|
323
355
|
model.protection = style.protection;
|
|
324
356
|
}
|
|
357
|
+
// -------------------------------------------------------
|
|
358
|
+
// xf-level attributes (pivotButton, apply* flags)
|
|
359
|
+
const xfFlags = [
|
|
360
|
+
"pivotButton",
|
|
361
|
+
"applyNumberFormat",
|
|
362
|
+
"applyFont",
|
|
363
|
+
"applyFill",
|
|
364
|
+
"applyBorder",
|
|
365
|
+
"applyAlignment",
|
|
366
|
+
"applyProtection"
|
|
367
|
+
];
|
|
368
|
+
for (const flag of xfFlags) {
|
|
369
|
+
if (style[flag]) {
|
|
370
|
+
model[flag] = true;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
325
373
|
return model;
|
|
326
374
|
}
|
|
327
375
|
addDxfStyle(style) {
|
|
@@ -600,6 +600,8 @@ class XLSX {
|
|
|
600
600
|
delete model.sharedStrings;
|
|
601
601
|
delete model.workbookRels;
|
|
602
602
|
delete model.sheetDefs;
|
|
603
|
+
// Preserve default font before deleting styles
|
|
604
|
+
model.defaultFont = model.styles?.defaultFont;
|
|
603
605
|
delete model.styles;
|
|
604
606
|
delete model.mediaIndex;
|
|
605
607
|
delete model.drawings;
|
|
@@ -759,16 +761,26 @@ class XLSX {
|
|
|
759
761
|
});
|
|
760
762
|
}
|
|
761
763
|
}
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
764
|
+
/**
|
|
765
|
+
* Process a drawing XML entry.
|
|
766
|
+
*
|
|
767
|
+
* @param stream - Stream to read from (used in loadFromZipEntries path)
|
|
768
|
+
* @param model - Model to populate
|
|
769
|
+
* @param name - Drawing name (e.g., "drawing1")
|
|
770
|
+
* @param rawData - Pre-read raw data (used in loadFromFiles path to avoid re-reading stream)
|
|
771
|
+
*/
|
|
772
|
+
async _processDrawingEntry(stream, model, name, rawData) {
|
|
773
|
+
// Use provided rawData if available (loadFromFiles path), otherwise collect from stream.
|
|
774
|
+
// In loadFromFiles, the stream is created from already-decoded text, and collecting from
|
|
775
|
+
// it may not work correctly due to PassThrough stream timing issues.
|
|
776
|
+
const data = rawData ?? (await this.collectStreamData(stream));
|
|
765
777
|
// Parse the drawing for normal processing (images, etc.)
|
|
766
778
|
const xform = new DrawingXform();
|
|
767
|
-
const xmlString = this.bufferToString(
|
|
779
|
+
const xmlString = this.bufferToString(data);
|
|
768
780
|
const drawing = await xform.parseStream(this.createTextStream(xmlString));
|
|
769
781
|
model.drawings[name] = drawing;
|
|
770
782
|
// Store raw data; reconcile() may later drop it if charts are not referenced.
|
|
771
|
-
model.rawDrawings[name] =
|
|
783
|
+
model.rawDrawings[name] = data;
|
|
772
784
|
}
|
|
773
785
|
async _processDrawingRelsEntry(entry, model, name) {
|
|
774
786
|
const xform = new RelationshipsXform();
|
|
@@ -885,11 +897,8 @@ class XLSX {
|
|
|
885
897
|
}
|
|
886
898
|
const drawingName = getDrawingNameFromPath(entryName);
|
|
887
899
|
if (drawingName) {
|
|
888
|
-
await this._processDrawingEntry(stream, model, drawingName);
|
|
889
|
-
//
|
|
890
|
-
if (rawData) {
|
|
891
|
-
model.rawDrawings[drawingName] = rawData;
|
|
892
|
-
}
|
|
900
|
+
await this._processDrawingEntry(stream, model, drawingName, rawData);
|
|
901
|
+
// rawData is now stored inside _processDrawingEntry
|
|
893
902
|
return true;
|
|
894
903
|
}
|
|
895
904
|
const drawingRelsName = getDrawingNameFromRelsPath(entryName);
|
|
@@ -1235,7 +1244,12 @@ class XLSX {
|
|
|
1235
1244
|
options.useSharedStrings !== undefined ? options.useSharedStrings : true;
|
|
1236
1245
|
model.useStyles = options.useStyles !== undefined ? options.useStyles : true;
|
|
1237
1246
|
model.sharedStrings = new SharedStringsXform();
|
|
1247
|
+
// Preserve default font from parsed styles if available
|
|
1248
|
+
const oldDefaultFont = model.defaultFont;
|
|
1238
1249
|
model.styles = model.useStyles ? new StylesXform(true) : new StylesXform.Mock();
|
|
1250
|
+
if (oldDefaultFont && model.styles.setDefaultFont) {
|
|
1251
|
+
model.styles.setDefaultFont(oldDefaultFont);
|
|
1252
|
+
}
|
|
1239
1253
|
const workbookXform = new WorkbookXform();
|
|
1240
1254
|
const worksheetXform = new WorkSheetXform();
|
|
1241
1255
|
workbookXform.prepare(model);
|