@cj-tech-master/excelts 4.2.3 → 5.0.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.
Files changed (51) 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/parse-sax.d.ts +0 -3
  4. package/dist/browser/modules/excel/utils/parse-sax.js +13 -32
  5. package/dist/browser/modules/excel/utils/passthrough-manager.d.ts +77 -0
  6. package/dist/browser/modules/excel/utils/passthrough-manager.js +129 -0
  7. package/dist/browser/modules/excel/workbook.d.ts +8 -0
  8. package/dist/browser/modules/excel/workbook.js +9 -1
  9. package/dist/browser/modules/excel/worksheet.d.ts +4 -0
  10. package/dist/browser/modules/excel/worksheet.js +4 -1
  11. package/dist/browser/modules/excel/xlsx/xform/base-xform.js +68 -1
  12. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +16 -10
  13. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +34 -11
  14. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +256 -86
  15. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +38 -11
  16. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +36 -1
  17. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +213 -131
  18. package/dist/browser/modules/stream/streams.browser.js +0 -3
  19. package/dist/cjs/modules/csv/csv.browser.js +3 -3
  20. package/dist/cjs/modules/excel/utils/parse-sax.js +13 -32
  21. package/dist/cjs/modules/excel/utils/passthrough-manager.js +133 -0
  22. package/dist/cjs/modules/excel/workbook.js +9 -1
  23. package/dist/cjs/modules/excel/worksheet.js +4 -1
  24. package/dist/cjs/modules/excel/xlsx/xform/base-xform.js +68 -1
  25. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +16 -10
  26. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +256 -86
  27. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +38 -11
  28. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +213 -131
  29. package/dist/cjs/modules/stream/streams.browser.js +0 -3
  30. package/dist/esm/modules/csv/csv.browser.js +3 -3
  31. package/dist/esm/modules/excel/utils/parse-sax.js +13 -32
  32. package/dist/esm/modules/excel/utils/passthrough-manager.js +129 -0
  33. package/dist/esm/modules/excel/workbook.js +9 -1
  34. package/dist/esm/modules/excel/worksheet.js +4 -1
  35. package/dist/esm/modules/excel/xlsx/xform/base-xform.js +68 -1
  36. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +16 -10
  37. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +256 -86
  38. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +38 -11
  39. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +213 -131
  40. package/dist/esm/modules/stream/streams.browser.js +0 -3
  41. package/dist/iife/excelts.iife.js +571 -268
  42. package/dist/iife/excelts.iife.js.map +1 -1
  43. package/dist/iife/excelts.iife.min.js +25 -52
  44. package/dist/types/modules/csv/csv-core.d.ts +0 -9
  45. package/dist/types/modules/excel/utils/parse-sax.d.ts +0 -3
  46. package/dist/types/modules/excel/utils/passthrough-manager.d.ts +77 -0
  47. package/dist/types/modules/excel/workbook.d.ts +8 -0
  48. package/dist/types/modules/excel/worksheet.d.ts +4 -0
  49. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +34 -11
  50. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +36 -1
  51. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @cj-tech-master/excelts v4.2.3
2
+ * @cj-tech-master/excelts v5.0.0
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
@@ -3951,7 +3951,6 @@ var ExcelTS = (function(exports) {
3951
3951
  yield chunk;
3952
3952
  }
3953
3953
  }
3954
- if (streamError) throw streamError;
3955
3954
  } finally {
3956
3955
  this.off("data", dataHandler);
3957
3956
  this.off("end", endHandler);
@@ -6217,7 +6216,8 @@ var ExcelTS = (function(exports) {
6217
6216
  tables: Object.values(this.tables).map((table) => table.model),
6218
6217
  pivotTables: this.pivotTables,
6219
6218
  conditionalFormattings: this.conditionalFormattings,
6220
- formControls: this.formControls.map((fc) => fc.model)
6219
+ formControls: this.formControls.map((fc) => fc.model),
6220
+ drawing: this._drawing
6221
6221
  };
6222
6222
  model.cols = Column.toModel(this.columns || []);
6223
6223
  const rows = model.rows = [];
@@ -6272,6 +6272,7 @@ var ExcelTS = (function(exports) {
6272
6272
  this.pivotTables = value.pivotTables;
6273
6273
  this.conditionalFormattings = value.conditionalFormattings;
6274
6274
  this.formControls = [];
6275
+ this._drawing = value.drawing;
6275
6276
  }
6276
6277
  };
6277
6278
 
@@ -6764,8 +6765,6 @@ var ExcelTS = (function(exports) {
6764
6765
  quot: "\"",
6765
6766
  apos: "'"
6766
6767
  };
6767
- const HAN_CELL_PREFIXES = /^(ep|cp|dc|dcterms|dcmitype|vt):/;
6768
- const SPREADSHEETML_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
6769
6768
  const S_TEXT = 0;
6770
6769
  const S_OPEN_WAKA = 1;
6771
6770
  const S_OPEN_WAKA_BANG = 2;
@@ -6817,7 +6816,6 @@ var ExcelTS = (function(exports) {
6817
6816
  this.positionAtNewLine = 0;
6818
6817
  this.chunkPosition = 0;
6819
6818
  this.ENTITIES = { ...XML_ENTITIES };
6820
- this.nsPrefix = null;
6821
6819
  this.trackPosition = opt?.position !== false;
6822
6820
  this.fileName = opt?.fileName;
6823
6821
  this.fragment = opt?.fragment ?? false;
@@ -6852,11 +6850,6 @@ var ExcelTS = (function(exports) {
6852
6850
  this.chunk = "";
6853
6851
  this.i = 0;
6854
6852
  this.prevI = 0;
6855
- this.nsPrefix = null;
6856
- }
6857
- stripNsPrefix(name) {
6858
- const n = name.replace(HAN_CELL_PREFIXES, "");
6859
- return this.nsPrefix && n.startsWith(this.nsPrefix + ":") ? n.slice(this.nsPrefix.length + 1) : n;
6860
6853
  }
6861
6854
  on(name, handler) {
6862
6855
  switch (name) {
@@ -7196,7 +7189,7 @@ var ExcelTS = (function(exports) {
7196
7189
  return;
7197
7190
  }
7198
7191
  this.tag = {
7199
- name: this.stripNsPrefix(this.name),
7192
+ name: this.name,
7200
7193
  attributes: Object.create(null),
7201
7194
  isSelfClosing: false
7202
7195
  };
@@ -7492,7 +7485,8 @@ var ExcelTS = (function(exports) {
7492
7485
  openTag() {
7493
7486
  const tag = this.tag;
7494
7487
  tag.isSelfClosing = false;
7495
- this.processAttributes(tag);
7488
+ for (const { name, value } of this.attribList) tag.attributes[name] = value;
7489
+ this.attribList = [];
7496
7490
  this.openTagHandler?.(tag);
7497
7491
  this.tags.push(tag);
7498
7492
  this.name = "";
@@ -7501,26 +7495,16 @@ var ExcelTS = (function(exports) {
7501
7495
  openSelfClosingTag() {
7502
7496
  const tag = this.tag;
7503
7497
  tag.isSelfClosing = true;
7504
- this.processAttributes(tag);
7498
+ for (const { name, value } of this.attribList) tag.attributes[name] = value;
7499
+ this.attribList = [];
7505
7500
  this.openTagHandler?.(tag);
7506
7501
  this.closeTagHandler?.(tag);
7507
7502
  if (this.tags.length === 0) this.closedRoot = true;
7508
7503
  this.name = "";
7509
7504
  this.state = S_TEXT;
7510
7505
  }
7511
- processAttributes(tag) {
7512
- for (const { name, value } of this.attribList) {
7513
- tag.attributes[name] = value;
7514
- if (name.startsWith("xmlns:") && value === SPREADSHEETML_NS) {
7515
- this.nsPrefix = name.slice(6);
7516
- tag.name = this.stripNsPrefix(tag.name);
7517
- }
7518
- }
7519
- this.attribList = [];
7520
- }
7521
7506
  closeTag() {
7522
- const { tags } = this;
7523
- const name = this.stripNsPrefix(this.name);
7507
+ const { tags, name } = this;
7524
7508
  this.state = S_TEXT;
7525
7509
  this.name = "";
7526
7510
  if (name === "") {
@@ -7595,6 +7579,30 @@ var ExcelTS = (function(exports) {
7595
7579
 
7596
7580
  //#endregion
7597
7581
  //#region src/modules/excel/xlsx/xform/base-xform.ts
7582
+ const HAN_CELL_PREFIXES = new Set([
7583
+ "ep",
7584
+ "cp",
7585
+ "dc",
7586
+ "dcterms",
7587
+ "dcmitype",
7588
+ "vt"
7589
+ ]);
7590
+ const SPREADSHEETML_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
7591
+ function detectHanCellPrefix(tagName, attrs) {
7592
+ for (const key in attrs) if (key.length > 6 && key.startsWith("xmlns:")) {
7593
+ const prefix = key.slice(6);
7594
+ if (attrs[key] === SPREADSHEETML_NS) return prefix;
7595
+ if (HAN_CELL_PREFIXES.has(prefix)) return null;
7596
+ }
7597
+ const i = tagName.indexOf(":");
7598
+ return i !== -1 && HAN_CELL_PREFIXES.has(tagName.slice(0, i)) ? null : void 0;
7599
+ }
7600
+ function stripPrefix(name, nsPrefix) {
7601
+ const i = name.indexOf(":");
7602
+ if (i === -1) return name;
7603
+ const p = name.slice(0, i);
7604
+ return p === nsPrefix || HAN_CELL_PREFIXES.has(p) ? name.slice(i + 1) : name;
7605
+ }
7598
7606
  var BaseXform = class BaseXform {
7599
7607
  prepare(_model, _options) {}
7600
7608
  render(_xmlStream, _model) {}
@@ -7617,12 +7625,38 @@ var ExcelTS = (function(exports) {
7617
7625
  async parse(saxParser) {
7618
7626
  let done = false;
7619
7627
  let finalModel;
7628
+ let nsMode = 0;
7629
+ let nsPrefix = null;
7620
7630
  for await (const events of saxParser) {
7621
7631
  if (done) continue;
7622
- for (const { eventType, value } of events) if (eventType === "opentag") this.parseOpen(value);
7623
- else if (eventType === "text") this.parseText(value);
7632
+ for (const { eventType, value } of events) if (eventType === "opentag") {
7633
+ if (nsMode === 1) {
7634
+ this.parseOpen(value);
7635
+ continue;
7636
+ }
7637
+ if (nsMode === 0) {
7638
+ const prefix = detectHanCellPrefix(value.name, value.attributes);
7639
+ if (prefix === void 0) {
7640
+ nsMode = 1;
7641
+ this.parseOpen(value);
7642
+ continue;
7643
+ }
7644
+ nsMode = 2;
7645
+ nsPrefix = prefix;
7646
+ }
7647
+ value.name = stripPrefix(value.name, nsPrefix);
7648
+ this.parseOpen(value);
7649
+ } else if (eventType === "text") this.parseText(value);
7624
7650
  else if (eventType === "closetag") {
7625
- if (!this.parseClose(value.name)) {
7651
+ if (nsMode === 1) {
7652
+ if (!this.parseClose(value.name)) {
7653
+ done = true;
7654
+ finalModel = this.model;
7655
+ break;
7656
+ }
7657
+ continue;
7658
+ }
7659
+ if (!this.parseClose(stripPrefix(value.name, nsPrefix))) {
7626
7660
  done = true;
7627
7661
  finalModel = this.model;
7628
7662
  break;
@@ -10407,28 +10441,26 @@ var ExcelTS = (function(exports) {
10407
10441
  ContentType: "application/vnd.openxmlformats-officedocument.drawing+xml"
10408
10442
  });
10409
10443
  });
10410
- if (model.commentRefs) {
10411
- xmlStream.leafNode("Default", {
10412
- Extension: "vml",
10413
- ContentType: "application/vnd.openxmlformats-officedocument.vmlDrawing"
10414
- });
10415
- model.commentRefs.forEach(({ commentName }) => {
10416
- xmlStream.leafNode("Override", {
10417
- PartName: toContentTypesPartName(commentsPathFromName(commentName)),
10418
- ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"
10419
- });
10420
- });
10421
- }
10422
- if (model.formControlRefs) {
10423
- if (!model.commentRefs) xmlStream.leafNode("Default", {
10424
- Extension: "vml",
10425
- ContentType: "application/vnd.openxmlformats-officedocument.vmlDrawing"
10426
- });
10427
- for (const ctrlPropId of model.formControlRefs) xmlStream.leafNode("Override", {
10428
- PartName: toContentTypesPartName(ctrlPropPath(ctrlPropId)),
10429
- ContentType: "application/vnd.ms-excel.controlproperties+xml"
10444
+ const hasComments = model.commentRefs && model.commentRefs.length > 0;
10445
+ const hasFormControls = model.formControlRefs && model.formControlRefs.length > 0;
10446
+ if (hasComments || hasFormControls) xmlStream.leafNode("Default", {
10447
+ Extension: "vml",
10448
+ ContentType: "application/vnd.openxmlformats-officedocument.vmlDrawing"
10449
+ });
10450
+ if (hasComments) model.commentRefs.forEach(({ commentName }) => {
10451
+ xmlStream.leafNode("Override", {
10452
+ PartName: toContentTypesPartName(commentsPathFromName(commentName)),
10453
+ ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"
10430
10454
  });
10431
- }
10455
+ });
10456
+ if (hasFormControls) for (const ctrlPropId of model.formControlRefs) xmlStream.leafNode("Override", {
10457
+ PartName: toContentTypesPartName(ctrlPropPath(ctrlPropId)),
10458
+ ContentType: "application/vnd.ms-excel.controlproperties+xml"
10459
+ });
10460
+ if (model.passthroughContentTypes) for (const { partName, contentType } of model.passthroughContentTypes) xmlStream.leafNode("Override", {
10461
+ PartName: toContentTypesPartName(partName),
10462
+ ContentType: contentType
10463
+ });
10432
10464
  xmlStream.leafNode("Override", {
10433
10465
  PartName: toContentTypesPartName(OOXML_PATHS.docPropsCore),
10434
10466
  ContentType: "application/vnd.openxmlformats-package.core-properties+xml"
@@ -13863,6 +13895,17 @@ var ExcelTS = (function(exports) {
13863
13895
  vmlDrawing: `vmlDrawing${model.id}`
13864
13896
  });
13865
13897
  }
13898
+ if (model.drawing && model.drawing.anchors) {
13899
+ const drawing = model.drawing;
13900
+ drawing.rId = nextRid(rels);
13901
+ if (!drawing.name) drawing.name = `drawing${++options.drawingsCount}`;
13902
+ options.drawings.push(drawing);
13903
+ rels.push({
13904
+ Id: drawing.rId,
13905
+ Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
13906
+ Target: drawingRelTargetFromWorksheet(drawing.name)
13907
+ });
13908
+ }
13866
13909
  const drawingRelsHash = [];
13867
13910
  let bookImage;
13868
13911
  model.media.forEach((medium) => {
@@ -14200,17 +14243,25 @@ var ExcelTS = (function(exports) {
14200
14243
  const match = rels[model.drawing.rId].Target.match(/\/drawings\/([a-zA-Z0-9]+)[.][a-zA-Z]{3,4}$/);
14201
14244
  if (match) {
14202
14245
  const drawingName = match[1];
14203
- options.drawings[drawingName].anchors.forEach((anchor) => {
14204
- if (anchor.medium) {
14205
- const image = {
14206
- type: "image",
14207
- imageId: anchor.medium.index,
14208
- range: anchor.range,
14209
- hyperlinks: anchor.picture.hyperlinks
14210
- };
14211
- model.media.push(image);
14212
- }
14213
- });
14246
+ const drawing = options.drawings[drawingName];
14247
+ if (drawing) {
14248
+ model.drawing = {
14249
+ ...drawing,
14250
+ name: drawingName,
14251
+ rels: options.drawingRels?.[drawingName] || drawing.rels || []
14252
+ };
14253
+ drawing.anchors.forEach((anchor) => {
14254
+ if (anchor.medium) {
14255
+ const image = {
14256
+ type: "image",
14257
+ imageId: anchor.medium.index,
14258
+ range: anchor.range,
14259
+ hyperlinks: anchor.picture.hyperlinks
14260
+ };
14261
+ model.media.push(image);
14262
+ }
14263
+ });
14264
+ }
14214
14265
  }
14215
14266
  }
14216
14267
  const backgroundRel = model.background && rels[model.background.rId];
@@ -15962,18 +16013,27 @@ var ExcelTS = (function(exports) {
15962
16013
  var PivotTableXform = class PivotTableXform extends BaseXform {
15963
16014
  constructor() {
15964
16015
  super();
16016
+ this.state = {
16017
+ inPivotFields: false,
16018
+ inRowFields: false,
16019
+ inColFields: false,
16020
+ inDataFields: false,
16021
+ inRowItems: false,
16022
+ inColItems: false,
16023
+ inLocation: false,
16024
+ inItems: false,
16025
+ inPivotTableStyleInfo: false,
16026
+ inChartFormats: false,
16027
+ inPivotArea: false
16028
+ };
16029
+ this.currentPivotField = null;
16030
+ this.currentRowItem = null;
16031
+ this.currentColItem = null;
16032
+ this.currentChartFormat = null;
16033
+ this.pivotAreaXmlBuffer = [];
16034
+ this.pivotAreaDepth = 0;
15965
16035
  this.map = {};
15966
16036
  this.model = null;
15967
- this.inPivotFields = false;
15968
- this.inRowFields = false;
15969
- this.inColFields = false;
15970
- this.inDataFields = false;
15971
- this.inRowItems = false;
15972
- this.inColItems = false;
15973
- this.inLocation = false;
15974
- this.currentPivotField = null;
15975
- this.inItems = false;
15976
- this.inPivotTableStyleInfo = false;
15977
16037
  }
15978
16038
  prepare(_model) {}
15979
16039
  get tag() {
@@ -15981,16 +16041,15 @@ var ExcelTS = (function(exports) {
15981
16041
  }
15982
16042
  reset() {
15983
16043
  this.model = null;
15984
- this.inPivotFields = false;
15985
- this.inRowFields = false;
15986
- this.inColFields = false;
15987
- this.inDataFields = false;
15988
- this.inRowItems = false;
15989
- this.inColItems = false;
15990
- this.inLocation = false;
16044
+ Object.keys(this.state).forEach((key) => {
16045
+ this.state[key] = false;
16046
+ });
15991
16047
  this.currentPivotField = null;
15992
- this.inItems = false;
15993
- this.inPivotTableStyleInfo = false;
16048
+ this.currentRowItem = null;
16049
+ this.currentColItem = null;
16050
+ this.currentChartFormat = null;
16051
+ this.pivotAreaXmlBuffer = [];
16052
+ this.pivotAreaDepth = 0;
15994
16053
  }
15995
16054
  /**
15996
16055
  * Render pivot table XML.
@@ -16089,8 +16148,7 @@ var ExcelTS = (function(exports) {
16089
16148
  * Render loaded pivot table (preserving original structure)
16090
16149
  */
16091
16150
  renderLoaded(xmlStream, model) {
16092
- xmlStream.openXml(XmlStream.StdDocAttributes);
16093
- xmlStream.openNode(this.tag, {
16151
+ const attrs = {
16094
16152
  ...PivotTableXform.PIVOT_TABLE_ATTRIBUTES,
16095
16153
  name: model.name || "PivotTable1",
16096
16154
  cacheId: model.cacheId,
@@ -16099,7 +16157,7 @@ var ExcelTS = (function(exports) {
16099
16157
  applyFontFormats: model.applyFontFormats || "0",
16100
16158
  applyPatternFormats: model.applyPatternFormats || "0",
16101
16159
  applyAlignmentFormats: model.applyAlignmentFormats || "0",
16102
- applyWidthHeightFormats: model.applyWidthHeightFormats || "0",
16160
+ applyWidthHeightFormats: model.applyWidthHeightFormats ?? "0",
16103
16161
  dataCaption: model.dataCaption || "Values",
16104
16162
  updatedVersion: model.updatedVersion || "8",
16105
16163
  minRefreshableVersion: model.minRefreshableVersion || "3",
@@ -16107,10 +16165,15 @@ var ExcelTS = (function(exports) {
16107
16165
  itemPrintTitles: model.itemPrintTitles ? "1" : "0",
16108
16166
  createdVersion: model.createdVersion || "8",
16109
16167
  indent: model.indent !== void 0 ? String(model.indent) : "0",
16110
- compact: model.compact ? "1" : "0",
16111
- compactData: model.compactData ? "1" : "0",
16112
16168
  multipleFieldFilters: model.multipleFieldFilters ? "1" : "0"
16113
- });
16169
+ };
16170
+ if (model.outline) attrs.outline = "1";
16171
+ if (model.outlineData) attrs.outlineData = "1";
16172
+ if (model.chartFormat !== void 0) attrs.chartFormat = String(model.chartFormat);
16173
+ if (model.compact) attrs.compact = "1";
16174
+ if (model.compactData) attrs.compactData = "1";
16175
+ xmlStream.openXml(XmlStream.StdDocAttributes);
16176
+ xmlStream.openNode(this.tag, attrs);
16114
16177
  if (model.location) xmlStream.leafNode("location", {
16115
16178
  ref: model.location.ref,
16116
16179
  firstHeaderRow: model.location.firstHeaderRow,
@@ -16127,30 +16190,46 @@ var ExcelTS = (function(exports) {
16127
16190
  for (const fieldIndex of model.rowFields) xmlStream.leafNode("field", { x: fieldIndex });
16128
16191
  xmlStream.closeNode();
16129
16192
  }
16130
- xmlStream.writeXml(`
16131
- <rowItems count="1">
16132
- <i t="grand"><x /></i>
16133
- </rowItems>`);
16193
+ if (model.rowItems && model.rowItems.length > 0) {
16194
+ xmlStream.openNode("rowItems", { count: model.rowItems.length });
16195
+ for (const item of model.rowItems) this.renderRowColItem(xmlStream, item);
16196
+ xmlStream.closeNode();
16197
+ } else xmlStream.writeXml("<rowItems count=\"1\"><i t=\"grand\"><x/></i></rowItems>");
16134
16198
  const colFieldCount = model.colFields.length === 0 ? 1 : model.colFields.length;
16135
16199
  xmlStream.openNode("colFields", { count: colFieldCount });
16136
16200
  if (model.colFields.length === 0) xmlStream.leafNode("field", { x: -2 });
16137
16201
  else for (const fieldIndex of model.colFields) xmlStream.leafNode("field", { x: fieldIndex });
16138
16202
  xmlStream.closeNode();
16139
- xmlStream.writeXml(`
16140
- <colItems count="1">
16141
- <i t="grand"><x /></i>
16142
- </colItems>`);
16203
+ if (model.colItems && model.colItems.length > 0) {
16204
+ xmlStream.openNode("colItems", { count: model.colItems.length });
16205
+ for (const item of model.colItems) this.renderRowColItem(xmlStream, item);
16206
+ xmlStream.closeNode();
16207
+ } else xmlStream.writeXml("<colItems count=\"1\"><i t=\"grand\"><x/></i></colItems>");
16143
16208
  if (model.dataFields.length > 0) {
16144
16209
  xmlStream.openNode("dataFields", { count: model.dataFields.length });
16145
16210
  for (const dataField of model.dataFields) {
16146
- const attrs = {
16211
+ const dfAttrs = {
16147
16212
  name: dataField.name,
16148
16213
  fld: dataField.fld,
16149
16214
  baseField: dataField.baseField ?? 0,
16150
16215
  baseItem: dataField.baseItem ?? 0
16151
16216
  };
16152
- if (dataField.subtotal && dataField.subtotal !== "sum") attrs.subtotal = dataField.subtotal;
16153
- xmlStream.leafNode("dataField", attrs);
16217
+ if (dataField.subtotal && dataField.subtotal !== "sum") dfAttrs.subtotal = dataField.subtotal;
16218
+ xmlStream.leafNode("dataField", dfAttrs);
16219
+ }
16220
+ xmlStream.closeNode();
16221
+ }
16222
+ if (model.chartFormats && model.chartFormats.length > 0) {
16223
+ xmlStream.openNode("chartFormats", { count: model.chartFormats.length });
16224
+ for (const cf of model.chartFormats) {
16225
+ xmlStream.openNode("chartFormat", {
16226
+ chart: cf.chart,
16227
+ format: cf.format,
16228
+ series: cf.series ? "1" : void 0
16229
+ });
16230
+ if (cf.pivotAreaXml) xmlStream.writeXml(cf.pivotAreaXml);
16231
+ 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>`);
16232
+ xmlStream.closeNode();
16154
16233
  }
16155
16234
  xmlStream.closeNode();
16156
16235
  }
@@ -16162,47 +16241,35 @@ var ExcelTS = (function(exports) {
16162
16241
  showColStripes: "0",
16163
16242
  showLastColumn: "1"
16164
16243
  });
16165
- xmlStream.writeXml(`
16166
- <extLst>
16167
- <ext
16168
- uri="{962EF5D1-5CA2-4c93-8EF4-DBF5C05439D2}"
16169
- xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
16170
- >
16171
- <x14:pivotTableDefinition
16172
- hideValuesRow="1"
16173
- xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main"
16174
- />
16175
- </ext>
16176
- <ext
16177
- uri="{747A6164-185A-40DC-8AA5-F01512510D54}"
16178
- xmlns:xpdl="http://schemas.microsoft.com/office/spreadsheetml/2016/pivotdefaultlayout"
16179
- >
16180
- <xpdl:pivotTableDefinition16
16181
- EnabledSubtotalsDefault="0"
16182
- SubtotalsOnTopDefault="0"
16183
- />
16184
- </ext>
16185
- </extLst>
16186
- `);
16244
+ 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>`);
16187
16245
  xmlStream.closeNode();
16188
16246
  }
16189
16247
  /**
16248
+ * Render a row or column item element
16249
+ */
16250
+ renderRowColItem(xmlStream, item) {
16251
+ const attrs = {};
16252
+ if (item.t) attrs.t = item.t;
16253
+ if (item.x && item.x.length > 0) {
16254
+ xmlStream.openNode("i", attrs);
16255
+ for (const x of item.x) if (x.v && x.v !== 0) xmlStream.leafNode("x", { v: x.v });
16256
+ else xmlStream.leafNode("x");
16257
+ xmlStream.closeNode();
16258
+ } else xmlStream.leafNode("i", attrs);
16259
+ }
16260
+ /**
16190
16261
  * Render a loaded pivot field
16191
16262
  */
16192
16263
  renderPivotFieldLoaded(xmlStream, field) {
16193
- const attrs = {
16194
- compact: field.compact ? "1" : "0",
16195
- outline: field.outline ? "1" : "0",
16196
- showAll: field.showAll ? "1" : "0",
16197
- defaultSubtotal: field.defaultSubtotal ? "1" : "0"
16198
- };
16264
+ const attrs = {};
16199
16265
  if (field.axis) attrs.axis = field.axis;
16200
16266
  if (field.dataField) attrs.dataField = "1";
16267
+ attrs.showAll = field.showAll ? "1" : "0";
16201
16268
  if (field.items && field.items.length > 0) {
16202
16269
  xmlStream.openNode("pivotField", attrs);
16203
16270
  xmlStream.openNode("items", { count: field.items.length + 1 });
16204
16271
  for (const itemIndex of field.items) xmlStream.leafNode("item", { x: itemIndex });
16205
- xmlStream.writeXml("<item t=\"default\" />");
16272
+ xmlStream.writeXml("<item t=\"default\"/>");
16206
16273
  xmlStream.closeNode();
16207
16274
  xmlStream.closeNode();
16208
16275
  } else xmlStream.leafNode("pivotField", attrs);
@@ -16236,6 +16303,12 @@ var ExcelTS = (function(exports) {
16236
16303
  compact: attributes.compact === "1",
16237
16304
  compactData: attributes.compactData === "1",
16238
16305
  multipleFieldFilters: attributes.multipleFieldFilters === "1",
16306
+ outline: attributes.outline === "1",
16307
+ outlineData: attributes.outlineData === "1",
16308
+ chartFormat: attributes.chartFormat ? parseInt(attributes.chartFormat, 10) : void 0,
16309
+ rowItems: [],
16310
+ colItems: [],
16311
+ chartFormats: [],
16239
16312
  isLoaded: true
16240
16313
  };
16241
16314
  break;
@@ -16248,10 +16321,10 @@ var ExcelTS = (function(exports) {
16248
16321
  };
16249
16322
  break;
16250
16323
  case "pivotFields":
16251
- this.inPivotFields = true;
16324
+ this.state.inPivotFields = true;
16252
16325
  break;
16253
16326
  case "pivotField":
16254
- if (this.inPivotFields) this.currentPivotField = {
16327
+ if (this.state.inPivotFields) this.currentPivotField = {
16255
16328
  axis: attributes.axis,
16256
16329
  dataField: attributes.dataField === "1",
16257
16330
  items: [],
@@ -16262,35 +16335,77 @@ var ExcelTS = (function(exports) {
16262
16335
  };
16263
16336
  break;
16264
16337
  case "items":
16265
- if (this.currentPivotField) this.inItems = true;
16338
+ if (this.currentPivotField) this.state.inItems = true;
16266
16339
  break;
16267
16340
  case "item":
16268
- if (this.inItems && this.currentPivotField && attributes.x !== void 0) this.currentPivotField.items.push(parseInt(attributes.x, 10));
16341
+ if (this.state.inItems && this.currentPivotField && attributes.x !== void 0) this.currentPivotField.items.push(parseInt(attributes.x, 10));
16269
16342
  break;
16270
16343
  case "rowFields":
16271
- this.inRowFields = true;
16344
+ this.state.inRowFields = true;
16272
16345
  break;
16273
16346
  case "colFields":
16274
- this.inColFields = true;
16347
+ this.state.inColFields = true;
16275
16348
  break;
16276
16349
  case "dataFields":
16277
- this.inDataFields = true;
16350
+ this.state.inDataFields = true;
16278
16351
  break;
16279
16352
  case "rowItems":
16280
- this.inRowItems = true;
16353
+ this.state.inRowItems = true;
16281
16354
  break;
16282
16355
  case "colItems":
16283
- this.inColItems = true;
16356
+ this.state.inColItems = true;
16357
+ break;
16358
+ case "i":
16359
+ if (this.state.inRowItems && this.model) this.currentRowItem = {
16360
+ t: attributes.t,
16361
+ x: []
16362
+ };
16363
+ else if (this.state.inColItems && this.model) this.currentColItem = {
16364
+ t: attributes.t,
16365
+ x: []
16366
+ };
16367
+ break;
16368
+ case "x":
16369
+ if (this.state.inPivotArea) {
16370
+ const xAttrs = Object.entries(attributes).map(([k, v]) => `${k}="${v}"`).join(" ");
16371
+ this.pivotAreaXmlBuffer.push(xAttrs ? `<x ${xAttrs}/>` : "<x/>");
16372
+ } else if (this.currentRowItem) this.currentRowItem.x.push({ v: attributes.v ? parseInt(attributes.v, 10) : 0 });
16373
+ else if (this.currentColItem) this.currentColItem.x.push({ v: attributes.v ? parseInt(attributes.v, 10) : 0 });
16374
+ break;
16375
+ case "chartFormats":
16376
+ this.state.inChartFormats = true;
16377
+ break;
16378
+ case "chartFormat":
16379
+ if (this.state.inChartFormats && this.model) this.currentChartFormat = {
16380
+ chart: attributes.chart ? parseInt(attributes.chart, 10) : 0,
16381
+ format: attributes.format ? parseInt(attributes.format, 10) : 0,
16382
+ series: attributes.series === "1"
16383
+ };
16384
+ break;
16385
+ case "pivotArea":
16386
+ if (this.currentChartFormat) {
16387
+ this.state.inPivotArea = true;
16388
+ const attrsStr = Object.entries(attributes).map(([k, v]) => `${k}="${v}"`).join(" ");
16389
+ this.pivotAreaXmlBuffer = [attrsStr ? `<pivotArea ${attrsStr}>` : "<pivotArea>"];
16390
+ }
16391
+ break;
16392
+ case "references":
16393
+ case "reference":
16394
+ if (this.state.inPivotArea) {
16395
+ this.pivotAreaDepth++;
16396
+ const attrsStr = Object.entries(attributes).map(([k, v]) => `${k}="${v}"`).join(" ");
16397
+ this.pivotAreaXmlBuffer.push(`<${name}${attrsStr ? " " + attrsStr : ""}>`);
16398
+ }
16284
16399
  break;
16285
16400
  case "field":
16286
16401
  if (this.model) {
16287
16402
  const fieldIndex = parseInt(attributes.x || "0", 10);
16288
- if (this.inRowFields) this.model.rowFields.push(fieldIndex);
16289
- else if (this.inColFields) this.model.colFields.push(fieldIndex);
16403
+ if (this.state.inRowFields) this.model.rowFields.push(fieldIndex);
16404
+ else if (this.state.inColFields) this.model.colFields.push(fieldIndex);
16290
16405
  }
16291
16406
  break;
16292
16407
  case "dataField":
16293
- if (this.inDataFields && this.model) this.model.dataFields.push({
16408
+ if (this.state.inDataFields && this.model) this.model.dataFields.push({
16294
16409
  name: xmlDecode(attributes.name || ""),
16295
16410
  fld: parseInt(attributes.fld || "0", 10),
16296
16411
  baseField: attributes.baseField ? parseInt(attributes.baseField, 10) : 0,
@@ -16306,10 +16421,25 @@ var ExcelTS = (function(exports) {
16306
16421
  }
16307
16422
  parseText(_text) {}
16308
16423
  parseClose(name) {
16424
+ if (this.state.inPivotArea) {
16425
+ if (name === "pivotArea") {
16426
+ this.pivotAreaXmlBuffer.push("</pivotArea>");
16427
+ if (this.currentChartFormat) this.currentChartFormat.pivotAreaXml = this.pivotAreaXmlBuffer.join("");
16428
+ this.state.inPivotArea = false;
16429
+ this.pivotAreaXmlBuffer = [];
16430
+ this.pivotAreaDepth = 0;
16431
+ return true;
16432
+ } else if (name === "references" || name === "reference") {
16433
+ this.pivotAreaXmlBuffer.push(`</${name}>`);
16434
+ this.pivotAreaDepth--;
16435
+ return true;
16436
+ }
16437
+ return true;
16438
+ }
16309
16439
  switch (name) {
16310
16440
  case this.tag: return false;
16311
16441
  case "pivotFields":
16312
- this.inPivotFields = false;
16442
+ this.state.inPivotFields = false;
16313
16443
  break;
16314
16444
  case "pivotField":
16315
16445
  if (this.currentPivotField && this.model) {
@@ -16318,22 +16448,40 @@ var ExcelTS = (function(exports) {
16318
16448
  }
16319
16449
  break;
16320
16450
  case "items":
16321
- this.inItems = false;
16451
+ this.state.inItems = false;
16322
16452
  break;
16323
16453
  case "rowFields":
16324
- this.inRowFields = false;
16454
+ this.state.inRowFields = false;
16325
16455
  break;
16326
16456
  case "colFields":
16327
- this.inColFields = false;
16457
+ this.state.inColFields = false;
16328
16458
  break;
16329
16459
  case "dataFields":
16330
- this.inDataFields = false;
16460
+ this.state.inDataFields = false;
16331
16461
  break;
16332
16462
  case "rowItems":
16333
- this.inRowItems = false;
16463
+ this.state.inRowItems = false;
16334
16464
  break;
16335
16465
  case "colItems":
16336
- this.inColItems = false;
16466
+ this.state.inColItems = false;
16467
+ break;
16468
+ case "i":
16469
+ if (this.currentRowItem && this.model) {
16470
+ this.model.rowItems.push(this.currentRowItem);
16471
+ this.currentRowItem = null;
16472
+ } else if (this.currentColItem && this.model) {
16473
+ this.model.colItems.push(this.currentColItem);
16474
+ this.currentColItem = null;
16475
+ }
16476
+ break;
16477
+ case "chartFormats":
16478
+ this.state.inChartFormats = false;
16479
+ break;
16480
+ case "chartFormat":
16481
+ if (this.currentChartFormat && this.model) {
16482
+ this.model.chartFormats.push(this.currentChartFormat);
16483
+ this.currentChartFormat = null;
16484
+ }
16337
16485
  break;
16338
16486
  }
16339
16487
  return true;
@@ -20206,6 +20354,115 @@ var ExcelTS = (function(exports) {
20206
20354
  }
20207
20355
  };
20208
20356
 
20357
+ //#endregion
20358
+ //#region src/modules/excel/utils/passthrough-manager.ts
20359
+ /**
20360
+ * Content type definitions for passthrough files
20361
+ */
20362
+ const PASSTHROUGH_CONTENT_TYPES = new Map([
20363
+ [/^xl\/charts\/chart\d+\.xml$/, "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"],
20364
+ [/^xl\/charts\/style\d+\.xml$/, "application/vnd.ms-office.chartstyle+xml"],
20365
+ [/^xl\/charts\/colors\d+\.xml$/, "application/vnd.ms-office.chartcolorstyle+xml"]
20366
+ ]);
20367
+ /**
20368
+ * Passthrough path prefixes that should be preserved
20369
+ */
20370
+ const PASSTHROUGH_PREFIXES = ["xl/charts/"];
20371
+ /**
20372
+ * PassthroughManager handles storage and retrieval of passthrough files
20373
+ * that need to be preserved during Excel read/write cycles.
20374
+ */
20375
+ var PassthroughManager = class PassthroughManager {
20376
+ constructor() {
20377
+ this.files = /* @__PURE__ */ new Map();
20378
+ }
20379
+ /**
20380
+ * Check if a path should be treated as passthrough
20381
+ */
20382
+ static isPassthroughPath(path) {
20383
+ return PASSTHROUGH_PREFIXES.some((prefix) => path.startsWith(prefix));
20384
+ }
20385
+ /**
20386
+ * Get the content type for a passthrough file path
20387
+ * @returns Content type string or undefined if unknown
20388
+ */
20389
+ static getContentType(path) {
20390
+ if (path.startsWith("xl/charts/_rels/")) return;
20391
+ for (const [regex, contentType] of PASSTHROUGH_CONTENT_TYPES) if (regex.test(path)) return contentType;
20392
+ }
20393
+ /**
20394
+ * Add a file to passthrough storage
20395
+ */
20396
+ add(path, data) {
20397
+ this.files.set(path, data);
20398
+ }
20399
+ /**
20400
+ * Get a file from passthrough storage
20401
+ */
20402
+ get(path) {
20403
+ return this.files.get(path);
20404
+ }
20405
+ /**
20406
+ * Check if a file exists in passthrough storage
20407
+ */
20408
+ has(path) {
20409
+ return this.files.has(path);
20410
+ }
20411
+ /**
20412
+ * Get all stored paths
20413
+ */
20414
+ getPaths() {
20415
+ return [...this.files.keys()];
20416
+ }
20417
+ /**
20418
+ * Get all files as a record (for serialization)
20419
+ */
20420
+ toRecord() {
20421
+ const record = {};
20422
+ for (const [path, data] of this.files) record[path] = data;
20423
+ return record;
20424
+ }
20425
+ /**
20426
+ * Load files from a record (for deserialization)
20427
+ */
20428
+ fromRecord(record) {
20429
+ this.files.clear();
20430
+ for (const [path, data] of Object.entries(record)) this.files.set(path, data);
20431
+ }
20432
+ /**
20433
+ * Get content types for all stored files that have known types
20434
+ */
20435
+ getContentTypes() {
20436
+ const contentTypes = [];
20437
+ for (const path of this.files.keys()) {
20438
+ const contentType = PassthroughManager.getContentType(path);
20439
+ if (contentType) contentTypes.push({
20440
+ partName: path,
20441
+ contentType
20442
+ });
20443
+ }
20444
+ return contentTypes;
20445
+ }
20446
+ /**
20447
+ * Write all passthrough files to a ZIP writer
20448
+ */
20449
+ writeToZip(zip$1) {
20450
+ for (const [path, data] of this.files) zip$1.append(data, { name: path });
20451
+ }
20452
+ /**
20453
+ * Clear all stored files
20454
+ */
20455
+ clear() {
20456
+ this.files.clear();
20457
+ }
20458
+ /**
20459
+ * Get the number of stored files
20460
+ */
20461
+ get size() {
20462
+ return this.files.size;
20463
+ }
20464
+ };
20465
+
20209
20466
  //#endregion
20210
20467
  //#region src/modules/excel/xlsx/xlsx.browser.ts
20211
20468
  /**
@@ -20356,6 +20613,7 @@ var ExcelTS = (function(exports) {
20356
20613
  this.addDrawings(zip$1, model);
20357
20614
  this.addTables(zip$1, model);
20358
20615
  this.addPivotTables(zip$1, model);
20616
+ this.addPassthrough(zip$1, model);
20359
20617
  await Promise.all([this.addThemes(zip$1, model), this.addStyles(zip$1, model)]);
20360
20618
  await this.addFeaturePropertyBag(zip$1, model);
20361
20619
  await this.addMedia(zip$1, model);
@@ -20429,8 +20687,12 @@ var ExcelTS = (function(exports) {
20429
20687
  * This is the foundation for TRUE streaming reads on platforms that have a
20430
20688
  * streaming ZIP parser (e.g. Node.js `modules/archive` Parse).
20431
20689
  */
20432
- async loadFromZipEntries(entries, options) {
20433
- const model = {
20690
+ /**
20691
+ * Create an empty model for parsing XLSX files.
20692
+ * Shared by loadFromZipEntries and loadFromFiles.
20693
+ */
20694
+ createEmptyModel() {
20695
+ return {
20434
20696
  worksheets: [],
20435
20697
  worksheetHash: {},
20436
20698
  worksheetRels: [],
@@ -20439,6 +20701,7 @@ var ExcelTS = (function(exports) {
20439
20701
  mediaIndex: {},
20440
20702
  drawings: {},
20441
20703
  drawingRels: {},
20704
+ rawDrawings: {},
20442
20705
  comments: {},
20443
20706
  tables: {},
20444
20707
  vmlDrawings: {},
@@ -20446,8 +20709,93 @@ var ExcelTS = (function(exports) {
20446
20709
  pivotTableRels: {},
20447
20710
  pivotCacheDefinitions: {},
20448
20711
  pivotCacheDefinitionRels: {},
20449
- pivotCacheRecords: {}
20712
+ pivotCacheRecords: {},
20713
+ passthrough: {}
20450
20714
  };
20715
+ }
20716
+ /**
20717
+ * Collect all data from a stream into a single Uint8Array.
20718
+ * Reusable helper for passthrough and drawing processing.
20719
+ */
20720
+ async collectStreamData(stream) {
20721
+ const chunks = [];
20722
+ await new Promise((resolve, reject) => {
20723
+ stream.on("data", (chunk) => {
20724
+ if (typeof chunk === "string") chunks.push(new TextEncoder().encode(chunk));
20725
+ else if (chunk instanceof Uint8Array) chunks.push(chunk);
20726
+ else chunks.push(new Uint8Array(chunk));
20727
+ });
20728
+ stream.on("end", () => resolve());
20729
+ stream.on("error", reject);
20730
+ });
20731
+ return concatUint8Arrays$2(chunks);
20732
+ }
20733
+ /**
20734
+ * Check if a drawing has chart references in its relationships
20735
+ */
20736
+ drawingHasChartReference(drawing) {
20737
+ return drawing.rels && drawing.rels.some((rel) => rel.Target && rel.Target.includes("/charts/"));
20738
+ }
20739
+ /**
20740
+ * Check if a drawing rels list references charts.
20741
+ * Used to decide whether we need to keep raw drawing XML for passthrough.
20742
+ */
20743
+ drawingRelsHasChartReference(drawingRels) {
20744
+ return Array.isArray(drawingRels) && drawingRels.some((rel) => typeof rel?.Target === "string" && rel.Target.includes("/charts/"));
20745
+ }
20746
+ /**
20747
+ * Process a known OOXML entry (workbook, styles, shared strings, etc.)
20748
+ * Returns true if handled, false if should be passed to _processDefaultEntry
20749
+ */
20750
+ async _processKnownEntry(stream, model, entryName, options) {
20751
+ const sheetNo = getWorksheetNoFromWorksheetPath(entryName);
20752
+ if (sheetNo !== void 0) {
20753
+ await this._processWorksheetEntry(stream, model, sheetNo, options, entryName);
20754
+ return true;
20755
+ }
20756
+ switch (entryName) {
20757
+ case OOXML_PATHS.rootRels:
20758
+ model.globalRels = await this.parseRels(stream);
20759
+ return true;
20760
+ case OOXML_PATHS.xlWorkbook: {
20761
+ const workbook = await this.parseWorkbook(stream);
20762
+ model.sheets = workbook.sheets;
20763
+ model.definedNames = workbook.definedNames;
20764
+ model.views = workbook.views;
20765
+ model.properties = workbook.properties;
20766
+ model.calcProperties = workbook.calcProperties;
20767
+ model.pivotCaches = workbook.pivotCaches;
20768
+ return true;
20769
+ }
20770
+ case OOXML_PATHS.xlSharedStrings:
20771
+ model.sharedStrings = new SharedStringsXform();
20772
+ await model.sharedStrings.parseStream(stream);
20773
+ return true;
20774
+ case OOXML_PATHS.xlWorkbookRels:
20775
+ model.workbookRels = await this.parseRels(stream);
20776
+ return true;
20777
+ case OOXML_PATHS.docPropsApp: {
20778
+ const appProperties = await new AppXform().parseStream(stream);
20779
+ if (appProperties) {
20780
+ model.company = appProperties.company;
20781
+ model.manager = appProperties.manager;
20782
+ }
20783
+ return true;
20784
+ }
20785
+ case OOXML_PATHS.docPropsCore: {
20786
+ const coreProperties = await new CoreXform().parseStream(stream);
20787
+ Object.assign(model, coreProperties);
20788
+ return true;
20789
+ }
20790
+ case OOXML_PATHS.xlStyles:
20791
+ model.styles = new StylesXform();
20792
+ await model.styles.parseStream(stream);
20793
+ return true;
20794
+ default: return false;
20795
+ }
20796
+ }
20797
+ async loadFromZipEntries(entries, options) {
20798
+ const model = this.createEmptyModel();
20451
20799
  for await (const entry of entries) {
20452
20800
  let drained = false;
20453
20801
  const drainEntry = async () => {
@@ -20462,52 +20810,8 @@ var ExcelTS = (function(exports) {
20462
20810
  const entryName = normalizeZipPath(entry.name);
20463
20811
  const stream = entry.stream;
20464
20812
  try {
20465
- const sheetNo = getWorksheetNoFromWorksheetPath(entryName);
20466
- if (sheetNo !== void 0) {
20467
- await this._processWorksheetEntry(stream, model, sheetNo, options, entryName);
20468
- continue;
20469
- }
20470
- switch (entryName) {
20471
- case OOXML_PATHS.rootRels:
20472
- model.globalRels = await this.parseRels(stream);
20473
- break;
20474
- case OOXML_PATHS.xlWorkbook: {
20475
- const workbook = await this.parseWorkbook(stream);
20476
- model.sheets = workbook.sheets;
20477
- model.definedNames = workbook.definedNames;
20478
- model.views = workbook.views;
20479
- model.properties = workbook.properties;
20480
- model.calcProperties = workbook.calcProperties;
20481
- model.pivotCaches = workbook.pivotCaches;
20482
- break;
20483
- }
20484
- case OOXML_PATHS.xlSharedStrings:
20485
- model.sharedStrings = new SharedStringsXform();
20486
- await model.sharedStrings.parseStream(stream);
20487
- break;
20488
- case OOXML_PATHS.xlWorkbookRels:
20489
- model.workbookRels = await this.parseRels(stream);
20490
- break;
20491
- case OOXML_PATHS.docPropsApp: {
20492
- const appProperties = await new AppXform().parseStream(stream);
20493
- if (appProperties) {
20494
- model.company = appProperties.company;
20495
- model.manager = appProperties.manager;
20496
- }
20497
- break;
20498
- }
20499
- case OOXML_PATHS.docPropsCore: {
20500
- const coreProperties = await new CoreXform().parseStream(stream);
20501
- Object.assign(model, coreProperties);
20502
- break;
20503
- }
20504
- case OOXML_PATHS.xlStyles:
20505
- model.styles = new StylesXform();
20506
- await model.styles.parseStream(stream);
20507
- break;
20508
- default:
20509
- if (!await this._processDefaultEntry(stream, model, entryName)) await drainEntry();
20510
- break;
20813
+ if (!await this._processKnownEntry(stream, model, entryName, options)) {
20814
+ if (!await this._processDefaultEntry(stream, model, entryName)) await drainEntry();
20511
20815
  }
20512
20816
  } finally {
20513
20817
  try {
@@ -20596,6 +20900,10 @@ var ExcelTS = (function(exports) {
20596
20900
  drawingXform.reconcile(drawing, drawingOptions);
20597
20901
  }
20598
20902
  });
20903
+ if (model.rawDrawings && model.drawingRels) for (const name of Object.keys(model.rawDrawings)) {
20904
+ const drawingRel = model.drawingRels[name];
20905
+ if (drawingRel && !this.drawingRelsHasChartReference(drawingRel)) delete model.rawDrawings[name];
20906
+ }
20599
20907
  const tableOptions = { styles: model.styles };
20600
20908
  Object.values(model.tables).forEach((table) => {
20601
20909
  tableXform.reconcile(table, tableOptions);
@@ -20608,6 +20916,7 @@ var ExcelTS = (function(exports) {
20608
20916
  mediaIndex: model.mediaIndex,
20609
20917
  date1904: model.properties && model.properties.date1904,
20610
20918
  drawings: model.drawings,
20919
+ drawingRels: model.drawingRels,
20611
20920
  comments: model.comments,
20612
20921
  tables: model.tables,
20613
20922
  vmlDrawings: model.vmlDrawings,
@@ -20764,8 +21073,12 @@ var ExcelTS = (function(exports) {
20764
21073
  }
20765
21074
  }
20766
21075
  async _processDrawingEntry(entry, model, name) {
20767
- const drawing = await new DrawingXform().parseStream(entry);
21076
+ const rawData = await this.collectStreamData(entry);
21077
+ const xform$1 = new DrawingXform();
21078
+ const xmlString = this.bufferToString(rawData);
21079
+ const drawing = await xform$1.parseStream(this.createTextStream(xmlString));
20768
21080
  model.drawings[name] = drawing;
21081
+ model.rawDrawings[name] = rawData;
20769
21082
  }
20770
21083
  async _processDrawingRelsEntry(entry, model, name) {
20771
21084
  const relationships = await new RelationshipsXform().parseStream(entry);
@@ -20820,24 +21133,7 @@ var ExcelTS = (function(exports) {
20820
21133
  if (cacheRecords) model.pivotCacheRecords[name] = cacheRecords;
20821
21134
  }
20822
21135
  async loadFromFiles(zipData, options) {
20823
- const model = {
20824
- worksheets: [],
20825
- worksheetHash: {},
20826
- worksheetRels: [],
20827
- themes: {},
20828
- media: [],
20829
- mediaIndex: {},
20830
- drawings: {},
20831
- drawingRels: {},
20832
- comments: {},
20833
- tables: {},
20834
- vmlDrawings: {},
20835
- pivotTables: {},
20836
- pivotTableRels: {},
20837
- pivotCacheDefinitions: {},
20838
- pivotCacheDefinitionRels: {},
20839
- pivotCacheRecords: {}
20840
- };
21136
+ const model = this.createEmptyModel();
20841
21137
  const entries = Object.keys(zipData).map((name) => ({
20842
21138
  name,
20843
21139
  dir: name.endsWith("/"),
@@ -20846,48 +21142,7 @@ var ExcelTS = (function(exports) {
20846
21142
  for (const entry of entries) if (!entry.dir) {
20847
21143
  const entryName = normalizeZipPath(entry.name);
20848
21144
  const stream = isBinaryEntryPath(entryName) ? this.createBinaryStream(entry.data) : this.createTextStream(this.bufferToString(entry.data));
20849
- const sheetNo = getWorksheetNoFromWorksheetPath(entryName);
20850
- if (sheetNo !== void 0) await this._processWorksheetEntry(stream, model, sheetNo, options, entryName);
20851
- else switch (entryName) {
20852
- case OOXML_PATHS.rootRels:
20853
- model.globalRels = await this.parseRels(stream);
20854
- break;
20855
- case OOXML_PATHS.xlWorkbook: {
20856
- const workbook = await this.parseWorkbook(stream);
20857
- model.sheets = workbook.sheets;
20858
- model.definedNames = workbook.definedNames;
20859
- model.views = workbook.views;
20860
- model.properties = workbook.properties;
20861
- model.calcProperties = workbook.calcProperties;
20862
- model.pivotCaches = workbook.pivotCaches;
20863
- break;
20864
- }
20865
- case OOXML_PATHS.xlSharedStrings:
20866
- model.sharedStrings = new SharedStringsXform();
20867
- await model.sharedStrings.parseStream(stream);
20868
- break;
20869
- case OOXML_PATHS.xlWorkbookRels:
20870
- model.workbookRels = await this.parseRels(stream);
20871
- break;
20872
- case OOXML_PATHS.docPropsApp: {
20873
- const appProperties = await new AppXform().parseStream(stream);
20874
- if (appProperties) {
20875
- model.company = appProperties.company;
20876
- model.manager = appProperties.manager;
20877
- }
20878
- break;
20879
- }
20880
- case OOXML_PATHS.docPropsCore: {
20881
- const coreProperties = await new CoreXform().parseStream(stream);
20882
- Object.assign(model, coreProperties);
20883
- break;
20884
- }
20885
- case OOXML_PATHS.xlStyles:
20886
- model.styles = new StylesXform();
20887
- await model.styles.parseStream(stream);
20888
- break;
20889
- default: await this._processDefaultEntry(stream, model, entryName);
20890
- }
21145
+ if (!await this._processKnownEntry(stream, model, entryName, options)) await this._processDefaultEntry(stream, model, entryName, entry.data);
20891
21146
  }
20892
21147
  this.reconcile(model, options);
20893
21148
  this.workbook.model = model;
@@ -20895,11 +21150,11 @@ var ExcelTS = (function(exports) {
20895
21150
  }
20896
21151
  /**
20897
21152
  * Process default entries (drawings, comments, tables, etc.)
21153
+ * @param rawData Optional raw entry data for passthrough preservation (used by loadFromFiles)
20898
21154
  */
20899
- async _processDefaultEntry(stream, model, entryName) {
20900
- const worksheetRelsSheetNo = getWorksheetNoFromWorksheetRelsPath(entryName);
20901
- if (worksheetRelsSheetNo !== void 0) {
20902
- const sheetNo = worksheetRelsSheetNo;
21155
+ async _processDefaultEntry(stream, model, entryName, rawData) {
21156
+ const sheetNo = getWorksheetNoFromWorksheetRelsPath(entryName);
21157
+ if (sheetNo !== void 0) {
20903
21158
  await this._processWorksheetRelsEntry(stream, model, sheetNo);
20904
21159
  return true;
20905
21160
  }
@@ -20911,6 +21166,7 @@ var ExcelTS = (function(exports) {
20911
21166
  const drawingName = getDrawingNameFromPath(entryName);
20912
21167
  if (drawingName) {
20913
21168
  await this._processDrawingEntry(stream, model, drawingName);
21169
+ if (rawData) model.rawDrawings[drawingName] = rawData;
20914
21170
  return true;
20915
21171
  }
20916
21172
  const drawingRelsName = getDrawingNameFromRelsPath(entryName);
@@ -20963,8 +21219,21 @@ var ExcelTS = (function(exports) {
20963
21219
  await this._processPivotCacheRecordsEntry(stream, model, pivotCacheRecordsName);
20964
21220
  return true;
20965
21221
  }
21222
+ if (PassthroughManager.isPassthroughPath(entryName)) {
21223
+ if (rawData) model.passthrough[entryName] = rawData;
21224
+ else await this._processPassthroughEntry(stream, model, entryName);
21225
+ return true;
21226
+ }
20966
21227
  return false;
20967
21228
  }
21229
+ /**
21230
+ * Store a passthrough file for preservation during read/write cycles.
21231
+ * These files are not parsed but stored as raw bytes to be written back unchanged.
21232
+ */
21233
+ async _processPassthroughEntry(stream, model, entryName) {
21234
+ const data = await this.collectStreamData(stream);
21235
+ model.passthrough[entryName] = data;
21236
+ }
20968
21237
  async addContentTypes(zip$1, model) {
20969
21238
  const xml = new ContentTypesXform().toXml(model);
20970
21239
  zip$1.append(xml, { name: OOXML_PATHS.contentTypes });
@@ -21101,14 +21370,29 @@ var ExcelTS = (function(exports) {
21101
21370
  addDrawings(zip$1, model) {
21102
21371
  const drawingXform = new DrawingXform();
21103
21372
  const relsXform = new RelationshipsXform();
21373
+ const rawDrawings = model.rawDrawings || {};
21104
21374
  model.worksheets.forEach((worksheet) => {
21105
21375
  const { drawing } = worksheet;
21106
21376
  if (drawing) {
21107
- drawingXform.prepare(drawing);
21108
- let xml = drawingXform.toXml(drawing);
21109
- zip$1.append(xml, { name: drawingPath(drawing.name) });
21110
- xml = relsXform.toXml(drawing.rels);
21111
- zip$1.append(xml, { name: drawingRelsPath(drawing.name) });
21377
+ if (this.drawingHasChartReference(drawing) && rawDrawings[drawing.name]) zip$1.append(rawDrawings[drawing.name], { name: drawingPath(drawing.name) });
21378
+ else {
21379
+ const filteredAnchors = (drawing.anchors || []).filter((a) => {
21380
+ if (a == null) return false;
21381
+ if (a.range?.br && a.shape) return true;
21382
+ if (!a.br && !a.picture) return false;
21383
+ if (a.br && !a.picture && !a.shape) return false;
21384
+ return true;
21385
+ });
21386
+ const drawingForWrite = drawing.anchors ? {
21387
+ ...drawing,
21388
+ anchors: filteredAnchors
21389
+ } : drawing;
21390
+ drawingXform.prepare(drawingForWrite);
21391
+ const xml = drawingXform.toXml(drawingForWrite);
21392
+ zip$1.append(xml, { name: drawingPath(drawing.name) });
21393
+ }
21394
+ const relsXml = relsXform.toXml(drawing.rels);
21395
+ zip$1.append(relsXml, { name: drawingRelsPath(drawing.name) });
21112
21396
  }
21113
21397
  });
21114
21398
  }
@@ -21123,6 +21407,15 @@ var ExcelTS = (function(exports) {
21123
21407
  });
21124
21408
  });
21125
21409
  }
21410
+ /**
21411
+ * Write passthrough files (charts, etc.) that were preserved during read.
21412
+ * These files are written back unchanged to preserve unsupported features.
21413
+ */
21414
+ addPassthrough(zip$1, model) {
21415
+ const passthroughManager = new PassthroughManager();
21416
+ passthroughManager.fromRecord(model.passthrough || {});
21417
+ passthroughManager.writeToZip(zip$1);
21418
+ }
21126
21419
  addPivotTables(zip$1, model) {
21127
21420
  if (!model.pivotTables.length) return;
21128
21421
  const pivotCacheRecordsXform = new PivotCacheRecordsXform();
@@ -21205,6 +21498,10 @@ var ExcelTS = (function(exports) {
21205
21498
  worksheetXform.prepare(worksheet, worksheetOptions);
21206
21499
  });
21207
21500
  model.hasCheckboxes = model.styles.hasCheckboxes;
21501
+ const passthrough = model.passthrough || {};
21502
+ const passthroughManager = new PassthroughManager();
21503
+ passthroughManager.fromRecord(passthrough);
21504
+ model.passthroughContentTypes = passthroughManager.getContentTypes();
21208
21505
  }
21209
21506
  };
21210
21507
 
@@ -22406,7 +22703,7 @@ var ExcelTS = (function(exports) {
22406
22703
  else str = String(content);
22407
22704
  const worksheet = this.workbook.addWorksheet(options?.sheetName);
22408
22705
  const dateFormats = options?.dateFormats ?? DEFAULT_DATE_FORMATS;
22409
- const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator ?? options?.parserOptions?.decimalSeparator });
22706
+ const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator });
22410
22707
  const rows = parseCsv(str, options?.parserOptions);
22411
22708
  for (const row of rows) worksheet.addRow(row.map(map));
22412
22709
  return worksheet;
@@ -22434,7 +22731,7 @@ var ExcelTS = (function(exports) {
22434
22731
  async read(stream, options) {
22435
22732
  const worksheet = this.workbook.addWorksheet(options?.sheetName);
22436
22733
  const dateFormats = options?.dateFormats ?? DEFAULT_DATE_FORMATS;
22437
- const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator ?? options?.parserOptions?.decimalSeparator });
22734
+ const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator });
22438
22735
  const parser = new CsvParserStream(options?.parserOptions);
22439
22736
  return new Promise((resolve, reject) => {
22440
22737
  parser.on("data", (row) => worksheet.addRow(row.map(map)));
@@ -22486,7 +22783,7 @@ var ExcelTS = (function(exports) {
22486
22783
  createWriteStream(options) {
22487
22784
  const worksheet = this.workbook.addWorksheet(options?.sheetName);
22488
22785
  const dateFormats = options?.dateFormats ?? DEFAULT_DATE_FORMATS;
22489
- const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator ?? options?.parserOptions?.decimalSeparator });
22786
+ const map = options?.map || createDefaultValueMapper(dateFormats, { decimalSeparator: options?.valueMapperOptions?.decimalSeparator });
22490
22787
  const parser = new CsvParserStream(options?.parserOptions);
22491
22788
  parser.on("data", (row) => worksheet.addRow(row.map(map)));
22492
22789
  return parser;
@@ -25487,6 +25784,8 @@ onmessage = async (ev) => {
25487
25784
  this.views = [];
25488
25785
  this.media = [];
25489
25786
  this.pivotTables = [];
25787
+ this._passthrough = {};
25788
+ this._rawDrawings = {};
25490
25789
  this._definedNames = new DefinedNames();
25491
25790
  }
25492
25791
  /**
@@ -25659,7 +25958,9 @@ onmessage = async (ev) => {
25659
25958
  themes: this._themes,
25660
25959
  media: this.media,
25661
25960
  pivotTables: this.pivotTables,
25662
- calcProperties: this.calcProperties
25961
+ calcProperties: this.calcProperties,
25962
+ passthrough: this._passthrough,
25963
+ rawDrawings: this._rawDrawings
25663
25964
  };
25664
25965
  }
25665
25966
  set model(value) {
@@ -25698,6 +25999,8 @@ onmessage = async (ev) => {
25698
25999
  this._themes = value.themes;
25699
26000
  this.media = value.media || [];
25700
26001
  this.pivotTables = value.pivotTables || value.loadedPivotTables || [];
26002
+ this._passthrough = value.passthrough || {};
26003
+ this._rawDrawings = value.rawDrawings || {};
25701
26004
  }
25702
26005
  };
25703
26006