@cj-tech-master/excelts 4.2.3 → 5.0.0-canary.20260123012457.1fdf506

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.
Files changed (84) hide show
  1. package/dist/browser/modules/csv/csv-core.d.ts +0 -9
  2. package/dist/browser/modules/csv/csv.browser.js +3 -3
  3. package/dist/browser/modules/excel/column.d.ts +5 -0
  4. package/dist/browser/modules/excel/column.js +10 -2
  5. package/dist/browser/modules/excel/row.d.ts +2 -0
  6. package/dist/browser/modules/excel/row.js +3 -1
  7. package/dist/browser/modules/excel/utils/parse-sax.d.ts +0 -3
  8. package/dist/browser/modules/excel/utils/parse-sax.js +13 -32
  9. package/dist/browser/modules/excel/utils/passthrough-manager.d.ts +77 -0
  10. package/dist/browser/modules/excel/utils/passthrough-manager.js +129 -0
  11. package/dist/browser/modules/excel/workbook.d.ts +12 -0
  12. package/dist/browser/modules/excel/workbook.js +12 -1
  13. package/dist/browser/modules/excel/worksheet.d.ts +4 -0
  14. package/dist/browser/modules/excel/worksheet.js +4 -1
  15. package/dist/browser/modules/excel/xlsx/xform/base-xform.js +68 -1
  16. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +16 -10
  17. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +35 -11
  18. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +271 -94
  19. package/dist/browser/modules/excel/xlsx/xform/sheet/row-xform.d.ts +1 -0
  20. package/dist/browser/modules/excel/xlsx/xform/sheet/row-xform.js +7 -1
  21. package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.d.ts +1 -0
  22. package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +9 -4
  23. package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +4 -2
  24. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +40 -12
  25. package/dist/browser/modules/excel/xlsx/xform/style/style-xform.d.ts +7 -0
  26. package/dist/browser/modules/excel/xlsx/xform/style/style-xform.js +26 -6
  27. package/dist/browser/modules/excel/xlsx/xform/style/styles-xform.d.ts +6 -0
  28. package/dist/browser/modules/excel/xlsx/xform/style/styles-xform.js +52 -4
  29. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +36 -1
  30. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +220 -131
  31. package/dist/browser/modules/stream/streams.browser.js +0 -3
  32. package/dist/cjs/modules/csv/csv.browser.js +3 -3
  33. package/dist/cjs/modules/excel/column.js +10 -2
  34. package/dist/cjs/modules/excel/row.js +3 -1
  35. package/dist/cjs/modules/excel/utils/parse-sax.js +13 -32
  36. package/dist/cjs/modules/excel/utils/passthrough-manager.js +133 -0
  37. package/dist/cjs/modules/excel/workbook.js +12 -1
  38. package/dist/cjs/modules/excel/worksheet.js +4 -1
  39. package/dist/cjs/modules/excel/xlsx/xform/base-xform.js +68 -1
  40. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +16 -10
  41. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +271 -94
  42. package/dist/cjs/modules/excel/xlsx/xform/sheet/row-xform.js +7 -1
  43. package/dist/cjs/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +9 -4
  44. package/dist/cjs/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +4 -2
  45. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +40 -12
  46. package/dist/cjs/modules/excel/xlsx/xform/style/style-xform.js +26 -6
  47. package/dist/cjs/modules/excel/xlsx/xform/style/styles-xform.js +52 -4
  48. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +220 -131
  49. package/dist/cjs/modules/stream/streams.browser.js +0 -3
  50. package/dist/esm/modules/csv/csv.browser.js +3 -3
  51. package/dist/esm/modules/excel/column.js +10 -2
  52. package/dist/esm/modules/excel/row.js +3 -1
  53. package/dist/esm/modules/excel/utils/parse-sax.js +13 -32
  54. package/dist/esm/modules/excel/utils/passthrough-manager.js +129 -0
  55. package/dist/esm/modules/excel/workbook.js +12 -1
  56. package/dist/esm/modules/excel/worksheet.js +4 -1
  57. package/dist/esm/modules/excel/xlsx/xform/base-xform.js +68 -1
  58. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +16 -10
  59. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +271 -94
  60. package/dist/esm/modules/excel/xlsx/xform/sheet/row-xform.js +7 -1
  61. package/dist/esm/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +9 -4
  62. package/dist/esm/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +4 -2
  63. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +40 -12
  64. package/dist/esm/modules/excel/xlsx/xform/style/style-xform.js +26 -6
  65. package/dist/esm/modules/excel/xlsx/xform/style/styles-xform.js +52 -4
  66. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +220 -131
  67. package/dist/esm/modules/stream/streams.browser.js +0 -3
  68. package/dist/iife/excelts.iife.js +1009 -650
  69. package/dist/iife/excelts.iife.js.map +1 -1
  70. package/dist/iife/excelts.iife.min.js +25 -52
  71. package/dist/types/modules/csv/csv-core.d.ts +0 -9
  72. package/dist/types/modules/excel/column.d.ts +5 -0
  73. package/dist/types/modules/excel/row.d.ts +2 -0
  74. package/dist/types/modules/excel/utils/parse-sax.d.ts +0 -3
  75. package/dist/types/modules/excel/utils/passthrough-manager.d.ts +77 -0
  76. package/dist/types/modules/excel/workbook.d.ts +12 -0
  77. package/dist/types/modules/excel/worksheet.d.ts +4 -0
  78. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +35 -11
  79. package/dist/types/modules/excel/xlsx/xform/sheet/row-xform.d.ts +1 -0
  80. package/dist/types/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.d.ts +1 -0
  81. package/dist/types/modules/excel/xlsx/xform/style/style-xform.d.ts +7 -0
  82. package/dist/types/modules/excel/xlsx/xform/style/styles-xform.d.ts +6 -0
  83. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +36 -1
  84. package/package.json +15 -15
@@ -5,6 +5,7 @@ interface SheetFormatPropertiesModel {
5
5
  outlineLevelRow: number;
6
6
  outlineLevelCol: number;
7
7
  defaultColWidth?: number;
8
+ customHeight?: boolean;
8
9
  }
9
10
  declare class SheetFormatPropertiesXform extends BaseXform {
10
11
  get tag(): string;
@@ -11,14 +11,14 @@ class SheetFormatPropertiesXform extends BaseXform {
11
11
  outlineLevelRow: model.outlineLevelRow || undefined,
12
12
  outlineLevelCol: model.outlineLevelCol || undefined,
13
13
  // Only output dyDescent if explicitly set (MS extension, not ECMA-376 standard)
14
- "x14ac:dyDescent": model.dyDescent || undefined
14
+ "x14ac:dyDescent": model.dyDescent !== undefined && model.dyDescent !== 0 ? model.dyDescent : undefined
15
15
  };
16
16
  // Only output defaultColWidth if explicitly set
17
17
  if (model.defaultColWidth) {
18
18
  attributes.defaultColWidth = model.defaultColWidth;
19
19
  }
20
- // default value for 'defaultRowHeight' is 15, this should not be 'custom'
21
- if (!model.defaultRowHeight || model.defaultRowHeight !== 15) {
20
+ // Only output customHeight if it was present in the original file
21
+ if (model.customHeight) {
22
22
  attributes.customHeight = "1";
23
23
  }
24
24
  if (Object.values(attributes).some((value) => value !== undefined)) {
@@ -30,13 +30,18 @@ class SheetFormatPropertiesXform extends BaseXform {
30
30
  if (node.name === "sheetFormatPr") {
31
31
  this.model = {
32
32
  defaultRowHeight: parseFloat(node.attributes.defaultRowHeight || "0"),
33
- dyDescent: parseFloat(node.attributes["x14ac:dyDescent"] || "0"),
33
+ dyDescent: node.attributes["x14ac:dyDescent"] !== undefined
34
+ ? parseFloat(node.attributes["x14ac:dyDescent"])
35
+ : undefined,
34
36
  outlineLevelRow: parseInt(node.attributes.outlineLevelRow || "0", 10),
35
37
  outlineLevelCol: parseInt(node.attributes.outlineLevelCol || "0", 10)
36
38
  };
37
39
  if (node.attributes.defaultColWidth) {
38
40
  this.model.defaultColWidth = parseFloat(node.attributes.defaultColWidth);
39
41
  }
42
+ if (node.attributes.customHeight === "1") {
43
+ this.model.customHeight = true;
44
+ }
40
45
  return true;
41
46
  }
42
47
  return false;
@@ -37,8 +37,8 @@ class SheetViewXform extends BaseXform {
37
37
  add("showRuler", "0", model.showRuler === false);
38
38
  add("showRowColHeaders", "0", model.showRowColHeaders === false);
39
39
  add("showGridLines", "0", model.showGridLines === false);
40
- add("zoomScale", model.zoomScale, model.zoomScale);
41
- add("zoomScaleNormal", model.zoomScaleNormal, model.zoomScaleNormal);
40
+ add("zoomScale", model.zoomScale, model.zoomScale !== undefined && model.zoomScale !== 100);
41
+ add("zoomScaleNormal", model.zoomScaleNormal, model.zoomScaleNormal !== undefined && model.zoomScaleNormal !== 100);
42
42
  add("view", model.style, model.style);
43
43
  let topLeftCell;
44
44
  let xSplit;
@@ -143,6 +143,7 @@ class SheetViewXform extends BaseXform {
143
143
  model = this.model = {
144
144
  workbookViewId: this.sheetView.workbookViewId,
145
145
  rightToLeft: this.sheetView.rightToLeft,
146
+ tabSelected: this.sheetView.tabSelected,
146
147
  state: VIEW_STATES[this.pane.state] || "split", // split is default
147
148
  xSplit: this.pane.xSplit,
148
149
  ySplit: this.pane.ySplit,
@@ -168,6 +169,7 @@ class SheetViewXform extends BaseXform {
168
169
  model = this.model = {
169
170
  workbookViewId: this.sheetView.workbookViewId,
170
171
  rightToLeft: this.sheetView.rightToLeft,
172
+ tabSelected: this.sheetView.tabSelected,
171
173
  state: "normal",
172
174
  showRuler: this.sheetView.showRuler,
173
175
  showRowColHeaders: this.sheetView.showRowColHeaders,
@@ -188,6 +188,23 @@ class WorkSheetXform extends BaseXform {
188
188
  vmlDrawing: `vmlDrawing${model.id}`
189
189
  });
190
190
  }
191
+ // Handle pre-loaded drawing (from file read) that may contain charts or other non-image content
192
+ // This preserves drawings through round-trip even if they don't contain images
193
+ // Note: Always assign a new rId since rels are rebuilt during write
194
+ if (model.drawing && model.drawing.anchors) {
195
+ // This is a loaded drawing that needs to be added to relationships
196
+ const drawing = model.drawing;
197
+ drawing.rId = nextRid(rels);
198
+ if (!drawing.name) {
199
+ drawing.name = `drawing${++options.drawingsCount}`;
200
+ }
201
+ options.drawings.push(drawing);
202
+ rels.push({
203
+ Id: drawing.rId,
204
+ Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
205
+ Target: drawingRelTargetFromWorksheet(drawing.name)
206
+ });
207
+ }
191
208
  const drawingRelsHash = [];
192
209
  let bookImage;
193
210
  model.media.forEach(medium => {
@@ -367,7 +384,8 @@ class WorkSheetXform extends BaseXform {
367
384
  defaultRowHeight: model.properties.defaultRowHeight,
368
385
  dyDescent: model.properties.dyDescent,
369
386
  outlineLevelCol: model.properties.outlineLevelCol,
370
- outlineLevelRow: model.properties.outlineLevelRow
387
+ outlineLevelRow: model.properties.outlineLevelRow,
388
+ customHeight: model.properties.customHeight
371
389
  }
372
390
  : undefined;
373
391
  if (model.properties && model.properties.defaultColWidth) {
@@ -599,17 +617,27 @@ class WorkSheetXform extends BaseXform {
599
617
  if (match) {
600
618
  const drawingName = match[1];
601
619
  const drawing = options.drawings[drawingName];
602
- drawing.anchors.forEach(anchor => {
603
- if (anchor.medium) {
604
- const image = {
605
- type: "image",
606
- imageId: anchor.medium.index,
607
- range: anchor.range,
608
- hyperlinks: anchor.picture.hyperlinks
609
- };
610
- model.media.push(image);
611
- }
612
- });
620
+ if (drawing) {
621
+ // Preserve the drawing object for round-trip (charts, etc.)
622
+ // This includes the name, anchors, and rels
623
+ model.drawing = {
624
+ ...drawing,
625
+ name: drawingName,
626
+ rels: options.drawingRels?.[drawingName] || drawing.rels || []
627
+ };
628
+ // Also extract images to model.media for backward compatibility
629
+ drawing.anchors.forEach(anchor => {
630
+ if (anchor.medium) {
631
+ const image = {
632
+ type: "image",
633
+ imageId: anchor.medium.index,
634
+ range: anchor.range,
635
+ hyperlinks: anchor.picture.hyperlinks
636
+ };
637
+ model.media.push(image);
638
+ }
639
+ });
640
+ }
613
641
  }
614
642
  }
615
643
  const backgroundRel = model.background && rels[model.background.rId];
@@ -11,6 +11,13 @@ interface StyleModel {
11
11
  protection?: any;
12
12
  checkbox?: boolean;
13
13
  xfComplementIndex?: number;
14
+ pivotButton?: boolean;
15
+ applyNumberFormat?: boolean;
16
+ applyFont?: boolean;
17
+ applyFill?: boolean;
18
+ applyBorder?: boolean;
19
+ applyAlignment?: boolean;
20
+ applyProtection?: boolean;
14
21
  }
15
22
  interface StyleOptions {
16
23
  xfId?: boolean;
@@ -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;
@@ -12,11 +12,17 @@ declare class StylesXform extends BaseXform {
12
12
  private index?;
13
13
  private weakMap?;
14
14
  private _hasCheckboxes?;
15
+ defaultFont?: any;
15
16
  parser: any;
16
17
  static Mock: typeof StylesXform;
17
18
  constructor(initialise?: boolean);
18
19
  initIndex(): void;
19
20
  init(): void;
21
+ /**
22
+ * Set the default font to use when no font is explicitly specified.
23
+ * This preserves the original file's default font during round-trip.
24
+ */
25
+ setDefaultFont(font: any): void;
20
26
  render(xmlStream: any, model?: StylesModel): void;
21
27
  parseOpen(node: any): boolean;
22
28
  parseText(text: string): void;
@@ -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({ size: 11, color: { theme: 1 }, name: "Calibri", family: 2, scheme: "minor" });
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) {
@@ -144,6 +144,30 @@ declare class XLSX {
144
144
  * This is the foundation for TRUE streaming reads on platforms that have a
145
145
  * streaming ZIP parser (e.g. Node.js `modules/archive` Parse).
146
146
  */
147
+ /**
148
+ * Create an empty model for parsing XLSX files.
149
+ * Shared by loadFromZipEntries and loadFromFiles.
150
+ */
151
+ private createEmptyModel;
152
+ /**
153
+ * Collect all data from a stream into a single Uint8Array.
154
+ * Reusable helper for passthrough and drawing processing.
155
+ */
156
+ protected collectStreamData(stream: IParseStream): Promise<Uint8Array>;
157
+ /**
158
+ * Check if a drawing has chart references in its relationships
159
+ */
160
+ private drawingHasChartReference;
161
+ /**
162
+ * Check if a drawing rels list references charts.
163
+ * Used to decide whether we need to keep raw drawing XML for passthrough.
164
+ */
165
+ private drawingRelsHasChartReference;
166
+ /**
167
+ * Process a known OOXML entry (workbook, styles, shared strings, etc.)
168
+ * Returns true if handled, false if should be passed to _processDefaultEntry
169
+ */
170
+ protected _processKnownEntry(stream: IParseStream, model: any, entryName: string, options?: XlsxOptions): Promise<boolean>;
147
171
  protected loadFromZipEntries(entries: AsyncIterable<ZipEntryLike>, options?: XlsxOptions): Promise<any>;
148
172
  /**
149
173
  * Write workbook to buffer
@@ -189,8 +213,14 @@ declare class XLSX {
189
213
  loadFromFiles(zipData: Record<string, Uint8Array>, options?: any): Promise<any>;
190
214
  /**
191
215
  * Process default entries (drawings, comments, tables, etc.)
216
+ * @param rawData Optional raw entry data for passthrough preservation (used by loadFromFiles)
192
217
  */
193
- protected _processDefaultEntry(stream: IParseStream, model: any, entryName: string): Promise<boolean>;
218
+ protected _processDefaultEntry(stream: IParseStream, model: any, entryName: string, rawData?: Uint8Array): Promise<boolean>;
219
+ /**
220
+ * Store a passthrough file for preservation during read/write cycles.
221
+ * These files are not parsed but stored as raw bytes to be written back unchanged.
222
+ */
223
+ _processPassthroughEntry(stream: IParseStream, model: any, entryName: string): Promise<void>;
194
224
  addContentTypes(zip: IZipWriter, model: any): Promise<void>;
195
225
  addApp(zip: IZipWriter, model: any): Promise<void>;
196
226
  addCore(zip: IZipWriter, model: any): Promise<void>;
@@ -204,6 +234,11 @@ declare class XLSX {
204
234
  addWorksheets(zip: IZipWriter, model: any): Promise<void>;
205
235
  addDrawings(zip: IZipWriter, model: any): void;
206
236
  addTables(zip: IZipWriter, model: any): void;
237
+ /**
238
+ * Write passthrough files (charts, etc.) that were preserved during read.
239
+ * These files are written back unchanged to preserve unsupported features.
240
+ */
241
+ addPassthrough(zip: IZipWriter, model: any): void;
207
242
  addPivotTables(zip: IZipWriter, model: any): void;
208
243
  _finalize(zip: IZipWriter): Promise<this>;
209
244
  prepareModel(model: any, options: any): void;