@cj-tech-master/excelts 4.2.3-canary.20260115111903.b80904d → 4.2.3-canary.20260122073152.a9bb6b0

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 (40) 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/utils/passthrough-manager.d.ts +77 -0
  4. package/dist/browser/modules/excel/utils/passthrough-manager.js +129 -0
  5. package/dist/browser/modules/excel/workbook.d.ts +8 -0
  6. package/dist/browser/modules/excel/workbook.js +9 -1
  7. package/dist/browser/modules/excel/worksheet.d.ts +4 -0
  8. package/dist/browser/modules/excel/worksheet.js +4 -1
  9. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +16 -10
  10. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +34 -11
  11. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +256 -86
  12. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +38 -11
  13. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +36 -1
  14. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +213 -131
  15. package/dist/cjs/modules/csv/csv.browser.js +3 -3
  16. package/dist/cjs/modules/excel/utils/passthrough-manager.js +133 -0
  17. package/dist/cjs/modules/excel/workbook.js +9 -1
  18. package/dist/cjs/modules/excel/worksheet.js +4 -1
  19. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +16 -10
  20. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +256 -86
  21. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +38 -11
  22. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +213 -131
  23. package/dist/esm/modules/csv/csv.browser.js +3 -3
  24. package/dist/esm/modules/excel/utils/passthrough-manager.js +129 -0
  25. package/dist/esm/modules/excel/workbook.js +9 -1
  26. package/dist/esm/modules/excel/worksheet.js +4 -1
  27. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +16 -10
  28. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +256 -86
  29. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +38 -11
  30. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +213 -131
  31. package/dist/iife/excelts.iife.js +512 -241
  32. package/dist/iife/excelts.iife.js.map +1 -1
  33. package/dist/iife/excelts.iife.min.js +24 -51
  34. package/dist/types/modules/csv/csv-core.d.ts +0 -9
  35. package/dist/types/modules/excel/utils/passthrough-manager.d.ts +77 -0
  36. package/dist/types/modules/excel/workbook.d.ts +8 -0
  37. package/dist/types/modules/excel/worksheet.d.ts +4 -0
  38. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +34 -11
  39. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +36 -1
  40. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @cj-tech-master/excelts v4.2.3-canary.20260115111903.b80904d
2
+ * @cj-tech-master/excelts v4.2.3-canary.20260122073152.a9bb6b0
3
3
  * TypeScript Excel Workbook Manager - Read and Write xlsx and csv Files.
4
4
  * (c) 2026 cjnoname
5
5
  * Released under the MIT License
@@ -6216,7 +6216,8 @@ var ExcelTS = (function(exports) {
6216
6216
  tables: Object.values(this.tables).map((table) => table.model),
6217
6217
  pivotTables: this.pivotTables,
6218
6218
  conditionalFormattings: this.conditionalFormattings,
6219
- formControls: this.formControls.map((fc) => fc.model)
6219
+ formControls: this.formControls.map((fc) => fc.model),
6220
+ drawing: this._drawing
6220
6221
  };
6221
6222
  model.cols = Column.toModel(this.columns || []);
6222
6223
  const rows = model.rows = [];
@@ -6271,6 +6272,7 @@ var ExcelTS = (function(exports) {
6271
6272
  this.pivotTables = value.pivotTables;
6272
6273
  this.conditionalFormattings = value.conditionalFormattings;
6273
6274
  this.formControls = [];
6275
+ this._drawing = value.drawing;
6274
6276
  }
6275
6277
  };
6276
6278
 
@@ -10406,28 +10408,26 @@ var ExcelTS = (function(exports) {
10406
10408
  ContentType: "application/vnd.openxmlformats-officedocument.drawing+xml"
10407
10409
  });
10408
10410
  });
10409
- if (model.commentRefs) {
10410
- xmlStream.leafNode("Default", {
10411
- Extension: "vml",
10412
- ContentType: "application/vnd.openxmlformats-officedocument.vmlDrawing"
10413
- });
10414
- model.commentRefs.forEach(({ commentName }) => {
10415
- xmlStream.leafNode("Override", {
10416
- PartName: toContentTypesPartName(commentsPathFromName(commentName)),
10417
- ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"
10418
- });
10419
- });
10420
- }
10421
- if (model.formControlRefs) {
10422
- if (!model.commentRefs) xmlStream.leafNode("Default", {
10423
- Extension: "vml",
10424
- ContentType: "application/vnd.openxmlformats-officedocument.vmlDrawing"
10425
- });
10426
- for (const ctrlPropId of model.formControlRefs) xmlStream.leafNode("Override", {
10427
- PartName: toContentTypesPartName(ctrlPropPath(ctrlPropId)),
10428
- ContentType: "application/vnd.ms-excel.controlproperties+xml"
10411
+ const hasComments = model.commentRefs && model.commentRefs.length > 0;
10412
+ const hasFormControls = model.formControlRefs && model.formControlRefs.length > 0;
10413
+ if (hasComments || hasFormControls) xmlStream.leafNode("Default", {
10414
+ Extension: "vml",
10415
+ ContentType: "application/vnd.openxmlformats-officedocument.vmlDrawing"
10416
+ });
10417
+ if (hasComments) model.commentRefs.forEach(({ commentName }) => {
10418
+ xmlStream.leafNode("Override", {
10419
+ PartName: toContentTypesPartName(commentsPathFromName(commentName)),
10420
+ ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"
10429
10421
  });
10430
- }
10422
+ });
10423
+ if (hasFormControls) for (const ctrlPropId of model.formControlRefs) xmlStream.leafNode("Override", {
10424
+ PartName: toContentTypesPartName(ctrlPropPath(ctrlPropId)),
10425
+ ContentType: "application/vnd.ms-excel.controlproperties+xml"
10426
+ });
10427
+ if (model.passthroughContentTypes) for (const { partName, contentType } of model.passthroughContentTypes) xmlStream.leafNode("Override", {
10428
+ PartName: toContentTypesPartName(partName),
10429
+ ContentType: contentType
10430
+ });
10431
10431
  xmlStream.leafNode("Override", {
10432
10432
  PartName: toContentTypesPartName(OOXML_PATHS.docPropsCore),
10433
10433
  ContentType: "application/vnd.openxmlformats-package.core-properties+xml"
@@ -13862,6 +13862,17 @@ var ExcelTS = (function(exports) {
13862
13862
  vmlDrawing: `vmlDrawing${model.id}`
13863
13863
  });
13864
13864
  }
13865
+ if (model.drawing && model.drawing.anchors) {
13866
+ const drawing = model.drawing;
13867
+ drawing.rId = nextRid(rels);
13868
+ if (!drawing.name) drawing.name = `drawing${++options.drawingsCount}`;
13869
+ options.drawings.push(drawing);
13870
+ rels.push({
13871
+ Id: drawing.rId,
13872
+ Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
13873
+ Target: drawingRelTargetFromWorksheet(drawing.name)
13874
+ });
13875
+ }
13865
13876
  const drawingRelsHash = [];
13866
13877
  let bookImage;
13867
13878
  model.media.forEach((medium) => {
@@ -14199,17 +14210,25 @@ var ExcelTS = (function(exports) {
14199
14210
  const match = rels[model.drawing.rId].Target.match(/\/drawings\/([a-zA-Z0-9]+)[.][a-zA-Z]{3,4}$/);
14200
14211
  if (match) {
14201
14212
  const drawingName = match[1];
14202
- options.drawings[drawingName].anchors.forEach((anchor) => {
14203
- if (anchor.medium) {
14204
- const image = {
14205
- type: "image",
14206
- imageId: anchor.medium.index,
14207
- range: anchor.range,
14208
- hyperlinks: anchor.picture.hyperlinks
14209
- };
14210
- model.media.push(image);
14211
- }
14212
- });
14213
+ const drawing = options.drawings[drawingName];
14214
+ if (drawing) {
14215
+ model.drawing = {
14216
+ ...drawing,
14217
+ name: drawingName,
14218
+ rels: options.drawingRels?.[drawingName] || drawing.rels || []
14219
+ };
14220
+ drawing.anchors.forEach((anchor) => {
14221
+ if (anchor.medium) {
14222
+ const image = {
14223
+ type: "image",
14224
+ imageId: anchor.medium.index,
14225
+ range: anchor.range,
14226
+ hyperlinks: anchor.picture.hyperlinks
14227
+ };
14228
+ model.media.push(image);
14229
+ }
14230
+ });
14231
+ }
14213
14232
  }
14214
14233
  }
14215
14234
  const backgroundRel = model.background && rels[model.background.rId];
@@ -15961,18 +15980,27 @@ var ExcelTS = (function(exports) {
15961
15980
  var PivotTableXform = class PivotTableXform extends BaseXform {
15962
15981
  constructor() {
15963
15982
  super();
15983
+ this.state = {
15984
+ inPivotFields: false,
15985
+ inRowFields: false,
15986
+ inColFields: false,
15987
+ inDataFields: false,
15988
+ inRowItems: false,
15989
+ inColItems: false,
15990
+ inLocation: false,
15991
+ inItems: false,
15992
+ inPivotTableStyleInfo: false,
15993
+ inChartFormats: false,
15994
+ inPivotArea: false
15995
+ };
15996
+ this.currentPivotField = null;
15997
+ this.currentRowItem = null;
15998
+ this.currentColItem = null;
15999
+ this.currentChartFormat = null;
16000
+ this.pivotAreaXmlBuffer = [];
16001
+ this.pivotAreaDepth = 0;
15964
16002
  this.map = {};
15965
16003
  this.model = null;
15966
- this.inPivotFields = false;
15967
- this.inRowFields = false;
15968
- this.inColFields = false;
15969
- this.inDataFields = false;
15970
- this.inRowItems = false;
15971
- this.inColItems = false;
15972
- this.inLocation = false;
15973
- this.currentPivotField = null;
15974
- this.inItems = false;
15975
- this.inPivotTableStyleInfo = false;
15976
16004
  }
15977
16005
  prepare(_model) {}
15978
16006
  get tag() {
@@ -15980,16 +16008,15 @@ var ExcelTS = (function(exports) {
15980
16008
  }
15981
16009
  reset() {
15982
16010
  this.model = null;
15983
- this.inPivotFields = false;
15984
- this.inRowFields = false;
15985
- this.inColFields = false;
15986
- this.inDataFields = false;
15987
- this.inRowItems = false;
15988
- this.inColItems = false;
15989
- this.inLocation = false;
16011
+ Object.keys(this.state).forEach((key) => {
16012
+ this.state[key] = false;
16013
+ });
15990
16014
  this.currentPivotField = null;
15991
- this.inItems = false;
15992
- this.inPivotTableStyleInfo = false;
16015
+ this.currentRowItem = null;
16016
+ this.currentColItem = null;
16017
+ this.currentChartFormat = null;
16018
+ this.pivotAreaXmlBuffer = [];
16019
+ this.pivotAreaDepth = 0;
15993
16020
  }
15994
16021
  /**
15995
16022
  * Render pivot table XML.
@@ -16088,8 +16115,7 @@ var ExcelTS = (function(exports) {
16088
16115
  * Render loaded pivot table (preserving original structure)
16089
16116
  */
16090
16117
  renderLoaded(xmlStream, model) {
16091
- xmlStream.openXml(XmlStream.StdDocAttributes);
16092
- xmlStream.openNode(this.tag, {
16118
+ const attrs = {
16093
16119
  ...PivotTableXform.PIVOT_TABLE_ATTRIBUTES,
16094
16120
  name: model.name || "PivotTable1",
16095
16121
  cacheId: model.cacheId,
@@ -16098,7 +16124,7 @@ var ExcelTS = (function(exports) {
16098
16124
  applyFontFormats: model.applyFontFormats || "0",
16099
16125
  applyPatternFormats: model.applyPatternFormats || "0",
16100
16126
  applyAlignmentFormats: model.applyAlignmentFormats || "0",
16101
- applyWidthHeightFormats: model.applyWidthHeightFormats || "0",
16127
+ applyWidthHeightFormats: model.applyWidthHeightFormats ?? "0",
16102
16128
  dataCaption: model.dataCaption || "Values",
16103
16129
  updatedVersion: model.updatedVersion || "8",
16104
16130
  minRefreshableVersion: model.minRefreshableVersion || "3",
@@ -16106,10 +16132,15 @@ var ExcelTS = (function(exports) {
16106
16132
  itemPrintTitles: model.itemPrintTitles ? "1" : "0",
16107
16133
  createdVersion: model.createdVersion || "8",
16108
16134
  indent: model.indent !== void 0 ? String(model.indent) : "0",
16109
- compact: model.compact ? "1" : "0",
16110
- compactData: model.compactData ? "1" : "0",
16111
16135
  multipleFieldFilters: model.multipleFieldFilters ? "1" : "0"
16112
- });
16136
+ };
16137
+ if (model.outline) attrs.outline = "1";
16138
+ if (model.outlineData) attrs.outlineData = "1";
16139
+ if (model.chartFormat !== void 0) attrs.chartFormat = String(model.chartFormat);
16140
+ if (model.compact) attrs.compact = "1";
16141
+ if (model.compactData) attrs.compactData = "1";
16142
+ xmlStream.openXml(XmlStream.StdDocAttributes);
16143
+ xmlStream.openNode(this.tag, attrs);
16113
16144
  if (model.location) xmlStream.leafNode("location", {
16114
16145
  ref: model.location.ref,
16115
16146
  firstHeaderRow: model.location.firstHeaderRow,
@@ -16126,30 +16157,46 @@ var ExcelTS = (function(exports) {
16126
16157
  for (const fieldIndex of model.rowFields) xmlStream.leafNode("field", { x: fieldIndex });
16127
16158
  xmlStream.closeNode();
16128
16159
  }
16129
- xmlStream.writeXml(`
16130
- <rowItems count="1">
16131
- <i t="grand"><x /></i>
16132
- </rowItems>`);
16160
+ if (model.rowItems && model.rowItems.length > 0) {
16161
+ xmlStream.openNode("rowItems", { count: model.rowItems.length });
16162
+ for (const item of model.rowItems) this.renderRowColItem(xmlStream, item);
16163
+ xmlStream.closeNode();
16164
+ } else xmlStream.writeXml("<rowItems count=\"1\"><i t=\"grand\"><x/></i></rowItems>");
16133
16165
  const colFieldCount = model.colFields.length === 0 ? 1 : model.colFields.length;
16134
16166
  xmlStream.openNode("colFields", { count: colFieldCount });
16135
16167
  if (model.colFields.length === 0) xmlStream.leafNode("field", { x: -2 });
16136
16168
  else for (const fieldIndex of model.colFields) xmlStream.leafNode("field", { x: fieldIndex });
16137
16169
  xmlStream.closeNode();
16138
- xmlStream.writeXml(`
16139
- <colItems count="1">
16140
- <i t="grand"><x /></i>
16141
- </colItems>`);
16170
+ if (model.colItems && model.colItems.length > 0) {
16171
+ xmlStream.openNode("colItems", { count: model.colItems.length });
16172
+ for (const item of model.colItems) this.renderRowColItem(xmlStream, item);
16173
+ xmlStream.closeNode();
16174
+ } else xmlStream.writeXml("<colItems count=\"1\"><i t=\"grand\"><x/></i></colItems>");
16142
16175
  if (model.dataFields.length > 0) {
16143
16176
  xmlStream.openNode("dataFields", { count: model.dataFields.length });
16144
16177
  for (const dataField of model.dataFields) {
16145
- const attrs = {
16178
+ const dfAttrs = {
16146
16179
  name: dataField.name,
16147
16180
  fld: dataField.fld,
16148
16181
  baseField: dataField.baseField ?? 0,
16149
16182
  baseItem: dataField.baseItem ?? 0
16150
16183
  };
16151
- if (dataField.subtotal && dataField.subtotal !== "sum") attrs.subtotal = dataField.subtotal;
16152
- xmlStream.leafNode("dataField", attrs);
16184
+ if (dataField.subtotal && dataField.subtotal !== "sum") dfAttrs.subtotal = dataField.subtotal;
16185
+ xmlStream.leafNode("dataField", dfAttrs);
16186
+ }
16187
+ xmlStream.closeNode();
16188
+ }
16189
+ if (model.chartFormats && model.chartFormats.length > 0) {
16190
+ xmlStream.openNode("chartFormats", { count: model.chartFormats.length });
16191
+ for (const cf of model.chartFormats) {
16192
+ xmlStream.openNode("chartFormat", {
16193
+ chart: cf.chart,
16194
+ format: cf.format,
16195
+ series: cf.series ? "1" : void 0
16196
+ });
16197
+ if (cf.pivotAreaXml) xmlStream.writeXml(cf.pivotAreaXml);
16198
+ else xmlStream.writeXml(`<pivotArea type="data" outline="0" fieldPosition="0"><references count="1"><reference field="4294967294" count="1" selected="0"><x v="0"/></reference></references></pivotArea>`);
16199
+ xmlStream.closeNode();
16153
16200
  }
16154
16201
  xmlStream.closeNode();
16155
16202
  }
@@ -16161,47 +16208,35 @@ var ExcelTS = (function(exports) {
16161
16208
  showColStripes: "0",
16162
16209
  showLastColumn: "1"
16163
16210
  });
16164
- xmlStream.writeXml(`
16165
- <extLst>
16166
- <ext
16167
- uri="{962EF5D1-5CA2-4c93-8EF4-DBF5C05439D2}"
16168
- xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
16169
- >
16170
- <x14:pivotTableDefinition
16171
- hideValuesRow="1"
16172
- xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main"
16173
- />
16174
- </ext>
16175
- <ext
16176
- uri="{747A6164-185A-40DC-8AA5-F01512510D54}"
16177
- xmlns:xpdl="http://schemas.microsoft.com/office/spreadsheetml/2016/pivotdefaultlayout"
16178
- >
16179
- <xpdl:pivotTableDefinition16
16180
- EnabledSubtotalsDefault="0"
16181
- SubtotalsOnTopDefault="0"
16182
- />
16183
- </ext>
16184
- </extLst>
16185
- `);
16211
+ xmlStream.writeXml(`<extLst><ext uri="{962EF5D1-5CA2-4c93-8EF4-DBF5C05439D2}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"><x14:pivotTableDefinition hideValuesRow="1" xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main"/></ext><ext uri="{747A6164-185A-40DC-8AA5-F01512510D54}" xmlns:xpdl="http://schemas.microsoft.com/office/spreadsheetml/2016/pivotdefaultlayout"><xpdl:pivotTableDefinition16/></ext></extLst>`);
16186
16212
  xmlStream.closeNode();
16187
16213
  }
16188
16214
  /**
16215
+ * Render a row or column item element
16216
+ */
16217
+ renderRowColItem(xmlStream, item) {
16218
+ const attrs = {};
16219
+ if (item.t) attrs.t = item.t;
16220
+ if (item.x && item.x.length > 0) {
16221
+ xmlStream.openNode("i", attrs);
16222
+ for (const x of item.x) if (x.v && x.v !== 0) xmlStream.leafNode("x", { v: x.v });
16223
+ else xmlStream.leafNode("x");
16224
+ xmlStream.closeNode();
16225
+ } else xmlStream.leafNode("i", attrs);
16226
+ }
16227
+ /**
16189
16228
  * Render a loaded pivot field
16190
16229
  */
16191
16230
  renderPivotFieldLoaded(xmlStream, field) {
16192
- const attrs = {
16193
- compact: field.compact ? "1" : "0",
16194
- outline: field.outline ? "1" : "0",
16195
- showAll: field.showAll ? "1" : "0",
16196
- defaultSubtotal: field.defaultSubtotal ? "1" : "0"
16197
- };
16231
+ const attrs = {};
16198
16232
  if (field.axis) attrs.axis = field.axis;
16199
16233
  if (field.dataField) attrs.dataField = "1";
16234
+ attrs.showAll = field.showAll ? "1" : "0";
16200
16235
  if (field.items && field.items.length > 0) {
16201
16236
  xmlStream.openNode("pivotField", attrs);
16202
16237
  xmlStream.openNode("items", { count: field.items.length + 1 });
16203
16238
  for (const itemIndex of field.items) xmlStream.leafNode("item", { x: itemIndex });
16204
- xmlStream.writeXml("<item t=\"default\" />");
16239
+ xmlStream.writeXml("<item t=\"default\"/>");
16205
16240
  xmlStream.closeNode();
16206
16241
  xmlStream.closeNode();
16207
16242
  } else xmlStream.leafNode("pivotField", attrs);
@@ -16235,6 +16270,12 @@ var ExcelTS = (function(exports) {
16235
16270
  compact: attributes.compact === "1",
16236
16271
  compactData: attributes.compactData === "1",
16237
16272
  multipleFieldFilters: attributes.multipleFieldFilters === "1",
16273
+ outline: attributes.outline === "1",
16274
+ outlineData: attributes.outlineData === "1",
16275
+ chartFormat: attributes.chartFormat ? parseInt(attributes.chartFormat, 10) : void 0,
16276
+ rowItems: [],
16277
+ colItems: [],
16278
+ chartFormats: [],
16238
16279
  isLoaded: true
16239
16280
  };
16240
16281
  break;
@@ -16247,10 +16288,10 @@ var ExcelTS = (function(exports) {
16247
16288
  };
16248
16289
  break;
16249
16290
  case "pivotFields":
16250
- this.inPivotFields = true;
16291
+ this.state.inPivotFields = true;
16251
16292
  break;
16252
16293
  case "pivotField":
16253
- if (this.inPivotFields) this.currentPivotField = {
16294
+ if (this.state.inPivotFields) this.currentPivotField = {
16254
16295
  axis: attributes.axis,
16255
16296
  dataField: attributes.dataField === "1",
16256
16297
  items: [],
@@ -16261,35 +16302,77 @@ var ExcelTS = (function(exports) {
16261
16302
  };
16262
16303
  break;
16263
16304
  case "items":
16264
- if (this.currentPivotField) this.inItems = true;
16305
+ if (this.currentPivotField) this.state.inItems = true;
16265
16306
  break;
16266
16307
  case "item":
16267
- if (this.inItems && this.currentPivotField && attributes.x !== void 0) this.currentPivotField.items.push(parseInt(attributes.x, 10));
16308
+ if (this.state.inItems && this.currentPivotField && attributes.x !== void 0) this.currentPivotField.items.push(parseInt(attributes.x, 10));
16268
16309
  break;
16269
16310
  case "rowFields":
16270
- this.inRowFields = true;
16311
+ this.state.inRowFields = true;
16271
16312
  break;
16272
16313
  case "colFields":
16273
- this.inColFields = true;
16314
+ this.state.inColFields = true;
16274
16315
  break;
16275
16316
  case "dataFields":
16276
- this.inDataFields = true;
16317
+ this.state.inDataFields = true;
16277
16318
  break;
16278
16319
  case "rowItems":
16279
- this.inRowItems = true;
16320
+ this.state.inRowItems = true;
16280
16321
  break;
16281
16322
  case "colItems":
16282
- this.inColItems = true;
16323
+ this.state.inColItems = true;
16324
+ break;
16325
+ case "i":
16326
+ if (this.state.inRowItems && this.model) this.currentRowItem = {
16327
+ t: attributes.t,
16328
+ x: []
16329
+ };
16330
+ else if (this.state.inColItems && this.model) this.currentColItem = {
16331
+ t: attributes.t,
16332
+ x: []
16333
+ };
16334
+ break;
16335
+ case "x":
16336
+ if (this.state.inPivotArea) {
16337
+ const xAttrs = Object.entries(attributes).map(([k, v]) => `${k}="${v}"`).join(" ");
16338
+ this.pivotAreaXmlBuffer.push(xAttrs ? `<x ${xAttrs}/>` : "<x/>");
16339
+ } else if (this.currentRowItem) this.currentRowItem.x.push({ v: attributes.v ? parseInt(attributes.v, 10) : 0 });
16340
+ else if (this.currentColItem) this.currentColItem.x.push({ v: attributes.v ? parseInt(attributes.v, 10) : 0 });
16341
+ break;
16342
+ case "chartFormats":
16343
+ this.state.inChartFormats = true;
16344
+ break;
16345
+ case "chartFormat":
16346
+ if (this.state.inChartFormats && this.model) this.currentChartFormat = {
16347
+ chart: attributes.chart ? parseInt(attributes.chart, 10) : 0,
16348
+ format: attributes.format ? parseInt(attributes.format, 10) : 0,
16349
+ series: attributes.series === "1"
16350
+ };
16351
+ break;
16352
+ case "pivotArea":
16353
+ if (this.currentChartFormat) {
16354
+ this.state.inPivotArea = true;
16355
+ const attrsStr = Object.entries(attributes).map(([k, v]) => `${k}="${v}"`).join(" ");
16356
+ this.pivotAreaXmlBuffer = [attrsStr ? `<pivotArea ${attrsStr}>` : "<pivotArea>"];
16357
+ }
16358
+ break;
16359
+ case "references":
16360
+ case "reference":
16361
+ if (this.state.inPivotArea) {
16362
+ this.pivotAreaDepth++;
16363
+ const attrsStr = Object.entries(attributes).map(([k, v]) => `${k}="${v}"`).join(" ");
16364
+ this.pivotAreaXmlBuffer.push(`<${name}${attrsStr ? " " + attrsStr : ""}>`);
16365
+ }
16283
16366
  break;
16284
16367
  case "field":
16285
16368
  if (this.model) {
16286
16369
  const fieldIndex = parseInt(attributes.x || "0", 10);
16287
- if (this.inRowFields) this.model.rowFields.push(fieldIndex);
16288
- else if (this.inColFields) this.model.colFields.push(fieldIndex);
16370
+ if (this.state.inRowFields) this.model.rowFields.push(fieldIndex);
16371
+ else if (this.state.inColFields) this.model.colFields.push(fieldIndex);
16289
16372
  }
16290
16373
  break;
16291
16374
  case "dataField":
16292
- if (this.inDataFields && this.model) this.model.dataFields.push({
16375
+ if (this.state.inDataFields && this.model) this.model.dataFields.push({
16293
16376
  name: xmlDecode(attributes.name || ""),
16294
16377
  fld: parseInt(attributes.fld || "0", 10),
16295
16378
  baseField: attributes.baseField ? parseInt(attributes.baseField, 10) : 0,
@@ -16305,10 +16388,25 @@ var ExcelTS = (function(exports) {
16305
16388
  }
16306
16389
  parseText(_text) {}
16307
16390
  parseClose(name) {
16391
+ if (this.state.inPivotArea) {
16392
+ if (name === "pivotArea") {
16393
+ this.pivotAreaXmlBuffer.push("</pivotArea>");
16394
+ if (this.currentChartFormat) this.currentChartFormat.pivotAreaXml = this.pivotAreaXmlBuffer.join("");
16395
+ this.state.inPivotArea = false;
16396
+ this.pivotAreaXmlBuffer = [];
16397
+ this.pivotAreaDepth = 0;
16398
+ return true;
16399
+ } else if (name === "references" || name === "reference") {
16400
+ this.pivotAreaXmlBuffer.push(`</${name}>`);
16401
+ this.pivotAreaDepth--;
16402
+ return true;
16403
+ }
16404
+ return true;
16405
+ }
16308
16406
  switch (name) {
16309
16407
  case this.tag: return false;
16310
16408
  case "pivotFields":
16311
- this.inPivotFields = false;
16409
+ this.state.inPivotFields = false;
16312
16410
  break;
16313
16411
  case "pivotField":
16314
16412
  if (this.currentPivotField && this.model) {
@@ -16317,22 +16415,40 @@ var ExcelTS = (function(exports) {
16317
16415
  }
16318
16416
  break;
16319
16417
  case "items":
16320
- this.inItems = false;
16418
+ this.state.inItems = false;
16321
16419
  break;
16322
16420
  case "rowFields":
16323
- this.inRowFields = false;
16421
+ this.state.inRowFields = false;
16324
16422
  break;
16325
16423
  case "colFields":
16326
- this.inColFields = false;
16424
+ this.state.inColFields = false;
16327
16425
  break;
16328
16426
  case "dataFields":
16329
- this.inDataFields = false;
16427
+ this.state.inDataFields = false;
16330
16428
  break;
16331
16429
  case "rowItems":
16332
- this.inRowItems = false;
16430
+ this.state.inRowItems = false;
16333
16431
  break;
16334
16432
  case "colItems":
16335
- this.inColItems = false;
16433
+ this.state.inColItems = false;
16434
+ break;
16435
+ case "i":
16436
+ if (this.currentRowItem && this.model) {
16437
+ this.model.rowItems.push(this.currentRowItem);
16438
+ this.currentRowItem = null;
16439
+ } else if (this.currentColItem && this.model) {
16440
+ this.model.colItems.push(this.currentColItem);
16441
+ this.currentColItem = null;
16442
+ }
16443
+ break;
16444
+ case "chartFormats":
16445
+ this.state.inChartFormats = false;
16446
+ break;
16447
+ case "chartFormat":
16448
+ if (this.currentChartFormat && this.model) {
16449
+ this.model.chartFormats.push(this.currentChartFormat);
16450
+ this.currentChartFormat = null;
16451
+ }
16336
16452
  break;
16337
16453
  }
16338
16454
  return true;
@@ -20205,6 +20321,115 @@ var ExcelTS = (function(exports) {
20205
20321
  }
20206
20322
  };
20207
20323
 
20324
+ //#endregion
20325
+ //#region src/modules/excel/utils/passthrough-manager.ts
20326
+ /**
20327
+ * Content type definitions for passthrough files
20328
+ */
20329
+ const PASSTHROUGH_CONTENT_TYPES = new Map([
20330
+ [/^xl\/charts\/chart\d+\.xml$/, "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"],
20331
+ [/^xl\/charts\/style\d+\.xml$/, "application/vnd.ms-office.chartstyle+xml"],
20332
+ [/^xl\/charts\/colors\d+\.xml$/, "application/vnd.ms-office.chartcolorstyle+xml"]
20333
+ ]);
20334
+ /**
20335
+ * Passthrough path prefixes that should be preserved
20336
+ */
20337
+ const PASSTHROUGH_PREFIXES = ["xl/charts/"];
20338
+ /**
20339
+ * PassthroughManager handles storage and retrieval of passthrough files
20340
+ * that need to be preserved during Excel read/write cycles.
20341
+ */
20342
+ var PassthroughManager = class PassthroughManager {
20343
+ constructor() {
20344
+ this.files = /* @__PURE__ */ new Map();
20345
+ }
20346
+ /**
20347
+ * Check if a path should be treated as passthrough
20348
+ */
20349
+ static isPassthroughPath(path) {
20350
+ return PASSTHROUGH_PREFIXES.some((prefix) => path.startsWith(prefix));
20351
+ }
20352
+ /**
20353
+ * Get the content type for a passthrough file path
20354
+ * @returns Content type string or undefined if unknown
20355
+ */
20356
+ static getContentType(path) {
20357
+ if (path.startsWith("xl/charts/_rels/")) return;
20358
+ for (const [regex, contentType] of PASSTHROUGH_CONTENT_TYPES) if (regex.test(path)) return contentType;
20359
+ }
20360
+ /**
20361
+ * Add a file to passthrough storage
20362
+ */
20363
+ add(path, data) {
20364
+ this.files.set(path, data);
20365
+ }
20366
+ /**
20367
+ * Get a file from passthrough storage
20368
+ */
20369
+ get(path) {
20370
+ return this.files.get(path);
20371
+ }
20372
+ /**
20373
+ * Check if a file exists in passthrough storage
20374
+ */
20375
+ has(path) {
20376
+ return this.files.has(path);
20377
+ }
20378
+ /**
20379
+ * Get all stored paths
20380
+ */
20381
+ getPaths() {
20382
+ return [...this.files.keys()];
20383
+ }
20384
+ /**
20385
+ * Get all files as a record (for serialization)
20386
+ */
20387
+ toRecord() {
20388
+ const record = {};
20389
+ for (const [path, data] of this.files) record[path] = data;
20390
+ return record;
20391
+ }
20392
+ /**
20393
+ * Load files from a record (for deserialization)
20394
+ */
20395
+ fromRecord(record) {
20396
+ this.files.clear();
20397
+ for (const [path, data] of Object.entries(record)) this.files.set(path, data);
20398
+ }
20399
+ /**
20400
+ * Get content types for all stored files that have known types
20401
+ */
20402
+ getContentTypes() {
20403
+ const contentTypes = [];
20404
+ for (const path of this.files.keys()) {
20405
+ const contentType = PassthroughManager.getContentType(path);
20406
+ if (contentType) contentTypes.push({
20407
+ partName: path,
20408
+ contentType
20409
+ });
20410
+ }
20411
+ return contentTypes;
20412
+ }
20413
+ /**
20414
+ * Write all passthrough files to a ZIP writer
20415
+ */
20416
+ writeToZip(zip$1) {
20417
+ for (const [path, data] of this.files) zip$1.append(data, { name: path });
20418
+ }
20419
+ /**
20420
+ * Clear all stored files
20421
+ */
20422
+ clear() {
20423
+ this.files.clear();
20424
+ }
20425
+ /**
20426
+ * Get the number of stored files
20427
+ */
20428
+ get size() {
20429
+ return this.files.size;
20430
+ }
20431
+ };
20432
+
20208
20433
  //#endregion
20209
20434
  //#region src/modules/excel/xlsx/xlsx.browser.ts
20210
20435
  /**
@@ -20355,6 +20580,7 @@ var ExcelTS = (function(exports) {
20355
20580
  this.addDrawings(zip$1, model);
20356
20581
  this.addTables(zip$1, model);
20357
20582
  this.addPivotTables(zip$1, model);
20583
+ this.addPassthrough(zip$1, model);
20358
20584
  await Promise.all([this.addThemes(zip$1, model), this.addStyles(zip$1, model)]);
20359
20585
  await this.addFeaturePropertyBag(zip$1, model);
20360
20586
  await this.addMedia(zip$1, model);
@@ -20428,8 +20654,12 @@ var ExcelTS = (function(exports) {
20428
20654
  * This is the foundation for TRUE streaming reads on platforms that have a
20429
20655
  * streaming ZIP parser (e.g. Node.js `modules/archive` Parse).
20430
20656
  */
20431
- async loadFromZipEntries(entries, options) {
20432
- const model = {
20657
+ /**
20658
+ * Create an empty model for parsing XLSX files.
20659
+ * Shared by loadFromZipEntries and loadFromFiles.
20660
+ */
20661
+ createEmptyModel() {
20662
+ return {
20433
20663
  worksheets: [],
20434
20664
  worksheetHash: {},
20435
20665
  worksheetRels: [],
@@ -20438,6 +20668,7 @@ var ExcelTS = (function(exports) {
20438
20668
  mediaIndex: {},
20439
20669
  drawings: {},
20440
20670
  drawingRels: {},
20671
+ rawDrawings: {},
20441
20672
  comments: {},
20442
20673
  tables: {},
20443
20674
  vmlDrawings: {},
@@ -20445,8 +20676,93 @@ var ExcelTS = (function(exports) {
20445
20676
  pivotTableRels: {},
20446
20677
  pivotCacheDefinitions: {},
20447
20678
  pivotCacheDefinitionRels: {},
20448
- pivotCacheRecords: {}
20679
+ pivotCacheRecords: {},
20680
+ passthrough: {}
20449
20681
  };
20682
+ }
20683
+ /**
20684
+ * Collect all data from a stream into a single Uint8Array.
20685
+ * Reusable helper for passthrough and drawing processing.
20686
+ */
20687
+ async collectStreamData(stream) {
20688
+ const chunks = [];
20689
+ await new Promise((resolve, reject) => {
20690
+ stream.on("data", (chunk) => {
20691
+ if (typeof chunk === "string") chunks.push(new TextEncoder().encode(chunk));
20692
+ else if (chunk instanceof Uint8Array) chunks.push(chunk);
20693
+ else chunks.push(new Uint8Array(chunk));
20694
+ });
20695
+ stream.on("end", () => resolve());
20696
+ stream.on("error", reject);
20697
+ });
20698
+ return concatUint8Arrays$2(chunks);
20699
+ }
20700
+ /**
20701
+ * Check if a drawing has chart references in its relationships
20702
+ */
20703
+ drawingHasChartReference(drawing) {
20704
+ return drawing.rels && drawing.rels.some((rel) => rel.Target && rel.Target.includes("/charts/"));
20705
+ }
20706
+ /**
20707
+ * Check if a drawing rels list references charts.
20708
+ * Used to decide whether we need to keep raw drawing XML for passthrough.
20709
+ */
20710
+ drawingRelsHasChartReference(drawingRels) {
20711
+ return Array.isArray(drawingRels) && drawingRels.some((rel) => typeof rel?.Target === "string" && rel.Target.includes("/charts/"));
20712
+ }
20713
+ /**
20714
+ * Process a known OOXML entry (workbook, styles, shared strings, etc.)
20715
+ * Returns true if handled, false if should be passed to _processDefaultEntry
20716
+ */
20717
+ async _processKnownEntry(stream, model, entryName, options) {
20718
+ const sheetNo = getWorksheetNoFromWorksheetPath(entryName);
20719
+ if (sheetNo !== void 0) {
20720
+ await this._processWorksheetEntry(stream, model, sheetNo, options, entryName);
20721
+ return true;
20722
+ }
20723
+ switch (entryName) {
20724
+ case OOXML_PATHS.rootRels:
20725
+ model.globalRels = await this.parseRels(stream);
20726
+ return true;
20727
+ case OOXML_PATHS.xlWorkbook: {
20728
+ const workbook = await this.parseWorkbook(stream);
20729
+ model.sheets = workbook.sheets;
20730
+ model.definedNames = workbook.definedNames;
20731
+ model.views = workbook.views;
20732
+ model.properties = workbook.properties;
20733
+ model.calcProperties = workbook.calcProperties;
20734
+ model.pivotCaches = workbook.pivotCaches;
20735
+ return true;
20736
+ }
20737
+ case OOXML_PATHS.xlSharedStrings:
20738
+ model.sharedStrings = new SharedStringsXform();
20739
+ await model.sharedStrings.parseStream(stream);
20740
+ return true;
20741
+ case OOXML_PATHS.xlWorkbookRels:
20742
+ model.workbookRels = await this.parseRels(stream);
20743
+ return true;
20744
+ case OOXML_PATHS.docPropsApp: {
20745
+ const appProperties = await new AppXform().parseStream(stream);
20746
+ if (appProperties) {
20747
+ model.company = appProperties.company;
20748
+ model.manager = appProperties.manager;
20749
+ }
20750
+ return true;
20751
+ }
20752
+ case OOXML_PATHS.docPropsCore: {
20753
+ const coreProperties = await new CoreXform().parseStream(stream);
20754
+ Object.assign(model, coreProperties);
20755
+ return true;
20756
+ }
20757
+ case OOXML_PATHS.xlStyles:
20758
+ model.styles = new StylesXform();
20759
+ await model.styles.parseStream(stream);
20760
+ return true;
20761
+ default: return false;
20762
+ }
20763
+ }
20764
+ async loadFromZipEntries(entries, options) {
20765
+ const model = this.createEmptyModel();
20450
20766
  for await (const entry of entries) {
20451
20767
  let drained = false;
20452
20768
  const drainEntry = async () => {
@@ -20461,52 +20777,8 @@ var ExcelTS = (function(exports) {
20461
20777
  const entryName = normalizeZipPath(entry.name);
20462
20778
  const stream = entry.stream;
20463
20779
  try {
20464
- const sheetNo = getWorksheetNoFromWorksheetPath(entryName);
20465
- if (sheetNo !== void 0) {
20466
- await this._processWorksheetEntry(stream, model, sheetNo, options, entryName);
20467
- continue;
20468
- }
20469
- switch (entryName) {
20470
- case OOXML_PATHS.rootRels:
20471
- model.globalRels = await this.parseRels(stream);
20472
- break;
20473
- case OOXML_PATHS.xlWorkbook: {
20474
- const workbook = await this.parseWorkbook(stream);
20475
- model.sheets = workbook.sheets;
20476
- model.definedNames = workbook.definedNames;
20477
- model.views = workbook.views;
20478
- model.properties = workbook.properties;
20479
- model.calcProperties = workbook.calcProperties;
20480
- model.pivotCaches = workbook.pivotCaches;
20481
- break;
20482
- }
20483
- case OOXML_PATHS.xlSharedStrings:
20484
- model.sharedStrings = new SharedStringsXform();
20485
- await model.sharedStrings.parseStream(stream);
20486
- break;
20487
- case OOXML_PATHS.xlWorkbookRels:
20488
- model.workbookRels = await this.parseRels(stream);
20489
- break;
20490
- case OOXML_PATHS.docPropsApp: {
20491
- const appProperties = await new AppXform().parseStream(stream);
20492
- if (appProperties) {
20493
- model.company = appProperties.company;
20494
- model.manager = appProperties.manager;
20495
- }
20496
- break;
20497
- }
20498
- case OOXML_PATHS.docPropsCore: {
20499
- const coreProperties = await new CoreXform().parseStream(stream);
20500
- Object.assign(model, coreProperties);
20501
- break;
20502
- }
20503
- case OOXML_PATHS.xlStyles:
20504
- model.styles = new StylesXform();
20505
- await model.styles.parseStream(stream);
20506
- break;
20507
- default:
20508
- if (!await this._processDefaultEntry(stream, model, entryName)) await drainEntry();
20509
- break;
20780
+ if (!await this._processKnownEntry(stream, model, entryName, options)) {
20781
+ if (!await this._processDefaultEntry(stream, model, entryName)) await drainEntry();
20510
20782
  }
20511
20783
  } finally {
20512
20784
  try {
@@ -20595,6 +20867,10 @@ var ExcelTS = (function(exports) {
20595
20867
  drawingXform.reconcile(drawing, drawingOptions);
20596
20868
  }
20597
20869
  });
20870
+ if (model.rawDrawings && model.drawingRels) for (const name of Object.keys(model.rawDrawings)) {
20871
+ const drawingRel = model.drawingRels[name];
20872
+ if (drawingRel && !this.drawingRelsHasChartReference(drawingRel)) delete model.rawDrawings[name];
20873
+ }
20598
20874
  const tableOptions = { styles: model.styles };
20599
20875
  Object.values(model.tables).forEach((table) => {
20600
20876
  tableXform.reconcile(table, tableOptions);
@@ -20607,6 +20883,7 @@ var ExcelTS = (function(exports) {
20607
20883
  mediaIndex: model.mediaIndex,
20608
20884
  date1904: model.properties && model.properties.date1904,
20609
20885
  drawings: model.drawings,
20886
+ drawingRels: model.drawingRels,
20610
20887
  comments: model.comments,
20611
20888
  tables: model.tables,
20612
20889
  vmlDrawings: model.vmlDrawings,
@@ -20763,8 +21040,12 @@ var ExcelTS = (function(exports) {
20763
21040
  }
20764
21041
  }
20765
21042
  async _processDrawingEntry(entry, model, name) {
20766
- const drawing = await new DrawingXform().parseStream(entry);
21043
+ const rawData = await this.collectStreamData(entry);
21044
+ const xform$1 = new DrawingXform();
21045
+ const xmlString = this.bufferToString(rawData);
21046
+ const drawing = await xform$1.parseStream(this.createTextStream(xmlString));
20767
21047
  model.drawings[name] = drawing;
21048
+ model.rawDrawings[name] = rawData;
20768
21049
  }
20769
21050
  async _processDrawingRelsEntry(entry, model, name) {
20770
21051
  const relationships = await new RelationshipsXform().parseStream(entry);
@@ -20819,24 +21100,7 @@ var ExcelTS = (function(exports) {
20819
21100
  if (cacheRecords) model.pivotCacheRecords[name] = cacheRecords;
20820
21101
  }
20821
21102
  async loadFromFiles(zipData, options) {
20822
- const model = {
20823
- worksheets: [],
20824
- worksheetHash: {},
20825
- worksheetRels: [],
20826
- themes: {},
20827
- media: [],
20828
- mediaIndex: {},
20829
- drawings: {},
20830
- drawingRels: {},
20831
- comments: {},
20832
- tables: {},
20833
- vmlDrawings: {},
20834
- pivotTables: {},
20835
- pivotTableRels: {},
20836
- pivotCacheDefinitions: {},
20837
- pivotCacheDefinitionRels: {},
20838
- pivotCacheRecords: {}
20839
- };
21103
+ const model = this.createEmptyModel();
20840
21104
  const entries = Object.keys(zipData).map((name) => ({
20841
21105
  name,
20842
21106
  dir: name.endsWith("/"),
@@ -20845,48 +21109,7 @@ var ExcelTS = (function(exports) {
20845
21109
  for (const entry of entries) if (!entry.dir) {
20846
21110
  const entryName = normalizeZipPath(entry.name);
20847
21111
  const stream = isBinaryEntryPath(entryName) ? this.createBinaryStream(entry.data) : this.createTextStream(this.bufferToString(entry.data));
20848
- const sheetNo = getWorksheetNoFromWorksheetPath(entryName);
20849
- if (sheetNo !== void 0) await this._processWorksheetEntry(stream, model, sheetNo, options, entryName);
20850
- else switch (entryName) {
20851
- case OOXML_PATHS.rootRels:
20852
- model.globalRels = await this.parseRels(stream);
20853
- break;
20854
- case OOXML_PATHS.xlWorkbook: {
20855
- const workbook = await this.parseWorkbook(stream);
20856
- model.sheets = workbook.sheets;
20857
- model.definedNames = workbook.definedNames;
20858
- model.views = workbook.views;
20859
- model.properties = workbook.properties;
20860
- model.calcProperties = workbook.calcProperties;
20861
- model.pivotCaches = workbook.pivotCaches;
20862
- break;
20863
- }
20864
- case OOXML_PATHS.xlSharedStrings:
20865
- model.sharedStrings = new SharedStringsXform();
20866
- await model.sharedStrings.parseStream(stream);
20867
- break;
20868
- case OOXML_PATHS.xlWorkbookRels:
20869
- model.workbookRels = await this.parseRels(stream);
20870
- break;
20871
- case OOXML_PATHS.docPropsApp: {
20872
- const appProperties = await new AppXform().parseStream(stream);
20873
- if (appProperties) {
20874
- model.company = appProperties.company;
20875
- model.manager = appProperties.manager;
20876
- }
20877
- break;
20878
- }
20879
- case OOXML_PATHS.docPropsCore: {
20880
- const coreProperties = await new CoreXform().parseStream(stream);
20881
- Object.assign(model, coreProperties);
20882
- break;
20883
- }
20884
- case OOXML_PATHS.xlStyles:
20885
- model.styles = new StylesXform();
20886
- await model.styles.parseStream(stream);
20887
- break;
20888
- default: await this._processDefaultEntry(stream, model, entryName);
20889
- }
21112
+ if (!await this._processKnownEntry(stream, model, entryName, options)) await this._processDefaultEntry(stream, model, entryName, entry.data);
20890
21113
  }
20891
21114
  this.reconcile(model, options);
20892
21115
  this.workbook.model = model;
@@ -20894,11 +21117,11 @@ var ExcelTS = (function(exports) {
20894
21117
  }
20895
21118
  /**
20896
21119
  * Process default entries (drawings, comments, tables, etc.)
21120
+ * @param rawData Optional raw entry data for passthrough preservation (used by loadFromFiles)
20897
21121
  */
20898
- async _processDefaultEntry(stream, model, entryName) {
20899
- const worksheetRelsSheetNo = getWorksheetNoFromWorksheetRelsPath(entryName);
20900
- if (worksheetRelsSheetNo !== void 0) {
20901
- const sheetNo = worksheetRelsSheetNo;
21122
+ async _processDefaultEntry(stream, model, entryName, rawData) {
21123
+ const sheetNo = getWorksheetNoFromWorksheetRelsPath(entryName);
21124
+ if (sheetNo !== void 0) {
20902
21125
  await this._processWorksheetRelsEntry(stream, model, sheetNo);
20903
21126
  return true;
20904
21127
  }
@@ -20910,6 +21133,7 @@ var ExcelTS = (function(exports) {
20910
21133
  const drawingName = getDrawingNameFromPath(entryName);
20911
21134
  if (drawingName) {
20912
21135
  await this._processDrawingEntry(stream, model, drawingName);
21136
+ if (rawData) model.rawDrawings[drawingName] = rawData;
20913
21137
  return true;
20914
21138
  }
20915
21139
  const drawingRelsName = getDrawingNameFromRelsPath(entryName);
@@ -20962,8 +21186,21 @@ var ExcelTS = (function(exports) {
20962
21186
  await this._processPivotCacheRecordsEntry(stream, model, pivotCacheRecordsName);
20963
21187
  return true;
20964
21188
  }
21189
+ if (PassthroughManager.isPassthroughPath(entryName)) {
21190
+ if (rawData) model.passthrough[entryName] = rawData;
21191
+ else await this._processPassthroughEntry(stream, model, entryName);
21192
+ return true;
21193
+ }
20965
21194
  return false;
20966
21195
  }
21196
+ /**
21197
+ * Store a passthrough file for preservation during read/write cycles.
21198
+ * These files are not parsed but stored as raw bytes to be written back unchanged.
21199
+ */
21200
+ async _processPassthroughEntry(stream, model, entryName) {
21201
+ const data = await this.collectStreamData(stream);
21202
+ model.passthrough[entryName] = data;
21203
+ }
20967
21204
  async addContentTypes(zip$1, model) {
20968
21205
  const xml = new ContentTypesXform().toXml(model);
20969
21206
  zip$1.append(xml, { name: OOXML_PATHS.contentTypes });
@@ -21100,14 +21337,29 @@ var ExcelTS = (function(exports) {
21100
21337
  addDrawings(zip$1, model) {
21101
21338
  const drawingXform = new DrawingXform();
21102
21339
  const relsXform = new RelationshipsXform();
21340
+ const rawDrawings = model.rawDrawings || {};
21103
21341
  model.worksheets.forEach((worksheet) => {
21104
21342
  const { drawing } = worksheet;
21105
21343
  if (drawing) {
21106
- drawingXform.prepare(drawing);
21107
- let xml = drawingXform.toXml(drawing);
21108
- zip$1.append(xml, { name: drawingPath(drawing.name) });
21109
- xml = relsXform.toXml(drawing.rels);
21110
- zip$1.append(xml, { name: drawingRelsPath(drawing.name) });
21344
+ if (this.drawingHasChartReference(drawing) && rawDrawings[drawing.name]) zip$1.append(rawDrawings[drawing.name], { name: drawingPath(drawing.name) });
21345
+ else {
21346
+ const filteredAnchors = (drawing.anchors || []).filter((a) => {
21347
+ if (a == null) return false;
21348
+ if (a.range?.br && a.shape) return true;
21349
+ if (!a.br && !a.picture) return false;
21350
+ if (a.br && !a.picture && !a.shape) return false;
21351
+ return true;
21352
+ });
21353
+ const drawingForWrite = drawing.anchors ? {
21354
+ ...drawing,
21355
+ anchors: filteredAnchors
21356
+ } : drawing;
21357
+ drawingXform.prepare(drawingForWrite);
21358
+ const xml = drawingXform.toXml(drawingForWrite);
21359
+ zip$1.append(xml, { name: drawingPath(drawing.name) });
21360
+ }
21361
+ const relsXml = relsXform.toXml(drawing.rels);
21362
+ zip$1.append(relsXml, { name: drawingRelsPath(drawing.name) });
21111
21363
  }
21112
21364
  });
21113
21365
  }
@@ -21122,6 +21374,15 @@ var ExcelTS = (function(exports) {
21122
21374
  });
21123
21375
  });
21124
21376
  }
21377
+ /**
21378
+ * Write passthrough files (charts, etc.) that were preserved during read.
21379
+ * These files are written back unchanged to preserve unsupported features.
21380
+ */
21381
+ addPassthrough(zip$1, model) {
21382
+ const passthroughManager = new PassthroughManager();
21383
+ passthroughManager.fromRecord(model.passthrough || {});
21384
+ passthroughManager.writeToZip(zip$1);
21385
+ }
21125
21386
  addPivotTables(zip$1, model) {
21126
21387
  if (!model.pivotTables.length) return;
21127
21388
  const pivotCacheRecordsXform = new PivotCacheRecordsXform();
@@ -21204,6 +21465,10 @@ var ExcelTS = (function(exports) {
21204
21465
  worksheetXform.prepare(worksheet, worksheetOptions);
21205
21466
  });
21206
21467
  model.hasCheckboxes = model.styles.hasCheckboxes;
21468
+ const passthrough = model.passthrough || {};
21469
+ const passthroughManager = new PassthroughManager();
21470
+ passthroughManager.fromRecord(passthrough);
21471
+ model.passthroughContentTypes = passthroughManager.getContentTypes();
21207
21472
  }
21208
21473
  };
21209
21474
 
@@ -22405,7 +22670,7 @@ var ExcelTS = (function(exports) {
22405
22670
  else str = String(content);
22406
22671
  const worksheet = this.workbook.addWorksheet(options?.sheetName);
22407
22672
  const dateFormats = options?.dateFormats ?? DEFAULT_DATE_FORMATS;
22408
- const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator ?? options?.parserOptions?.decimalSeparator });
22673
+ const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator });
22409
22674
  const rows = parseCsv(str, options?.parserOptions);
22410
22675
  for (const row of rows) worksheet.addRow(row.map(map));
22411
22676
  return worksheet;
@@ -22433,7 +22698,7 @@ var ExcelTS = (function(exports) {
22433
22698
  async read(stream, options) {
22434
22699
  const worksheet = this.workbook.addWorksheet(options?.sheetName);
22435
22700
  const dateFormats = options?.dateFormats ?? DEFAULT_DATE_FORMATS;
22436
- const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator ?? options?.parserOptions?.decimalSeparator });
22701
+ const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator });
22437
22702
  const parser = new CsvParserStream(options?.parserOptions);
22438
22703
  return new Promise((resolve, reject) => {
22439
22704
  parser.on("data", (row) => worksheet.addRow(row.map(map)));
@@ -22485,7 +22750,7 @@ var ExcelTS = (function(exports) {
22485
22750
  createWriteStream(options) {
22486
22751
  const worksheet = this.workbook.addWorksheet(options?.sheetName);
22487
22752
  const dateFormats = options?.dateFormats ?? DEFAULT_DATE_FORMATS;
22488
- const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator ?? options?.parserOptions?.decimalSeparator });
22753
+ const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator });
22489
22754
  const parser = new CsvParserStream(options?.parserOptions);
22490
22755
  parser.on("data", (row) => worksheet.addRow(row.map(map)));
22491
22756
  return parser;
@@ -25486,6 +25751,8 @@ onmessage = async (ev) => {
25486
25751
  this.views = [];
25487
25752
  this.media = [];
25488
25753
  this.pivotTables = [];
25754
+ this._passthrough = {};
25755
+ this._rawDrawings = {};
25489
25756
  this._definedNames = new DefinedNames();
25490
25757
  }
25491
25758
  /**
@@ -25658,7 +25925,9 @@ onmessage = async (ev) => {
25658
25925
  themes: this._themes,
25659
25926
  media: this.media,
25660
25927
  pivotTables: this.pivotTables,
25661
- calcProperties: this.calcProperties
25928
+ calcProperties: this.calcProperties,
25929
+ passthrough: this._passthrough,
25930
+ rawDrawings: this._rawDrawings
25662
25931
  };
25663
25932
  }
25664
25933
  set model(value) {
@@ -25697,6 +25966,8 @@ onmessage = async (ev) => {
25697
25966
  this._themes = value.themes;
25698
25967
  this.media = value.media || [];
25699
25968
  this.pivotTables = value.pivotTables || value.loadedPivotTables || [];
25969
+ this._passthrough = value.passthrough || {};
25970
+ this._rawDrawings = value.rawDrawings || {};
25700
25971
  }
25701
25972
  };
25702
25973