@cj-tech-master/excelts 1.5.0 → 1.6.1

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 (45) hide show
  1. package/dist/browser/excelts.iife.js +1057 -201
  2. package/dist/browser/excelts.iife.js.map +1 -1
  3. package/dist/browser/excelts.iife.min.js +63 -33
  4. package/dist/cjs/doc/column.js +7 -3
  5. package/dist/cjs/doc/pivot-table.js +149 -61
  6. package/dist/cjs/doc/workbook.js +3 -1
  7. package/dist/cjs/doc/worksheet.js +0 -2
  8. package/dist/cjs/stream/xlsx/worksheet-writer.js +1 -1
  9. package/dist/cjs/utils/unzip/zip-parser.js +2 -5
  10. package/dist/cjs/xlsx/xform/book/workbook-xform.js +3 -0
  11. package/dist/cjs/xlsx/xform/core/content-types-xform.js +19 -14
  12. package/dist/cjs/xlsx/xform/pivot-table/cache-field-xform.js +135 -0
  13. package/dist/cjs/xlsx/xform/pivot-table/cache-field.js +7 -4
  14. package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +135 -13
  15. package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-records-xform.js +193 -45
  16. package/dist/cjs/xlsx/xform/pivot-table/pivot-table-xform.js +390 -39
  17. package/dist/cjs/xlsx/xform/sheet/cell-xform.js +6 -0
  18. package/dist/cjs/xlsx/xform/sheet/worksheet-xform.js +14 -3
  19. package/dist/cjs/xlsx/xlsx.js +261 -38
  20. package/dist/esm/doc/column.js +7 -3
  21. package/dist/esm/doc/pivot-table.js +150 -62
  22. package/dist/esm/doc/workbook.js +3 -1
  23. package/dist/esm/doc/worksheet.js +0 -2
  24. package/dist/esm/stream/xlsx/worksheet-writer.js +1 -1
  25. package/dist/esm/utils/unzip/zip-parser.js +2 -5
  26. package/dist/esm/xlsx/xform/book/workbook-xform.js +3 -0
  27. package/dist/esm/xlsx/xform/core/content-types-xform.js +19 -14
  28. package/dist/esm/xlsx/xform/pivot-table/cache-field-xform.js +132 -0
  29. package/dist/esm/xlsx/xform/pivot-table/cache-field.js +7 -4
  30. package/dist/esm/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +135 -13
  31. package/dist/esm/xlsx/xform/pivot-table/pivot-cache-records-xform.js +193 -45
  32. package/dist/esm/xlsx/xform/pivot-table/pivot-table-xform.js +390 -39
  33. package/dist/esm/xlsx/xform/sheet/cell-xform.js +6 -0
  34. package/dist/esm/xlsx/xform/sheet/worksheet-xform.js +14 -3
  35. package/dist/esm/xlsx/xlsx.js +261 -38
  36. package/dist/types/doc/column.d.ts +13 -6
  37. package/dist/types/doc/pivot-table.d.ts +135 -9
  38. package/dist/types/doc/workbook.d.ts +2 -0
  39. package/dist/types/index.d.ts +1 -0
  40. package/dist/types/xlsx/xform/pivot-table/cache-field-xform.d.ts +42 -0
  41. package/dist/types/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +45 -6
  42. package/dist/types/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +52 -5
  43. package/dist/types/xlsx/xform/pivot-table/pivot-table-xform.d.ts +98 -5
  44. package/dist/types/xlsx/xlsx.d.ts +27 -0
  45. package/package.json +17 -17
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @cj-tech-master/excelts v1.5.0
2
+ * @cj-tech-master/excelts v1.6.1
3
3
  * TypeScript Excel Workbook Manager - Read and Write xlsx and csv Files.
4
4
  * (c) 2025 cjnoname
5
5
  * Released under the MIT License
@@ -1882,7 +1882,7 @@ var ExcelTS = (function(exports) {
1882
1882
  * This includes header rows, widths, key, (style), etc.
1883
1883
  * Worksheet will condense the columns as appropriate during serialization
1884
1884
  */
1885
- var Column = class Column {
1885
+ var Column$1 = class Column$1 {
1886
1886
  constructor(worksheet, number, defn) {
1887
1887
  this._worksheet = worksheet;
1888
1888
  this._number = number;
@@ -1930,13 +1930,17 @@ var ExcelTS = (function(exports) {
1930
1930
  this.outlineLevel = 0;
1931
1931
  }
1932
1932
  }
1933
+ /**
1934
+ * Get header values as an array (for multi-row header support)
1935
+ */
1933
1936
  get headers() {
1934
1937
  if (Array.isArray(this._header)) return this._header;
1935
1938
  if (this._header !== void 0) return [this._header];
1936
1939
  return [];
1937
1940
  }
1938
1941
  /**
1939
- * Can be a string to set one row high header or an array to set multi-row high header
1942
+ * Can be a single value or an array for multi-row headers.
1943
+ * Supports any CellValue type including Date, number, string, etc.
1940
1944
  */
1941
1945
  get header() {
1942
1946
  return this._header;
@@ -1944,8 +1948,8 @@ var ExcelTS = (function(exports) {
1944
1948
  set header(value) {
1945
1949
  if (value !== void 0) {
1946
1950
  this._header = value;
1947
- this.headers.forEach((text, index) => {
1948
- this._worksheet.getCell(index + 1, this.number).value = text;
1951
+ this.headers.forEach((cellValue, index) => {
1952
+ this._worksheet.getCell(index + 1, this.number).value = cellValue;
1949
1953
  });
1950
1954
  } else this._header = void 0;
1951
1955
  }
@@ -2132,8 +2136,8 @@ var ExcelTS = (function(exports) {
2132
2136
  });
2133
2137
  while (index < cols.length) {
2134
2138
  const col = cols[index++];
2135
- while (count < col.min) columns.push(new Column(worksheet, count++));
2136
- while (count <= col.max) columns.push(new Column(worksheet, count++, col));
2139
+ while (count < col.min) columns.push(new Column$1(worksheet, count++));
2140
+ while (count <= col.max) columns.push(new Column$1(worksheet, count++, col));
2137
2141
  }
2138
2142
  return columns.length ? columns : null;
2139
2143
  }
@@ -2274,7 +2278,7 @@ var ExcelTS = (function(exports) {
2274
2278
 
2275
2279
  //#endregion
2276
2280
  //#region src/doc/table.ts
2277
- var Column$1 = class {
2281
+ var Column = class {
2278
2282
  constructor(table, column, index) {
2279
2283
  this.table = table;
2280
2284
  this.column = column;
@@ -2519,7 +2523,7 @@ var ExcelTS = (function(exports) {
2519
2523
  }
2520
2524
  getColumn(colIndex) {
2521
2525
  const column = this.table.columns[colIndex];
2522
- return new Column$1(this, column, colIndex);
2526
+ return new Column(this, column, colIndex);
2523
2527
  }
2524
2528
  addColumn(column, values, colIndex) {
2525
2529
  this.cacheState();
@@ -13579,10 +13583,10 @@ var ExcelTS = (function(exports) {
13579
13583
  //#endregion
13580
13584
  //#region node_modules/.pnpm/buffer-xor@1.0.3/node_modules/buffer-xor/index.js
13581
13585
  var require_buffer_xor = /* @__PURE__ */ __commonJSMin(((exports, module) => {
13582
- var import_buffer$13 = require_buffer$1();
13586
+ var import_buffer$8 = require_buffer$1();
13583
13587
  module.exports = function xor(a, b) {
13584
13588
  var length = Math.min(a.length, b.length);
13585
- var buffer = new import_buffer$13.Buffer(length);
13589
+ var buffer = new import_buffer$8.Buffer(length);
13586
13590
  for (var i$1 = 0; i$1 < length; ++i$1) buffer[i$1] = a[i$1] ^ b[i$1];
13587
13591
  return buffer;
13588
13592
  };
@@ -13694,14 +13698,14 @@ var ExcelTS = (function(exports) {
13694
13698
  //#endregion
13695
13699
  //#region node_modules/.pnpm/browserify-aes@1.2.0/node_modules/browserify-aes/modes/ofb.js
13696
13700
  var require_ofb = /* @__PURE__ */ __commonJSMin(((exports) => {
13697
- var import_buffer$12 = require_buffer$1();
13701
+ var import_buffer$7 = require_buffer$1();
13698
13702
  var xor = require_buffer_xor();
13699
13703
  function getBlock(self$1) {
13700
13704
  self$1._prev = self$1._cipher.encryptBlock(self$1._prev);
13701
13705
  return self$1._prev;
13702
13706
  }
13703
13707
  exports.encrypt = function(self$1, chunk) {
13704
- while (self$1._cache.length < chunk.length) self$1._cache = import_buffer$12.Buffer.concat([self$1._cache, getBlock(self$1)]);
13708
+ while (self$1._cache.length < chunk.length) self$1._cache = import_buffer$7.Buffer.concat([self$1._cache, getBlock(self$1)]);
13705
13709
  var pad = self$1._cache.slice(0, chunk.length);
13706
13710
  self$1._cache = self$1._cache.slice(chunk.length);
13707
13711
  return xor(chunk, pad);
@@ -17411,7 +17415,7 @@ var ExcelTS = (function(exports) {
17411
17415
  //#endregion
17412
17416
  //#region node_modules/.pnpm/diffie-hellman@5.0.3/node_modules/diffie-hellman/lib/dh.js
17413
17417
  var require_dh = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17414
- var import_buffer$11 = require_buffer$1();
17418
+ var import_buffer$6 = require_buffer$1();
17415
17419
  var BN = require_bn$1();
17416
17420
  var millerRabin = new (require_mr())();
17417
17421
  var TWENTYFOUR = new BN(24);
@@ -17424,13 +17428,13 @@ var ExcelTS = (function(exports) {
17424
17428
  module.exports = DH;
17425
17429
  function setPublicKey(pub, enc) {
17426
17430
  enc = enc || "utf8";
17427
- if (!import_buffer$11.Buffer.isBuffer(pub)) pub = new import_buffer$11.Buffer(pub, enc);
17431
+ if (!import_buffer$6.Buffer.isBuffer(pub)) pub = new import_buffer$6.Buffer(pub, enc);
17428
17432
  this._pub = new BN(pub);
17429
17433
  return this;
17430
17434
  }
17431
17435
  function setPrivateKey(priv, enc) {
17432
17436
  enc = enc || "utf8";
17433
- if (!import_buffer$11.Buffer.isBuffer(priv)) priv = new import_buffer$11.Buffer(priv, enc);
17437
+ if (!import_buffer$6.Buffer.isBuffer(priv)) priv = new import_buffer$6.Buffer(priv, enc);
17434
17438
  this._priv = new BN(priv);
17435
17439
  return this;
17436
17440
  }
@@ -17490,12 +17494,12 @@ var ExcelTS = (function(exports) {
17490
17494
  DH.prototype.computeSecret = function(other) {
17491
17495
  other = new BN(other);
17492
17496
  other = other.toRed(this._prime);
17493
- var out = new import_buffer$11.Buffer(other.redPow(this._priv).fromRed().toArray());
17497
+ var out = new import_buffer$6.Buffer(other.redPow(this._priv).fromRed().toArray());
17494
17498
  var prime = this.getPrime();
17495
17499
  if (out.length < prime.length) {
17496
- var front = new import_buffer$11.Buffer(prime.length - out.length);
17500
+ var front = new import_buffer$6.Buffer(prime.length - out.length);
17497
17501
  front.fill(0);
17498
- out = import_buffer$11.Buffer.concat([front, out]);
17502
+ out = import_buffer$6.Buffer.concat([front, out]);
17499
17503
  }
17500
17504
  return out;
17501
17505
  };
@@ -17513,13 +17517,13 @@ var ExcelTS = (function(exports) {
17513
17517
  };
17514
17518
  DH.prototype.setGenerator = function(gen, enc) {
17515
17519
  enc = enc || "utf8";
17516
- if (!import_buffer$11.Buffer.isBuffer(gen)) gen = new import_buffer$11.Buffer(gen, enc);
17520
+ if (!import_buffer$6.Buffer.isBuffer(gen)) gen = new import_buffer$6.Buffer(gen, enc);
17517
17521
  this.__gen = gen;
17518
17522
  this._gen = new BN(gen);
17519
17523
  return this;
17520
17524
  };
17521
17525
  function formatReturnValue(bn, enc) {
17522
- var buf = new import_buffer$11.Buffer(bn.toArray());
17526
+ var buf = new import_buffer$6.Buffer(bn.toArray());
17523
17527
  if (!enc) return buf;
17524
17528
  else return buf.toString(enc);
17525
17529
  }
@@ -17528,12 +17532,12 @@ var ExcelTS = (function(exports) {
17528
17532
  //#endregion
17529
17533
  //#region node_modules/.pnpm/diffie-hellman@5.0.3/node_modules/diffie-hellman/browser.js
17530
17534
  var require_browser$4 = /* @__PURE__ */ __commonJSMin(((exports) => {
17531
- var import_buffer$10 = require_buffer$1();
17535
+ var import_buffer$5 = require_buffer$1();
17532
17536
  var generatePrime = require_generatePrime();
17533
17537
  var primes = require_primes();
17534
17538
  var DH = require_dh();
17535
17539
  function getDiffieHellman(mod) {
17536
- return new DH(new import_buffer$10.Buffer(primes[mod].prime, "hex"), new import_buffer$10.Buffer(primes[mod].gen, "hex"));
17540
+ return new DH(new import_buffer$5.Buffer(primes[mod].prime, "hex"), new import_buffer$5.Buffer(primes[mod].gen, "hex"));
17537
17541
  }
17538
17542
  var ENCODINGS = {
17539
17543
  "binary": true,
@@ -17541,13 +17545,13 @@ var ExcelTS = (function(exports) {
17541
17545
  "base64": true
17542
17546
  };
17543
17547
  function createDiffieHellman(prime, enc, generator, genc) {
17544
- if (import_buffer$10.Buffer.isBuffer(enc) || ENCODINGS[enc] === void 0) return createDiffieHellman(prime, "binary", enc, generator);
17548
+ if (import_buffer$5.Buffer.isBuffer(enc) || ENCODINGS[enc] === void 0) return createDiffieHellman(prime, "binary", enc, generator);
17545
17549
  enc = enc || "binary";
17546
17550
  genc = genc || "binary";
17547
- generator = generator || new import_buffer$10.Buffer([2]);
17548
- if (!import_buffer$10.Buffer.isBuffer(generator)) generator = new import_buffer$10.Buffer(generator, genc);
17551
+ generator = generator || new import_buffer$5.Buffer([2]);
17552
+ if (!import_buffer$5.Buffer.isBuffer(generator)) generator = new import_buffer$5.Buffer(generator, genc);
17549
17553
  if (typeof prime === "number") return new DH(generatePrime(prime, generator), generator, true);
17550
- if (!import_buffer$10.Buffer.isBuffer(prime)) prime = new import_buffer$10.Buffer(prime, enc);
17554
+ if (!import_buffer$5.Buffer.isBuffer(prime)) prime = new import_buffer$5.Buffer(prime, enc);
17551
17555
  return new DH(prime, generator, true);
17552
17556
  }
17553
17557
  exports.DiffieHellmanGroup = exports.createDiffieHellmanGroup = exports.getDiffieHellman = getDiffieHellman;
@@ -25839,7 +25843,7 @@ var ExcelTS = (function(exports) {
25839
25843
  //#endregion
25840
25844
  //#region node_modules/.pnpm/create-ecdh@4.0.4/node_modules/create-ecdh/browser.js
25841
25845
  var require_browser$2 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
25842
- var import_buffer$9 = require_buffer$1();
25846
+ var import_buffer$4 = require_buffer$1();
25843
25847
  var elliptic = require_elliptic();
25844
25848
  var BN = require_bn$1();
25845
25849
  module.exports = function createECDH(curve) {
@@ -25892,7 +25896,7 @@ var ExcelTS = (function(exports) {
25892
25896
  };
25893
25897
  ECDH.prototype.computeSecret = function(other, inenc, enc) {
25894
25898
  inenc = inenc || "utf8";
25895
- if (!import_buffer$9.Buffer.isBuffer(other)) other = new import_buffer$9.Buffer(other, inenc);
25899
+ if (!import_buffer$4.Buffer.isBuffer(other)) other = new import_buffer$4.Buffer(other, inenc);
25896
25900
  return formatReturnValue(this.curve.keyFromPublic(other).getPublic().mul(this.keys.getPrivate()).getX(), enc, this.curveType.byteLength);
25897
25901
  };
25898
25902
  ECDH.prototype.getPublicKey = function(enc, format$2) {
@@ -25906,13 +25910,13 @@ var ExcelTS = (function(exports) {
25906
25910
  };
25907
25911
  ECDH.prototype.setPublicKey = function(pub, enc) {
25908
25912
  enc = enc || "utf8";
25909
- if (!import_buffer$9.Buffer.isBuffer(pub)) pub = new import_buffer$9.Buffer(pub, enc);
25913
+ if (!import_buffer$4.Buffer.isBuffer(pub)) pub = new import_buffer$4.Buffer(pub, enc);
25910
25914
  this.keys._importPublic(pub);
25911
25915
  return this;
25912
25916
  };
25913
25917
  ECDH.prototype.setPrivateKey = function(priv, enc) {
25914
25918
  enc = enc || "utf8";
25915
- if (!import_buffer$9.Buffer.isBuffer(priv)) priv = new import_buffer$9.Buffer(priv, enc);
25919
+ if (!import_buffer$4.Buffer.isBuffer(priv)) priv = new import_buffer$4.Buffer(priv, enc);
25916
25920
  var _priv = new BN(priv);
25917
25921
  _priv = _priv.toString(16);
25918
25922
  this.keys = this.curve.genKeyPair();
@@ -25921,11 +25925,11 @@ var ExcelTS = (function(exports) {
25921
25925
  };
25922
25926
  function formatReturnValue(bn, enc, len) {
25923
25927
  if (!Array.isArray(bn)) bn = bn.toArray();
25924
- var buf = new import_buffer$9.Buffer(bn);
25928
+ var buf = new import_buffer$4.Buffer(bn);
25925
25929
  if (len && buf.length < len) {
25926
- var zeros = new import_buffer$9.Buffer(len - buf.length);
25930
+ var zeros = new import_buffer$4.Buffer(len - buf.length);
25927
25931
  zeros.fill(0);
25928
- buf = import_buffer$9.Buffer.concat([zeros, buf]);
25932
+ buf = import_buffer$4.Buffer.concat([zeros, buf]);
25929
25933
  }
25930
25934
  if (!enc) return buf;
25931
25935
  else return buf.toString(enc);
@@ -26300,21 +26304,21 @@ var ExcelTS = (function(exports) {
26300
26304
 
26301
26305
  //#endregion
26302
26306
  //#region src/utils/encryptor.ts
26303
- var import_buffer$8 = require_buffer$1();
26307
+ var import_buffer$3 = require_buffer$1();
26304
26308
  var import_crypto_browserify = /* @__PURE__ */ __toESM(require_crypto_browserify(), 1);
26305
26309
  const Encryptor = {
26306
26310
  hash(algorithm, ...buffers) {
26307
26311
  const hash = import_crypto_browserify.createHash(algorithm);
26308
- hash.update(import_buffer$8.Buffer.concat(buffers));
26312
+ hash.update(import_buffer$3.Buffer.concat(buffers));
26309
26313
  return hash.digest();
26310
26314
  },
26311
26315
  convertPasswordToHash(password, hashAlgorithm, saltValue, spinCount) {
26312
26316
  hashAlgorithm = hashAlgorithm.toLowerCase();
26313
26317
  if (import_crypto_browserify.getHashes().indexOf(hashAlgorithm) < 0) throw new Error(`Hash algorithm '${hashAlgorithm}' not supported!`);
26314
- const passwordBuffer = import_buffer$8.Buffer.from(password, "utf16le");
26315
- let key = this.hash(hashAlgorithm, import_buffer$8.Buffer.from(saltValue, "base64"), passwordBuffer);
26318
+ const passwordBuffer = import_buffer$3.Buffer.from(password, "utf16le");
26319
+ let key = this.hash(hashAlgorithm, import_buffer$3.Buffer.from(saltValue, "base64"), passwordBuffer);
26316
26320
  for (let i$1 = 0; i$1 < spinCount; i$1++) {
26317
- const iterator = import_buffer$8.Buffer.alloc(4);
26321
+ const iterator = import_buffer$3.Buffer.alloc(4);
26318
26322
  iterator.writeUInt32LE(i$1, 0);
26319
26323
  key = this.hash(hashAlgorithm, key, iterator);
26320
26324
  }
@@ -26451,12 +26455,6 @@ var ExcelTS = (function(exports) {
26451
26455
  }
26452
26456
  return result.sort();
26453
26457
  }
26454
- function objectFromProps(props, value = null) {
26455
- return props.reduce((result, property) => {
26456
- result[property] = value;
26457
- return result;
26458
- }, {});
26459
- }
26460
26458
  const textDecoder = new TextDecoder("utf-8");
26461
26459
  /**
26462
26460
  * Convert a Buffer or ArrayBuffer to a UTF-8 string
@@ -26469,49 +26467,117 @@ var ExcelTS = (function(exports) {
26469
26467
 
26470
26468
  //#endregion
26471
26469
  //#region src/doc/pivot-table.ts
26470
+ /**
26471
+ * Creates a PivotTableSource adapter from a Table object.
26472
+ * This allows Tables to be used as pivot table data sources with the same interface as Worksheets.
26473
+ */
26474
+ function createTableSourceAdapter(table) {
26475
+ const tableModel = table.model;
26476
+ if (tableModel.headerRow === false) throw new Error("Cannot create pivot table from a table without headers. Set headerRow: true on the table.");
26477
+ if (!tableModel.rows || tableModel.rows.length === 0) throw new Error("Cannot create pivot table from an empty table. Add data rows to the table.");
26478
+ const columnNames = tableModel.columns.map((col) => col.name);
26479
+ const nameSet = /* @__PURE__ */ new Set();
26480
+ for (const name of columnNames) {
26481
+ if (nameSet.has(name)) throw new Error(`Duplicate column name "${name}" found in table. Pivot tables require unique column names.`);
26482
+ nameSet.add(name);
26483
+ }
26484
+ const headerRow = [void 0, ...columnNames];
26485
+ const dataRows = tableModel.rows.map((row) => [void 0, ...row]);
26486
+ const tl = tableModel.tl;
26487
+ const startRow = tl.row;
26488
+ const startCol = tl.col;
26489
+ const endRow = startRow + tableModel.rows.length;
26490
+ const endCol = startCol + columnNames.length - 1;
26491
+ const shortRange = colCache.encode(startRow, startCol, endRow, endCol);
26492
+ return {
26493
+ name: tableModel.name,
26494
+ getRow(rowNumber) {
26495
+ if (rowNumber === 1) return { values: headerRow };
26496
+ const dataIndex = rowNumber - 2;
26497
+ if (dataIndex >= 0 && dataIndex < dataRows.length) return { values: dataRows[dataIndex] };
26498
+ return { values: [] };
26499
+ },
26500
+ getColumn(columnNumber) {
26501
+ if (columnNumber < 1 || columnNumber > columnNames.length) return { values: [] };
26502
+ const values = [];
26503
+ values[1] = columnNames[columnNumber - 1];
26504
+ for (let i$1 = 0; i$1 < tableModel.rows.length; i$1++) values[i$1 + 2] = tableModel.rows[i$1][columnNumber - 1];
26505
+ return { values };
26506
+ },
26507
+ getSheetValues() {
26508
+ const result = [];
26509
+ result[1] = headerRow;
26510
+ for (let i$1 = 0; i$1 < dataRows.length; i$1++) result[i$1 + 2] = dataRows[i$1];
26511
+ return result;
26512
+ },
26513
+ dimensions: { shortRange }
26514
+ };
26515
+ }
26516
+ /**
26517
+ * Resolves the data source from the model, supporting both sourceSheet and sourceTable.
26518
+ */
26519
+ function resolveSource(model) {
26520
+ if (model.sourceTable) return createTableSourceAdapter(model.sourceTable);
26521
+ return model.sourceSheet;
26522
+ }
26472
26523
  function makePivotTable(worksheet, model) {
26473
- validate(worksheet, model);
26474
- const { sourceSheet } = model;
26475
- const { rows, columns, values } = model;
26476
- const cacheFields = makeCacheFields(sourceSheet, [...rows, ...columns]);
26524
+ if (!model.sourceSheet && !model.sourceTable) throw new Error("Either sourceSheet or sourceTable must be provided.");
26525
+ if (model.sourceSheet && model.sourceTable) throw new Error("Cannot specify both sourceSheet and sourceTable. Choose one.");
26526
+ const source = resolveSource(model);
26527
+ validate(worksheet, model, source);
26528
+ const { rows, values } = model;
26529
+ const columns = model.columns ?? [];
26530
+ const cacheFields = makeCacheFields(source, [...rows, ...columns]);
26477
26531
  const nameToIndex = cacheFields.reduce((result, cacheField, index) => {
26478
26532
  result[cacheField.name] = index;
26479
26533
  return result;
26480
26534
  }, {});
26535
+ const rowIndices = rows.map((row) => nameToIndex[row]);
26536
+ const columnIndices = columns.map((column) => nameToIndex[column]);
26537
+ const valueIndices = values.map((value) => nameToIndex[value]);
26538
+ const tableNumber = worksheet.workbook.pivotTables.length + 1;
26481
26539
  return {
26482
- sourceSheet,
26483
- rows: rows.map((row) => nameToIndex[row]),
26484
- columns: columns.map((column) => nameToIndex[column]),
26485
- values: values.map((value) => nameToIndex[value]),
26486
- metric: "sum",
26540
+ source,
26541
+ rows: rowIndices,
26542
+ columns: columnIndices,
26543
+ values: valueIndices,
26544
+ metric: model.metric ?? "sum",
26487
26545
  cacheFields,
26488
- cacheId: "10"
26546
+ cacheId: String(10 + tableNumber - 1),
26547
+ applyWidthHeightFormats: model.applyWidthHeightFormats ?? "1",
26548
+ tableNumber
26489
26549
  };
26490
26550
  }
26491
- function validate(worksheet, model) {
26492
- if (worksheet.workbook.pivotTables.length === 1) throw new Error("A pivot table was already added. At this time, ExcelTS supports at most one pivot table per file.");
26493
- if (model.metric && model.metric !== "sum") throw new Error("Only the \"sum\" metric is supported at this time.");
26494
- const isInHeaderNames = objectFromProps(model.sourceSheet.getRow(1).values.slice(1), true);
26551
+ function validate(_worksheet, model, source) {
26552
+ if (model.metric && model.metric !== "sum" && model.metric !== "count") throw new Error("Only the \"sum\" and \"count\" metrics are supported at this time.");
26553
+ const columns = model.columns ?? [];
26554
+ const headerNames = source.getRow(1).values.slice(1);
26555
+ const headerNameSet = new Set(headerNames);
26495
26556
  for (const name of [
26496
26557
  ...model.rows,
26497
- ...model.columns,
26558
+ ...columns,
26498
26559
  ...model.values
26499
- ]) if (!isInHeaderNames[name]) throw new Error(`The header name "${name}" was not found in ${model.sourceSheet.name}.`);
26560
+ ]) if (!headerNameSet.has(name)) throw new Error(`The header name "${name}" was not found in ${source.name}.`);
26500
26561
  if (!model.rows.length) throw new Error("No pivot table rows specified.");
26501
- if (!model.columns.length) throw new Error("No pivot table columns specified.");
26502
- if (model.values.length !== 1) throw new Error("Exactly 1 value needs to be specified at this time.");
26562
+ if (model.values.length < 1) throw new Error("Must have at least one value.");
26563
+ if (model.values.length > 1 && columns.length > 0) throw new Error("It is currently not possible to have multiple values when columns are specified. Please either supply an empty array for columns or a single value.");
26503
26564
  }
26504
- function makeCacheFields(worksheet, fieldNamesWithSharedItems) {
26505
- const names = worksheet.getRow(1).values;
26506
- const nameToHasSharedItems = objectFromProps(fieldNamesWithSharedItems, true);
26565
+ function makeCacheFields(source, fieldNamesWithSharedItems) {
26566
+ const names = source.getRow(1).values;
26567
+ const sharedItemsFields = new Set(fieldNamesWithSharedItems);
26507
26568
  const aggregate = (columnIndex) => {
26508
- const columnValues = worksheet.getColumn(columnIndex).values.splice(2);
26509
- return toSortedArray(new Set(columnValues));
26569
+ const columnValues = source.getColumn(columnIndex).values;
26570
+ const uniqueValues = /* @__PURE__ */ new Set();
26571
+ for (let i$1 = 2; i$1 < columnValues.length; i$1++) {
26572
+ const v = columnValues[i$1];
26573
+ if (v !== null && v !== void 0) uniqueValues.add(v);
26574
+ }
26575
+ return toSortedArray(uniqueValues);
26510
26576
  };
26511
26577
  const result = [];
26512
26578
  for (const columnIndex of range(1, names.length)) {
26513
26579
  const name = names[columnIndex];
26514
- const sharedItems = nameToHasSharedItems[name] ? aggregate(columnIndex) : null;
26580
+ const sharedItems = sharedItemsFields.has(name) ? aggregate(columnIndex) : null;
26515
26581
  result.push({
26516
26582
  name,
26517
26583
  sharedItems
@@ -26692,7 +26758,7 @@ var ExcelTS = (function(exports) {
26692
26758
  let count = 1;
26693
26759
  const columns = this._columns = [];
26694
26760
  value.forEach((defn) => {
26695
- const column = new Column(this, count++, false);
26761
+ const column = new Column$1(this, count++, false);
26696
26762
  columns.push(column);
26697
26763
  column.defn = defn;
26698
26764
  });
@@ -26722,7 +26788,7 @@ var ExcelTS = (function(exports) {
26722
26788
  if (!this._columns) this._columns = [];
26723
26789
  if (colNum > this._columns.length) {
26724
26790
  let n = this._columns.length + 1;
26725
- while (n <= colNum) this._columns.push(new Column(this, n++));
26791
+ while (n <= colNum) this._columns.push(new Column$1(this, n++));
26726
26792
  }
26727
26793
  return this._columns[colNum - 1];
26728
26794
  }
@@ -27170,8 +27236,6 @@ var ExcelTS = (function(exports) {
27170
27236
  return Object.values(this.tables);
27171
27237
  }
27172
27238
  addPivotTable(model) {
27173
- console.warn(`Warning: Pivot Table support is experimental.
27174
- Please leave feedback at https://github.com/excelts/excelts/discussions/2575`);
27175
27239
  const pivotTable = makePivotTable(this, model);
27176
27240
  this.pivotTables.push(pivotTable);
27177
27241
  this.workbook.pivotTables.push(pivotTable);
@@ -27209,7 +27273,7 @@ Please leave feedback at https://github.com/excelts/excelts/discussions/2575`);
27209
27273
  pivotTables: this.pivotTables,
27210
27274
  conditionalFormattings: this.conditionalFormattings
27211
27275
  };
27212
- model.cols = Column.toModel(this.columns || []);
27276
+ model.cols = Column$1.toModel(this.columns || []);
27213
27277
  const rows = model.rows = [];
27214
27278
  const dimensions = model.dimensions = new Range();
27215
27279
  this._rows.forEach((row) => {
@@ -27240,7 +27304,7 @@ Please leave feedback at https://github.com/excelts/excelts/discussions/2575`);
27240
27304
  }
27241
27305
  set model(value) {
27242
27306
  this.name = value.name;
27243
- this._columns = Column.fromModel(this, value.cols);
27307
+ this._columns = Column$1.fromModel(this, value.cols);
27244
27308
  this._parseRows(value);
27245
27309
  this._parseMergeCells(value);
27246
27310
  this.dataValidations = new DataValidations(value.dataValidations);
@@ -33085,7 +33149,7 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
33085
33149
  //#endregion
33086
33150
  //#region node_modules/.pnpm/browserify-zlib@0.2.0/node_modules/browserify-zlib/lib/binding.js
33087
33151
  var require_binding = /* @__PURE__ */ __commonJSMin(((exports) => {
33088
- var import_buffer$7 = require_buffer$1();
33152
+ var import_buffer$2 = require_buffer$1();
33089
33153
  init_process();
33090
33154
  var assert = require_assert();
33091
33155
  var Zstream = require_zstream();
@@ -33151,7 +33215,7 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
33151
33215
  this.write_in_progress = true;
33152
33216
  if (flush !== exports.Z_NO_FLUSH && flush !== exports.Z_PARTIAL_FLUSH && flush !== exports.Z_SYNC_FLUSH && flush !== exports.Z_FULL_FLUSH && flush !== exports.Z_FINISH && flush !== exports.Z_BLOCK) throw new Error("Invalid flush value");
33153
33217
  if (input == null) {
33154
- input = import_buffer$7.Buffer.alloc(0);
33218
+ input = import_buffer$2.Buffer.alloc(0);
33155
33219
  in_len = 0;
33156
33220
  in_off = 0;
33157
33221
  }
@@ -33759,7 +33823,7 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
33759
33823
 
33760
33824
  //#endregion
33761
33825
  //#region src/utils/zip/crc32.ts
33762
- var import_stream_browserify$1 = require_stream_browserify();
33826
+ var import_stream_browserify = require_stream_browserify();
33763
33827
  var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
33764
33828
  init_process();
33765
33829
  const isNode$1 = typeof api !== "undefined" && api.versions?.node;
@@ -33815,7 +33879,6 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
33815
33879
 
33816
33880
  //#endregion
33817
33881
  //#region src/utils/zip/compress.ts
33818
- var import_buffer$6 = require_buffer$1();
33819
33882
  init_process();
33820
33883
  const isNode = typeof api !== "undefined" && api.versions?.node;
33821
33884
  let _zlib = null;
@@ -33865,7 +33928,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
33865
33928
  if (level === 0) return data;
33866
33929
  const zlib = await ensureZlib();
33867
33930
  if (zlib && typeof zlib.deflateRawSync === "function") {
33868
- const result = zlib.deflateRawSync(import_buffer$6.Buffer.from(data), { level });
33931
+ const result = zlib.deflateRawSync(import_buffer$3.Buffer.from(data), { level });
33869
33932
  return new Uint8Array(result.buffer, result.byteOffset, result.byteLength);
33870
33933
  }
33871
33934
  if (typeof CompressionStream !== "undefined") return compressWithCompressionStream(data);
@@ -33886,7 +33949,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
33886
33949
  if (level === 0) return data;
33887
33950
  const zlib = getZlib();
33888
33951
  if (!zlib || typeof zlib.deflateRawSync !== "function") throw new Error("Synchronous compression is only available in Node.js environment");
33889
- const result = zlib.deflateRawSync(import_buffer$6.Buffer.from(data), { level });
33952
+ const result = zlib.deflateRawSync(import_buffer$3.Buffer.from(data), { level });
33890
33953
  return new Uint8Array(result.buffer, result.byteOffset, result.byteLength);
33891
33954
  }
33892
33955
  /**
@@ -34131,10 +34194,9 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34131
34194
 
34132
34195
  //#endregion
34133
34196
  //#region src/utils/string-buf.ts
34134
- var import_buffer$5 = require_buffer$1();
34135
34197
  var StringBuf = class {
34136
34198
  constructor(options) {
34137
- this._buf = import_buffer$5.Buffer.alloc(options && options.size || 16384);
34199
+ this._buf = import_buffer$3.Buffer.alloc(options && options.size || 16384);
34138
34200
  this._encoding = options && options.encoding || "utf8";
34139
34201
  this._inPos = 0;
34140
34202
  this._buffer = void 0;
@@ -34150,7 +34212,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34150
34212
  }
34151
34213
  toBuffer() {
34152
34214
  if (!this._buffer) {
34153
- this._buffer = import_buffer$5.Buffer.alloc(this.length);
34215
+ this._buffer = import_buffer$3.Buffer.alloc(this.length);
34154
34216
  this._buf.copy(this._buffer, 0, 0, this.length);
34155
34217
  }
34156
34218
  return this._buffer;
@@ -34163,7 +34225,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34163
34225
  _grow(min) {
34164
34226
  let size = this._buf.length * 2;
34165
34227
  while (size < min) size *= 2;
34166
- const buf = import_buffer$5.Buffer.alloc(size);
34228
+ const buf = import_buffer$3.Buffer.alloc(size);
34167
34229
  this._buf.copy(buf, 0);
34168
34230
  this._buf = buf;
34169
34231
  }
@@ -34188,7 +34250,6 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34188
34250
 
34189
34251
  //#endregion
34190
34252
  //#region src/utils/stream-buf.ts
34191
- var import_buffer$4 = require_buffer$1();
34192
34253
  var StringChunk = class {
34193
34254
  constructor(data, encoding) {
34194
34255
  this._data = data;
@@ -34201,7 +34262,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34201
34262
  return this.toBuffer().copy(target, targetOffset, offset, length);
34202
34263
  }
34203
34264
  toBuffer() {
34204
- if (!this._buffer) this._buffer = import_buffer$4.Buffer.from(this._data, this._encoding);
34265
+ if (!this._buffer) this._buffer = import_buffer$3.Buffer.from(this._data, this._encoding);
34205
34266
  return this._buffer;
34206
34267
  }
34207
34268
  };
@@ -34236,13 +34297,13 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34236
34297
  var ReadWriteBuf = class {
34237
34298
  constructor(size) {
34238
34299
  this.size = size;
34239
- this.buffer = import_buffer$4.Buffer.alloc(size);
34300
+ this.buffer = import_buffer$3.Buffer.alloc(size);
34240
34301
  this.iRead = 0;
34241
34302
  this.iWrite = 0;
34242
34303
  }
34243
34304
  toBuffer() {
34244
34305
  if (this.iRead === 0 && this.iWrite === this.size) return this.buffer;
34245
- const buf = import_buffer$4.Buffer.alloc(this.iWrite - this.iRead);
34306
+ const buf = import_buffer$3.Buffer.alloc(this.iWrite - this.iRead);
34246
34307
  this.buffer.copy(buf, 0, this.iRead, this.iWrite);
34247
34308
  return buf;
34248
34309
  }
@@ -34263,7 +34324,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34263
34324
  this.iRead = this.iWrite;
34264
34325
  return buf;
34265
34326
  }
34266
- buf = import_buffer$4.Buffer.alloc(size);
34327
+ buf = import_buffer$3.Buffer.alloc(size);
34267
34328
  this.buffer.copy(buf, 0, this.iRead, size);
34268
34329
  this.iRead += size;
34269
34330
  return buf;
@@ -34277,7 +34338,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34277
34338
  };
34278
34339
  const StreamBuf = function(options) {
34279
34340
  if (!(this instanceof StreamBuf)) return new StreamBuf(options);
34280
- import_stream_browserify$1.Duplex.call(this, options);
34341
+ import_stream_browserify.Duplex.call(this, options);
34281
34342
  options = options || {};
34282
34343
  this.bufSize = options.bufSize || 1024 * 1024;
34283
34344
  this.buffers = [];
@@ -34289,12 +34350,12 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34289
34350
  this.paused = false;
34290
34351
  this.encoding = null;
34291
34352
  };
34292
- inherits(StreamBuf, import_stream_browserify$1.Duplex, {
34353
+ inherits(StreamBuf, import_stream_browserify.Duplex, {
34293
34354
  toBuffer() {
34294
34355
  switch (this.buffers.length) {
34295
34356
  case 0: return null;
34296
34357
  case 1: return this.buffers[0].toBuffer();
34297
- default: return import_buffer$4.Buffer.concat(this.buffers.map((rwBuf) => rwBuf.toBuffer()));
34358
+ default: return import_buffer$3.Buffer.concat(this.buffers.map((rwBuf) => rwBuf.toBuffer()));
34298
34359
  }
34299
34360
  },
34300
34361
  _getWritableBuffer() {
@@ -34332,9 +34393,9 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34332
34393
  callback = callback || nop;
34333
34394
  let chunk;
34334
34395
  if (data instanceof StringBuf || data && data.constructor?.name === "StringBuf") chunk = new StringBufChunk(data);
34335
- else if (import_buffer$4.Buffer.isBuffer(data)) chunk = new BufferChunk(data);
34336
- else if (ArrayBuffer.isView(data)) chunk = new BufferChunk(import_buffer$4.Buffer.from(data.buffer, data.byteOffset, data.byteLength));
34337
- else if (data instanceof ArrayBuffer) chunk = new BufferChunk(import_buffer$4.Buffer.from(data));
34396
+ else if (import_buffer$3.Buffer.isBuffer(data)) chunk = new BufferChunk(data);
34397
+ else if (ArrayBuffer.isView(data)) chunk = new BufferChunk(import_buffer$3.Buffer.from(data.buffer, data.byteOffset, data.byteLength));
34398
+ else if (data instanceof ArrayBuffer) chunk = new BufferChunk(import_buffer$3.Buffer.from(data));
34338
34399
  else if (typeof data === "string" || data instanceof String) chunk = new StringChunk(String(data), encoding);
34339
34400
  else throw new Error("Chunk must be one of type String, Buffer, Uint8Array, ArrayBuffer or StringBuf.");
34340
34401
  if (this.pipes.length) if (this.batch) {
@@ -34389,11 +34450,11 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34389
34450
  buffers.push(buffer);
34390
34451
  if (first.eod && first.full) this.buffers.shift();
34391
34452
  }
34392
- return import_buffer$4.Buffer.concat(buffers);
34453
+ return import_buffer$3.Buffer.concat(buffers);
34393
34454
  }
34394
34455
  buffers = this.buffers.map((buf) => buf.toBuffer()).filter(Boolean);
34395
34456
  this.buffers = [];
34396
- return import_buffer$4.Buffer.concat(buffers);
34457
+ return import_buffer$3.Buffer.concat(buffers);
34397
34458
  },
34398
34459
  setEncoding(encoding) {
34399
34460
  this.encoding = encoding;
@@ -34425,7 +34486,6 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34425
34486
 
34426
34487
  //#endregion
34427
34488
  //#region src/utils/zip-stream.ts
34428
- var import_buffer$3 = require_buffer$1();
34429
34489
  var ZipWriter = class extends import_events.default.EventEmitter {
34430
34490
  constructor(options) {
34431
34491
  super();
@@ -38998,27 +39058,28 @@ ${XMLNS_NAMESPACE}.`);
38998
39058
  PartName: "/xl/workbook.xml",
38999
39059
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"
39000
39060
  });
39001
- model.worksheets.forEach((worksheet) => {
39002
- const name = `/xl/worksheets/sheet${worksheet.id}.xml`;
39061
+ model.worksheets.forEach((worksheet, index) => {
39062
+ const name = `/xl/worksheets/sheet${worksheet.fileIndex || index + 1}.xml`;
39003
39063
  xmlStream.leafNode("Override", {
39004
39064
  PartName: name,
39005
39065
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"
39006
39066
  });
39007
39067
  });
39008
- if ((model.pivotTables || []).length) {
39068
+ if ((model.pivotTables || []).length) (model.pivotTables || []).forEach((pivotTable) => {
39069
+ const n = pivotTable.tableNumber;
39009
39070
  xmlStream.leafNode("Override", {
39010
- PartName: "/xl/pivotCache/pivotCacheDefinition1.xml",
39071
+ PartName: `/xl/pivotCache/pivotCacheDefinition${n}.xml`,
39011
39072
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml"
39012
39073
  });
39013
39074
  xmlStream.leafNode("Override", {
39014
- PartName: "/xl/pivotCache/pivotCacheRecords1.xml",
39075
+ PartName: `/xl/pivotCache/pivotCacheRecords${n}.xml`,
39015
39076
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml"
39016
39077
  });
39017
39078
  xmlStream.leafNode("Override", {
39018
- PartName: "/xl/pivotTables/pivotTable1.xml",
39079
+ PartName: `/xl/pivotTables/pivotTable${n}.xml`,
39019
39080
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml"
39020
39081
  });
39021
- }
39082
+ });
39022
39083
  xmlStream.leafNode("Override", {
39023
39084
  PartName: "/xl/theme/theme1.xml",
39024
39085
  ContentType: "application/vnd.openxmlformats-officedocument.theme+xml"
@@ -39539,6 +39600,7 @@ ${XMLNS_NAMESPACE}.`);
39539
39600
  calcProperties: {}
39540
39601
  };
39541
39602
  if (this.map.definedNames.model) this.model.definedNames = this.map.definedNames.model;
39603
+ if (this.map.pivotCaches.model && this.map.pivotCaches.model.length > 0) this.model.pivotCaches = this.map.pivotCaches.model;
39542
39604
  return false;
39543
39605
  default: return true;
39544
39606
  }
@@ -39935,6 +39997,10 @@ ${XMLNS_NAMESPACE}.`);
39935
39997
  model.type = Enums.ValueType.Error;
39936
39998
  model.value = { error: model.value };
39937
39999
  break;
40000
+ case "d":
40001
+ model.type = Enums.ValueType.Date;
40002
+ model.value = new Date(model.value);
40003
+ break;
39938
40004
  default:
39939
40005
  model.type = Enums.ValueType.Number;
39940
40006
  model.value = parseFloat(model.value);
@@ -42521,10 +42587,12 @@ ${XMLNS_NAMESPACE}.`);
42521
42587
  if (style) column.dxfId = options.styles.addDxfStyle(style);
42522
42588
  });
42523
42589
  });
42524
- if ((model.pivotTables || []).length) rels.push({
42525
- Id: nextRid(rels),
42526
- Type: RelType.PivotTable,
42527
- Target: "../pivotTables/pivotTable1.xml"
42590
+ (model.pivotTables || []).forEach((pivotTable) => {
42591
+ rels.push({
42592
+ Id: nextRid(rels),
42593
+ Type: RelType.PivotTable,
42594
+ Target: `../pivotTables/pivotTable${pivotTable.tableNumber}.xml`
42595
+ });
42528
42596
  });
42529
42597
  this.map.extLst.prepare(model, options);
42530
42598
  }
@@ -42695,6 +42763,13 @@ ${XMLNS_NAMESPACE}.`);
42695
42763
  const rel = rels[tablePart.rId];
42696
42764
  return options.tables[rel.Target];
42697
42765
  });
42766
+ model.pivotTables = [];
42767
+ (model.relationships || []).forEach((rel) => {
42768
+ if (rel.Type === RelType.PivotTable && options.pivotTables) {
42769
+ const pivotTable = options.pivotTables[rel.Target];
42770
+ if (pivotTable) model.pivotTables.push(pivotTable);
42771
+ }
42772
+ });
42698
42773
  delete model.relationships;
42699
42774
  delete model.hyperlinks;
42700
42775
  delete model.comments;
@@ -43782,50 +43857,164 @@ ${XMLNS_NAMESPACE}.`);
43782
43857
  constructor() {
43783
43858
  super();
43784
43859
  this.map = {};
43860
+ this.model = null;
43861
+ this.currentRecord = null;
43785
43862
  }
43786
43863
  prepare(_model) {}
43787
43864
  get tag() {
43788
43865
  return "pivotCacheRecords";
43789
43866
  }
43867
+ reset() {
43868
+ this.model = null;
43869
+ this.currentRecord = null;
43870
+ }
43871
+ /**
43872
+ * Render pivot cache records XML.
43873
+ * Supports both newly created models (with PivotTableSource) and loaded models.
43874
+ */
43790
43875
  render(xmlStream, model) {
43791
- const { sourceSheet, cacheFields } = model;
43792
- const sourceBodyRows = sourceSheet.getSheetValues().slice(2);
43876
+ if (model.isLoaded || !("source" in model)) this.renderLoaded(xmlStream, model);
43877
+ else this.renderNew(xmlStream, model);
43878
+ }
43879
+ /**
43880
+ * Render newly created pivot cache records
43881
+ */
43882
+ renderNew(xmlStream, model) {
43883
+ const { source, cacheFields } = model;
43884
+ const sourceBodyRows = source.getSheetValues().slice(2);
43793
43885
  xmlStream.openXml(XmlStream.StdDocAttributes);
43794
43886
  xmlStream.openNode(this.tag, {
43795
43887
  ...PivotCacheRecordsXform.PIVOT_CACHE_RECORDS_ATTRIBUTES,
43796
43888
  count: sourceBodyRows.length
43797
43889
  });
43798
- xmlStream.writeXml(renderTable());
43890
+ xmlStream.writeXml(this.renderTableNew(sourceBodyRows, cacheFields));
43799
43891
  xmlStream.closeNode();
43800
- function renderTable() {
43801
- return sourceBodyRows.map((row) => {
43802
- return [...renderRowLines(row.slice(1))].join("");
43803
- }).join("");
43804
- }
43805
- function* renderRowLines(row) {
43806
- yield "\n <r>";
43807
- for (const [index, cellValue] of row.entries()) {
43808
- yield "\n ";
43809
- yield renderCell(cellValue, cacheFields[index].sharedItems);
43892
+ }
43893
+ /**
43894
+ * Render loaded pivot cache records
43895
+ */
43896
+ renderLoaded(xmlStream, model) {
43897
+ xmlStream.openXml(XmlStream.StdDocAttributes);
43898
+ xmlStream.openNode(this.tag, {
43899
+ ...PivotCacheRecordsXform.PIVOT_CACHE_RECORDS_ATTRIBUTES,
43900
+ count: model.count
43901
+ });
43902
+ for (const record of model.records) {
43903
+ xmlStream.writeXml("\n <r>");
43904
+ for (const value of record) {
43905
+ xmlStream.writeXml("\n ");
43906
+ xmlStream.writeXml(this.renderRecordValue(value));
43810
43907
  }
43811
- yield "\n </r>";
43908
+ xmlStream.writeXml("\n </r>");
43909
+ }
43910
+ xmlStream.closeNode();
43911
+ }
43912
+ /**
43913
+ * Render a single record value to XML
43914
+ */
43915
+ renderRecordValue(value) {
43916
+ switch (value.type) {
43917
+ case "x": return `<x v="${value.value}" />`;
43918
+ case "n": return `<n v="${value.value}" />`;
43919
+ case "s": return `<s v="${xmlEncode(String(value.value))}" />`;
43920
+ case "b": return `<b v="${value.value ? "1" : "0"}" />`;
43921
+ case "m": return "<m />";
43922
+ case "d": return `<d v="${value.value.toISOString()}" />`;
43923
+ case "e": return `<e v="${value.value}" />`;
43924
+ default: return "<m />";
43812
43925
  }
43813
- function renderCell(value, sharedItems) {
43814
- if (sharedItems === null) {
43815
- if (Number.isFinite(value)) return `<n v="${value}" />`;
43816
- return `<s v="${value}" />`;
43926
+ }
43927
+ renderTableNew(sourceBodyRows, cacheFields) {
43928
+ const parts = [];
43929
+ for (const row of sourceBodyRows) {
43930
+ const realRow = row.slice(1);
43931
+ parts.push("\n <r>");
43932
+ for (let i$1 = 0; i$1 < realRow.length; i$1++) {
43933
+ parts.push("\n ");
43934
+ parts.push(this.renderCellNew(realRow[i$1], cacheFields[i$1].sharedItems));
43817
43935
  }
43818
- const sharedItemsIndex = sharedItems.indexOf(value);
43819
- if (sharedItemsIndex < 0) throw new Error(`${JSON.stringify(value)} not in sharedItems ${JSON.stringify(sharedItems)}`);
43820
- return `<x v="${sharedItemsIndex}" />`;
43936
+ parts.push("\n </r>");
43821
43937
  }
43938
+ return parts.join("");
43822
43939
  }
43823
- parseOpen(_node) {
43824
- return false;
43940
+ renderCellNew(value, sharedItems) {
43941
+ if (value === null || value === void 0) return "<m />";
43942
+ if (sharedItems === null) {
43943
+ if (Number.isFinite(value)) return `<n v="${value}" />`;
43944
+ return `<s v="${xmlEncode(String(value))}" />`;
43945
+ }
43946
+ const sharedItemsIndex = sharedItems.indexOf(value);
43947
+ if (sharedItemsIndex < 0) throw new Error(`${JSON.stringify(value)} not in sharedItems ${JSON.stringify(sharedItems)}`);
43948
+ return `<x v="${sharedItemsIndex}" />`;
43949
+ }
43950
+ parseOpen(node) {
43951
+ const { name, attributes } = node;
43952
+ switch (name) {
43953
+ case this.tag:
43954
+ this.reset();
43955
+ this.model = {
43956
+ records: [],
43957
+ count: parseInt(attributes.count || "0", 10),
43958
+ isLoaded: true
43959
+ };
43960
+ break;
43961
+ case "r":
43962
+ this.currentRecord = [];
43963
+ break;
43964
+ case "x":
43965
+ if (this.currentRecord) this.currentRecord.push({
43966
+ type: "x",
43967
+ value: parseInt(attributes.v || "0", 10)
43968
+ });
43969
+ break;
43970
+ case "n":
43971
+ if (this.currentRecord) this.currentRecord.push({
43972
+ type: "n",
43973
+ value: parseFloat(attributes.v || "0")
43974
+ });
43975
+ break;
43976
+ case "s":
43977
+ if (this.currentRecord) this.currentRecord.push({
43978
+ type: "s",
43979
+ value: xmlDecode(attributes.v || "")
43980
+ });
43981
+ break;
43982
+ case "b":
43983
+ if (this.currentRecord) this.currentRecord.push({
43984
+ type: "b",
43985
+ value: attributes.v === "1"
43986
+ });
43987
+ break;
43988
+ case "m":
43989
+ if (this.currentRecord) this.currentRecord.push({ type: "m" });
43990
+ break;
43991
+ case "d":
43992
+ if (this.currentRecord) this.currentRecord.push({
43993
+ type: "d",
43994
+ value: new Date(attributes.v || "")
43995
+ });
43996
+ break;
43997
+ case "e":
43998
+ if (this.currentRecord) this.currentRecord.push({
43999
+ type: "e",
44000
+ value: attributes.v || ""
44001
+ });
44002
+ break;
44003
+ }
44004
+ return true;
43825
44005
  }
43826
44006
  parseText(_text) {}
43827
- parseClose(_name) {
43828
- return false;
44007
+ parseClose(name) {
44008
+ switch (name) {
44009
+ case this.tag: return false;
44010
+ case "r":
44011
+ if (this.model && this.currentRecord) {
44012
+ this.model.records.push(this.currentRecord);
44013
+ this.currentRecord = null;
44014
+ }
44015
+ break;
44016
+ }
44017
+ return true;
43829
44018
  }
43830
44019
  reconcile(_model, _options) {}
43831
44020
  static {
@@ -43847,30 +44036,157 @@ ${XMLNS_NAMESPACE}.`);
43847
44036
  this.sharedItems = sharedItems;
43848
44037
  }
43849
44038
  render() {
43850
- if (this.sharedItems === null) return `<cacheField name="${this.name}" numFmtId="0">
44039
+ const escapedName = xmlEncode(this.name);
44040
+ if (this.sharedItems === null) return `<cacheField name="${escapedName}" numFmtId="0">
43851
44041
  <sharedItems containsSemiMixedTypes="0" containsString="0" containsNumber="1" containsInteger="1" />
43852
44042
  </cacheField>`;
43853
- return `<cacheField name="${this.name}" numFmtId="0">
44043
+ return `<cacheField name="${escapedName}" numFmtId="0">
43854
44044
  <sharedItems count="${this.sharedItems.length}">
43855
- ${this.sharedItems.map((item) => `<s v="${item}" />`).join("")}
44045
+ ${this.sharedItems.map((item) => `<s v="${xmlEncode(String(item))}" />`).join("")}
43856
44046
  </sharedItems>
43857
44047
  </cacheField>`;
43858
44048
  }
43859
44049
  };
43860
44050
 
44051
+ //#endregion
44052
+ //#region src/xlsx/xform/pivot-table/cache-field-xform.ts
44053
+ /**
44054
+ * Xform for parsing individual <cacheField> elements within a pivot cache definition.
44055
+ *
44056
+ * Example XML:
44057
+ * ```xml
44058
+ * <cacheField name="Category" numFmtId="0">
44059
+ * <sharedItems count="3">
44060
+ * <s v="A" />
44061
+ * <s v="B" />
44062
+ * <s v="C" />
44063
+ * </sharedItems>
44064
+ * </cacheField>
44065
+ *
44066
+ * <cacheField name="Value" numFmtId="0">
44067
+ * <sharedItems containsSemiMixedTypes="0" containsString="0"
44068
+ * containsNumber="1" containsInteger="1" minValue="5" maxValue="45" />
44069
+ * </cacheField>
44070
+ * ```
44071
+ */
44072
+ var CacheFieldXform = class extends BaseXform {
44073
+ constructor() {
44074
+ super();
44075
+ this.model = null;
44076
+ this.inSharedItems = false;
44077
+ }
44078
+ get tag() {
44079
+ return "cacheField";
44080
+ }
44081
+ reset() {
44082
+ this.model = null;
44083
+ this.inSharedItems = false;
44084
+ }
44085
+ parseOpen(node) {
44086
+ const { name, attributes } = node;
44087
+ switch (name) {
44088
+ case "cacheField":
44089
+ this.model = {
44090
+ name: xmlDecode(attributes.name || ""),
44091
+ sharedItems: null
44092
+ };
44093
+ break;
44094
+ case "sharedItems":
44095
+ this.inSharedItems = true;
44096
+ if (attributes.containsNumber === "1" || attributes.containsInteger === "1") {
44097
+ if (this.model) {
44098
+ this.model.containsNumber = attributes.containsNumber === "1";
44099
+ this.model.containsInteger = attributes.containsInteger === "1";
44100
+ if (attributes.minValue !== void 0) this.model.minValue = parseFloat(attributes.minValue);
44101
+ if (attributes.maxValue !== void 0) this.model.maxValue = parseFloat(attributes.maxValue);
44102
+ this.model.sharedItems = null;
44103
+ }
44104
+ } else if (this.model) {
44105
+ if (parseInt(attributes.count || "0", 10) > 0) this.model.sharedItems = [];
44106
+ }
44107
+ break;
44108
+ case "s":
44109
+ if (this.inSharedItems && this.model?.sharedItems !== null) {
44110
+ const value = xmlDecode(attributes.v || "");
44111
+ this.model.sharedItems.push(value);
44112
+ }
44113
+ break;
44114
+ case "n":
44115
+ if (this.inSharedItems && this.model?.sharedItems !== null) {
44116
+ const value = parseFloat(attributes.v || "0");
44117
+ this.model.sharedItems.push(value);
44118
+ }
44119
+ break;
44120
+ case "b":
44121
+ if (this.inSharedItems && this.model?.sharedItems !== null) {
44122
+ const value = attributes.v === "1";
44123
+ this.model.sharedItems.push(value);
44124
+ }
44125
+ break;
44126
+ case "e":
44127
+ if (this.inSharedItems && this.model?.sharedItems !== null) {
44128
+ const value = `#${attributes.v || "ERROR!"}`;
44129
+ this.model.sharedItems.push(value);
44130
+ }
44131
+ break;
44132
+ case "m":
44133
+ if (this.inSharedItems && this.model?.sharedItems !== null) this.model.sharedItems.push(null);
44134
+ break;
44135
+ case "d":
44136
+ if (this.inSharedItems && this.model?.sharedItems !== null) {
44137
+ const value = new Date(attributes.v || "");
44138
+ this.model.sharedItems.push(value);
44139
+ }
44140
+ break;
44141
+ }
44142
+ return true;
44143
+ }
44144
+ parseText(_text) {}
44145
+ parseClose(name) {
44146
+ switch (name) {
44147
+ case "cacheField": return false;
44148
+ case "sharedItems":
44149
+ this.inSharedItems = false;
44150
+ break;
44151
+ }
44152
+ return true;
44153
+ }
44154
+ };
44155
+
43861
44156
  //#endregion
43862
44157
  //#region src/xlsx/xform/pivot-table/pivot-cache-definition-xform.ts
43863
44158
  var PivotCacheDefinitionXform = class PivotCacheDefinitionXform extends BaseXform {
43864
44159
  constructor() {
43865
44160
  super();
43866
44161
  this.map = {};
44162
+ this.model = null;
44163
+ this.currentCacheField = null;
44164
+ this.inCacheFields = false;
44165
+ this.inCacheSource = false;
43867
44166
  }
43868
44167
  prepare(_model) {}
43869
44168
  get tag() {
43870
44169
  return "pivotCacheDefinition";
43871
44170
  }
44171
+ reset() {
44172
+ this.model = null;
44173
+ this.currentCacheField = null;
44174
+ this.inCacheFields = false;
44175
+ this.inCacheSource = false;
44176
+ }
44177
+ /**
44178
+ * Render pivot cache definition XML.
44179
+ * Supports both newly created models (with PivotTableSource) and loaded models.
44180
+ */
43872
44181
  render(xmlStream, model) {
43873
- const { sourceSheet, cacheFields } = model;
44182
+ if (model.isLoaded || !("source" in model)) this.renderLoaded(xmlStream, model);
44183
+ else this.renderNew(xmlStream, model);
44184
+ }
44185
+ /**
44186
+ * Render newly created pivot cache definition
44187
+ */
44188
+ renderNew(xmlStream, model) {
44189
+ const { source, cacheFields } = model;
43874
44190
  xmlStream.openXml(XmlStream.StdDocAttributes);
43875
44191
  xmlStream.openNode(this.tag, {
43876
44192
  ...PivotCacheDefinitionXform.PIVOT_CACHE_DEFINITION_ATTRIBUTES,
@@ -43885,8 +44201,8 @@ ${XMLNS_NAMESPACE}.`);
43885
44201
  });
43886
44202
  xmlStream.openNode("cacheSource", { type: "worksheet" });
43887
44203
  xmlStream.leafNode("worksheetSource", {
43888
- ref: sourceSheet.dimensions.shortRange,
43889
- sheet: sourceSheet.name
44204
+ ref: source.dimensions.shortRange,
44205
+ sheet: source.name
43890
44206
  });
43891
44207
  xmlStream.closeNode();
43892
44208
  xmlStream.openNode("cacheFields", { count: cacheFields.length });
@@ -43894,12 +44210,98 @@ ${XMLNS_NAMESPACE}.`);
43894
44210
  xmlStream.closeNode();
43895
44211
  xmlStream.closeNode();
43896
44212
  }
43897
- parseOpen(_node) {
43898
- return false;
44213
+ /**
44214
+ * Render loaded pivot cache definition (preserving original structure)
44215
+ */
44216
+ renderLoaded(xmlStream, model) {
44217
+ const { cacheFields, sourceRef, sourceSheet, recordCount } = model;
44218
+ xmlStream.openXml(XmlStream.StdDocAttributes);
44219
+ xmlStream.openNode(this.tag, {
44220
+ ...PivotCacheDefinitionXform.PIVOT_CACHE_DEFINITION_ATTRIBUTES,
44221
+ "r:id": model.rId || "rId1",
44222
+ refreshOnLoad: model.refreshOnLoad || "1",
44223
+ refreshedBy: model.refreshedBy || "Author",
44224
+ refreshedDate: model.refreshedDate || "45125.026046874998",
44225
+ createdVersion: model.createdVersion || "8",
44226
+ refreshedVersion: model.refreshedVersion || "8",
44227
+ minRefreshableVersion: model.minRefreshableVersion || "3",
44228
+ recordCount: recordCount || cacheFields.length + 1
44229
+ });
44230
+ xmlStream.openNode("cacheSource", { type: "worksheet" });
44231
+ xmlStream.leafNode("worksheetSource", {
44232
+ ref: sourceRef,
44233
+ sheet: sourceSheet
44234
+ });
44235
+ xmlStream.closeNode();
44236
+ xmlStream.openNode("cacheFields", { count: cacheFields.length });
44237
+ xmlStream.writeXml(cacheFields.map((cacheField) => new CacheField(cacheField).render()).join("\n "));
44238
+ xmlStream.closeNode();
44239
+ xmlStream.closeNode();
43899
44240
  }
43900
- parseText(_text) {}
43901
- parseClose(_name) {
43902
- return false;
44241
+ parseOpen(node) {
44242
+ const { name, attributes } = node;
44243
+ if (this.currentCacheField) {
44244
+ this.currentCacheField.parseOpen(node);
44245
+ return true;
44246
+ }
44247
+ switch (name) {
44248
+ case this.tag:
44249
+ this.reset();
44250
+ this.model = {
44251
+ cacheFields: [],
44252
+ rId: attributes["r:id"],
44253
+ refreshOnLoad: attributes.refreshOnLoad,
44254
+ refreshedBy: attributes.refreshedBy,
44255
+ refreshedDate: attributes.refreshedDate,
44256
+ createdVersion: attributes.createdVersion,
44257
+ refreshedVersion: attributes.refreshedVersion,
44258
+ minRefreshableVersion: attributes.minRefreshableVersion,
44259
+ recordCount: attributes.recordCount ? parseInt(attributes.recordCount, 10) : void 0,
44260
+ isLoaded: true
44261
+ };
44262
+ break;
44263
+ case "cacheSource":
44264
+ this.inCacheSource = true;
44265
+ break;
44266
+ case "worksheetSource":
44267
+ if (this.inCacheSource && this.model) {
44268
+ this.model.sourceRef = attributes.ref;
44269
+ this.model.sourceSheet = attributes.sheet;
44270
+ }
44271
+ break;
44272
+ case "cacheFields":
44273
+ this.inCacheFields = true;
44274
+ break;
44275
+ case "cacheField":
44276
+ if (this.inCacheFields) {
44277
+ this.currentCacheField = new CacheFieldXform();
44278
+ this.currentCacheField.parseOpen(node);
44279
+ }
44280
+ break;
44281
+ }
44282
+ return true;
44283
+ }
44284
+ parseText(text) {
44285
+ if (this.currentCacheField) this.currentCacheField.parseText(text);
44286
+ }
44287
+ parseClose(name) {
44288
+ if (this.currentCacheField) {
44289
+ if (!this.currentCacheField.parseClose(name)) {
44290
+ if (this.model && this.currentCacheField.model) this.model.cacheFields.push(this.currentCacheField.model);
44291
+ this.currentCacheField = null;
44292
+ }
44293
+ return true;
44294
+ }
44295
+ switch (name) {
44296
+ case this.tag: return false;
44297
+ case "cacheSource":
44298
+ this.inCacheSource = false;
44299
+ break;
44300
+ case "cacheFields":
44301
+ this.inCacheFields = false;
44302
+ break;
44303
+ }
44304
+ return true;
43903
44305
  }
43904
44306
  reconcile(_model, _options) {}
43905
44307
  static {
@@ -43919,17 +44321,53 @@ ${XMLNS_NAMESPACE}.`);
43919
44321
  constructor() {
43920
44322
  super();
43921
44323
  this.map = {};
44324
+ this.model = null;
44325
+ this.inPivotFields = false;
44326
+ this.inRowFields = false;
44327
+ this.inColFields = false;
44328
+ this.inDataFields = false;
44329
+ this.inRowItems = false;
44330
+ this.inColItems = false;
44331
+ this.inLocation = false;
44332
+ this.currentPivotField = null;
44333
+ this.inItems = false;
44334
+ this.inPivotTableStyleInfo = false;
43922
44335
  }
43923
44336
  prepare(_model) {}
43924
44337
  get tag() {
43925
44338
  return "pivotTableDefinition";
43926
44339
  }
44340
+ reset() {
44341
+ this.model = null;
44342
+ this.inPivotFields = false;
44343
+ this.inRowFields = false;
44344
+ this.inColFields = false;
44345
+ this.inDataFields = false;
44346
+ this.inRowItems = false;
44347
+ this.inColItems = false;
44348
+ this.inLocation = false;
44349
+ this.currentPivotField = null;
44350
+ this.inItems = false;
44351
+ this.inPivotTableStyleInfo = false;
44352
+ }
44353
+ /**
44354
+ * Render pivot table XML.
44355
+ * Supports both newly created models and loaded models.
44356
+ */
43927
44357
  render(xmlStream, model) {
43928
- const { rows, columns, values, cacheFields, cacheId } = model;
44358
+ if (model.isLoaded) this.renderLoaded(xmlStream, model);
44359
+ else this.renderNew(xmlStream, model);
44360
+ }
44361
+ /**
44362
+ * Render newly created pivot table
44363
+ */
44364
+ renderNew(xmlStream, model) {
44365
+ const { rows, columns, values, cacheFields, cacheId, applyWidthHeightFormats } = model;
44366
+ const uniqueUid = `{${v4_default().toUpperCase()}}`;
43929
44367
  xmlStream.openXml(XmlStream.StdDocAttributes);
43930
44368
  xmlStream.openNode(this.tag, {
43931
44369
  ...PivotTableXform.PIVOT_TABLE_ATTRIBUTES,
43932
- "xr:uid": "{267EE50F-B116-784D-8DC2-BA77DE3F4F4A}",
44370
+ "xr:uid": uniqueUid,
43933
44371
  name: "PivotTable2",
43934
44372
  cacheId,
43935
44373
  applyNumberFormats: "0",
@@ -43937,7 +44375,7 @@ ${XMLNS_NAMESPACE}.`);
43937
44375
  applyFontFormats: "0",
43938
44376
  applyPatternFormats: "0",
43939
44377
  applyAlignmentFormats: "0",
43940
- applyWidthHeightFormats: "1",
44378
+ applyWidthHeightFormats,
43941
44379
  dataCaption: "Values",
43942
44380
  updatedVersion: "8",
43943
44381
  minRefreshableVersion: "3",
@@ -43960,19 +44398,14 @@ ${XMLNS_NAMESPACE}.`);
43960
44398
  <rowItems count="1">
43961
44399
  <i t="grand"><x /></i>
43962
44400
  </rowItems>
43963
- <colFields count="${columns.length}">
43964
- ${columns.map((columnIndex) => `<field x="${columnIndex}" />`).join("\n ")}
44401
+ <colFields count="${columns.length === 0 ? 1 : columns.length}">
44402
+ ${columns.length === 0 ? "<field x=\"-2\" />" : columns.map((columnIndex) => `<field x="${columnIndex}" />`).join("\n ")}
43965
44403
  </colFields>
43966
44404
  <colItems count="1">
43967
44405
  <i t="grand"><x /></i>
43968
44406
  </colItems>
43969
44407
  <dataFields count="${values.length}">
43970
- <dataField
43971
- name="Sum of ${cacheFields[values[0]].name}"
43972
- fld="${values[0]}"
43973
- baseField="0"
43974
- baseItem="0"
43975
- />
44408
+ ${buildDataFields(cacheFields, values, model.metric)}
43976
44409
  </dataFields>
43977
44410
  <pivotTableStyleInfo
43978
44411
  name="PivotStyleLight16"
@@ -44005,12 +44438,260 @@ ${XMLNS_NAMESPACE}.`);
44005
44438
  `);
44006
44439
  xmlStream.closeNode();
44007
44440
  }
44008
- parseOpen(_node) {
44009
- return false;
44441
+ /**
44442
+ * Render loaded pivot table (preserving original structure)
44443
+ */
44444
+ renderLoaded(xmlStream, model) {
44445
+ const uniqueUid = model.uid || `{${v4_default().toUpperCase()}}`;
44446
+ xmlStream.openXml(XmlStream.StdDocAttributes);
44447
+ xmlStream.openNode(this.tag, {
44448
+ ...PivotTableXform.PIVOT_TABLE_ATTRIBUTES,
44449
+ "xr:uid": uniqueUid,
44450
+ name: model.name || "PivotTable1",
44451
+ cacheId: model.cacheId,
44452
+ applyNumberFormats: model.applyNumberFormats || "0",
44453
+ applyBorderFormats: model.applyBorderFormats || "0",
44454
+ applyFontFormats: model.applyFontFormats || "0",
44455
+ applyPatternFormats: model.applyPatternFormats || "0",
44456
+ applyAlignmentFormats: model.applyAlignmentFormats || "0",
44457
+ applyWidthHeightFormats: model.applyWidthHeightFormats || "0",
44458
+ dataCaption: model.dataCaption || "Values",
44459
+ updatedVersion: model.updatedVersion || "8",
44460
+ minRefreshableVersion: model.minRefreshableVersion || "3",
44461
+ useAutoFormatting: model.useAutoFormatting ? "1" : "0",
44462
+ itemPrintTitles: model.itemPrintTitles ? "1" : "0",
44463
+ createdVersion: model.createdVersion || "8",
44464
+ indent: model.indent !== void 0 ? String(model.indent) : "0",
44465
+ compact: model.compact ? "1" : "0",
44466
+ compactData: model.compactData ? "1" : "0",
44467
+ multipleFieldFilters: model.multipleFieldFilters ? "1" : "0"
44468
+ });
44469
+ if (model.location) xmlStream.leafNode("location", {
44470
+ ref: model.location.ref,
44471
+ firstHeaderRow: model.location.firstHeaderRow,
44472
+ firstDataRow: model.location.firstDataRow,
44473
+ firstDataCol: model.location.firstDataCol
44474
+ });
44475
+ if (model.pivotFields.length > 0) {
44476
+ xmlStream.openNode("pivotFields", { count: model.pivotFields.length });
44477
+ for (const pivotField of model.pivotFields) this.renderPivotFieldLoaded(xmlStream, pivotField);
44478
+ xmlStream.closeNode();
44479
+ }
44480
+ if (model.rowFields.length > 0) {
44481
+ xmlStream.openNode("rowFields", { count: model.rowFields.length });
44482
+ for (const fieldIndex of model.rowFields) xmlStream.leafNode("field", { x: fieldIndex });
44483
+ xmlStream.closeNode();
44484
+ }
44485
+ xmlStream.writeXml(`
44486
+ <rowItems count="1">
44487
+ <i t="grand"><x /></i>
44488
+ </rowItems>`);
44489
+ const colFieldCount = model.colFields.length === 0 ? 1 : model.colFields.length;
44490
+ xmlStream.openNode("colFields", { count: colFieldCount });
44491
+ if (model.colFields.length === 0) xmlStream.leafNode("field", { x: -2 });
44492
+ else for (const fieldIndex of model.colFields) xmlStream.leafNode("field", { x: fieldIndex });
44493
+ xmlStream.closeNode();
44494
+ xmlStream.writeXml(`
44495
+ <colItems count="1">
44496
+ <i t="grand"><x /></i>
44497
+ </colItems>`);
44498
+ if (model.dataFields.length > 0) {
44499
+ xmlStream.openNode("dataFields", { count: model.dataFields.length });
44500
+ for (const dataField of model.dataFields) {
44501
+ const attrs = {
44502
+ name: dataField.name,
44503
+ fld: dataField.fld,
44504
+ baseField: dataField.baseField ?? 0,
44505
+ baseItem: dataField.baseItem ?? 0
44506
+ };
44507
+ if (dataField.subtotal && dataField.subtotal !== "sum") attrs.subtotal = dataField.subtotal;
44508
+ xmlStream.leafNode("dataField", attrs);
44509
+ }
44510
+ xmlStream.closeNode();
44511
+ }
44512
+ xmlStream.leafNode("pivotTableStyleInfo", {
44513
+ name: model.styleName || "PivotStyleLight16",
44514
+ showRowHeaders: "1",
44515
+ showColHeaders: "1",
44516
+ showRowStripes: "0",
44517
+ showColStripes: "0",
44518
+ showLastColumn: "1"
44519
+ });
44520
+ xmlStream.writeXml(`
44521
+ <extLst>
44522
+ <ext
44523
+ uri="{962EF5D1-5CA2-4c93-8EF4-DBF5C05439D2}"
44524
+ xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
44525
+ >
44526
+ <x14:pivotTableDefinition
44527
+ hideValuesRow="1"
44528
+ xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main"
44529
+ />
44530
+ </ext>
44531
+ <ext
44532
+ uri="{747A6164-185A-40DC-8AA5-F01512510D54}"
44533
+ xmlns:xpdl="http://schemas.microsoft.com/office/spreadsheetml/2016/pivotdefaultlayout"
44534
+ >
44535
+ <xpdl:pivotTableDefinition16
44536
+ EnabledSubtotalsDefault="0"
44537
+ SubtotalsOnTopDefault="0"
44538
+ />
44539
+ </ext>
44540
+ </extLst>
44541
+ `);
44542
+ xmlStream.closeNode();
44543
+ }
44544
+ /**
44545
+ * Render a loaded pivot field
44546
+ */
44547
+ renderPivotFieldLoaded(xmlStream, field) {
44548
+ const attrs = {
44549
+ compact: field.compact ? "1" : "0",
44550
+ outline: field.outline ? "1" : "0",
44551
+ showAll: field.showAll ? "1" : "0",
44552
+ defaultSubtotal: field.defaultSubtotal ? "1" : "0"
44553
+ };
44554
+ if (field.axis) attrs.axis = field.axis;
44555
+ if (field.dataField) attrs.dataField = "1";
44556
+ if (field.items && field.items.length > 0) {
44557
+ xmlStream.openNode("pivotField", attrs);
44558
+ xmlStream.openNode("items", { count: field.items.length + 1 });
44559
+ for (const itemIndex of field.items) xmlStream.leafNode("item", { x: itemIndex });
44560
+ xmlStream.writeXml("<item t=\"default\" />");
44561
+ xmlStream.closeNode();
44562
+ xmlStream.closeNode();
44563
+ } else xmlStream.leafNode("pivotField", attrs);
44564
+ }
44565
+ parseOpen(node) {
44566
+ const { name, attributes } = node;
44567
+ switch (name) {
44568
+ case this.tag:
44569
+ this.reset();
44570
+ this.model = {
44571
+ name: attributes.name,
44572
+ cacheId: parseInt(attributes.cacheId || "0", 10),
44573
+ uid: attributes["xr:uid"],
44574
+ pivotFields: [],
44575
+ rowFields: [],
44576
+ colFields: [],
44577
+ dataFields: [],
44578
+ applyNumberFormats: attributes.applyNumberFormats,
44579
+ applyBorderFormats: attributes.applyBorderFormats,
44580
+ applyFontFormats: attributes.applyFontFormats,
44581
+ applyPatternFormats: attributes.applyPatternFormats,
44582
+ applyAlignmentFormats: attributes.applyAlignmentFormats,
44583
+ applyWidthHeightFormats: attributes.applyWidthHeightFormats,
44584
+ dataCaption: attributes.dataCaption,
44585
+ updatedVersion: attributes.updatedVersion,
44586
+ minRefreshableVersion: attributes.minRefreshableVersion,
44587
+ createdVersion: attributes.createdVersion,
44588
+ useAutoFormatting: attributes.useAutoFormatting === "1",
44589
+ itemPrintTitles: attributes.itemPrintTitles === "1",
44590
+ indent: attributes.indent ? parseInt(attributes.indent, 10) : 0,
44591
+ compact: attributes.compact === "1",
44592
+ compactData: attributes.compactData === "1",
44593
+ multipleFieldFilters: attributes.multipleFieldFilters === "1",
44594
+ isLoaded: true
44595
+ };
44596
+ break;
44597
+ case "location":
44598
+ if (this.model) this.model.location = {
44599
+ ref: attributes.ref,
44600
+ firstHeaderRow: attributes.firstHeaderRow ? parseInt(attributes.firstHeaderRow, 10) : void 0,
44601
+ firstDataRow: attributes.firstDataRow ? parseInt(attributes.firstDataRow, 10) : void 0,
44602
+ firstDataCol: attributes.firstDataCol ? parseInt(attributes.firstDataCol, 10) : void 0
44603
+ };
44604
+ break;
44605
+ case "pivotFields":
44606
+ this.inPivotFields = true;
44607
+ break;
44608
+ case "pivotField":
44609
+ if (this.inPivotFields) this.currentPivotField = {
44610
+ axis: attributes.axis,
44611
+ dataField: attributes.dataField === "1",
44612
+ items: [],
44613
+ compact: attributes.compact === "1",
44614
+ outline: attributes.outline === "1",
44615
+ showAll: attributes.showAll === "1",
44616
+ defaultSubtotal: attributes.defaultSubtotal === "1"
44617
+ };
44618
+ break;
44619
+ case "items":
44620
+ if (this.currentPivotField) this.inItems = true;
44621
+ break;
44622
+ case "item":
44623
+ if (this.inItems && this.currentPivotField && attributes.x !== void 0) this.currentPivotField.items.push(parseInt(attributes.x, 10));
44624
+ break;
44625
+ case "rowFields":
44626
+ this.inRowFields = true;
44627
+ break;
44628
+ case "colFields":
44629
+ this.inColFields = true;
44630
+ break;
44631
+ case "dataFields":
44632
+ this.inDataFields = true;
44633
+ break;
44634
+ case "rowItems":
44635
+ this.inRowItems = true;
44636
+ break;
44637
+ case "colItems":
44638
+ this.inColItems = true;
44639
+ break;
44640
+ case "field":
44641
+ if (this.model) {
44642
+ const fieldIndex = parseInt(attributes.x || "0", 10);
44643
+ if (this.inRowFields) this.model.rowFields.push(fieldIndex);
44644
+ else if (this.inColFields) this.model.colFields.push(fieldIndex);
44645
+ }
44646
+ break;
44647
+ case "dataField":
44648
+ if (this.inDataFields && this.model) this.model.dataFields.push({
44649
+ name: xmlDecode(attributes.name || ""),
44650
+ fld: parseInt(attributes.fld || "0", 10),
44651
+ baseField: attributes.baseField ? parseInt(attributes.baseField, 10) : 0,
44652
+ baseItem: attributes.baseItem ? parseInt(attributes.baseItem, 10) : 0,
44653
+ subtotal: attributes.subtotal
44654
+ });
44655
+ break;
44656
+ case "pivotTableStyleInfo":
44657
+ if (this.model) this.model.styleName = attributes.name;
44658
+ break;
44659
+ }
44660
+ return true;
44010
44661
  }
44011
44662
  parseText(_text) {}
44012
- parseClose(_name) {
44013
- return false;
44663
+ parseClose(name) {
44664
+ switch (name) {
44665
+ case this.tag: return false;
44666
+ case "pivotFields":
44667
+ this.inPivotFields = false;
44668
+ break;
44669
+ case "pivotField":
44670
+ if (this.currentPivotField && this.model) {
44671
+ this.model.pivotFields.push(this.currentPivotField);
44672
+ this.currentPivotField = null;
44673
+ }
44674
+ break;
44675
+ case "items":
44676
+ this.inItems = false;
44677
+ break;
44678
+ case "rowFields":
44679
+ this.inRowFields = false;
44680
+ break;
44681
+ case "colFields":
44682
+ this.inColFields = false;
44683
+ break;
44684
+ case "dataFields":
44685
+ this.inDataFields = false;
44686
+ break;
44687
+ case "rowItems":
44688
+ this.inRowItems = false;
44689
+ break;
44690
+ case "colItems":
44691
+ this.inColItems = false;
44692
+ break;
44693
+ }
44694
+ return true;
44014
44695
  }
44015
44696
  reconcile(_model, _options) {}
44016
44697
  static {
@@ -44022,9 +44703,26 @@ ${XMLNS_NAMESPACE}.`);
44022
44703
  };
44023
44704
  }
44024
44705
  };
44706
+ /**
44707
+ * Build dataField XML elements for all values in the pivot table.
44708
+ * Supports multiple values when columns is empty.
44709
+ */
44710
+ function buildDataFields(cacheFields, values, metric) {
44711
+ const metricName = metric === "count" ? "Count" : "Sum";
44712
+ const subtotalAttr = metric === "count" ? " subtotal=\"count\"" : "";
44713
+ return values.map((valueIndex) => `<dataField
44714
+ name="${metricName} of ${xmlEncode(cacheFields[valueIndex].name)}"
44715
+ fld="${valueIndex}"
44716
+ baseField="0"
44717
+ baseItem="0"${subtotalAttr}
44718
+ />`).join("");
44719
+ }
44025
44720
  function renderPivotFields(pivotTable) {
44721
+ const rowSet = new Set(pivotTable.rows);
44722
+ const colSet = new Set(pivotTable.columns);
44723
+ const valueSet = new Set(pivotTable.values);
44026
44724
  return pivotTable.cacheFields.map((cacheField, fieldIndex) => {
44027
- return renderPivotField(pivotTable.rows.indexOf(fieldIndex) >= 0 ? "row" : pivotTable.columns.indexOf(fieldIndex) >= 0 ? "column" : pivotTable.values.indexOf(fieldIndex) >= 0 ? "value" : null, cacheField.sharedItems);
44725
+ return renderPivotField(rowSet.has(fieldIndex) ? "row" : colSet.has(fieldIndex) ? "column" : valueSet.has(fieldIndex) ? "value" : null, cacheField.sharedItems);
44028
44726
  }).join("");
44029
44727
  }
44030
44728
  function renderPivotField(fieldType, sharedItems) {
@@ -44592,9 +45290,7 @@ ${XMLNS_NAMESPACE}.`);
44592
45290
 
44593
45291
  //#endregion
44594
45292
  //#region src/xlsx/xlsx.ts
44595
- var import_buffer$2 = require_buffer$1();
44596
45293
  init_empty();
44597
- var import_stream_browserify = require_stream_browserify();
44598
45294
  function fsReadFileAsync(filename, options) {
44599
45295
  return new Promise((resolve, reject) => {
44600
45296
  empty.readFile(filename, options, (error, data) => {
@@ -44660,6 +45356,7 @@ ${XMLNS_NAMESPACE}.`);
44660
45356
  Object.values(model.tables).forEach((table) => {
44661
45357
  tableXform.reconcile(table, tableOptions);
44662
45358
  });
45359
+ this._reconcilePivotTables(model);
44663
45360
  const sheetOptions = {
44664
45361
  styles: model.styles,
44665
45362
  sharedStrings: model.sharedStrings,
@@ -44669,7 +45366,8 @@ ${XMLNS_NAMESPACE}.`);
44669
45366
  drawings: model.drawings,
44670
45367
  comments: model.comments,
44671
45368
  tables: model.tables,
44672
- vmlDrawings: model.vmlDrawings
45369
+ vmlDrawings: model.vmlDrawings,
45370
+ pivotTables: model.pivotTablesIndexed
44673
45371
  };
44674
45372
  model.worksheets.forEach((worksheet) => {
44675
45373
  worksheet.relationships = model.worksheetRels[worksheet.sheetNo];
@@ -44686,6 +45384,99 @@ ${XMLNS_NAMESPACE}.`);
44686
45384
  delete model.drawings;
44687
45385
  delete model.drawingRels;
44688
45386
  delete model.vmlDrawings;
45387
+ delete model.pivotTableRels;
45388
+ delete model.pivotCacheDefinitionRels;
45389
+ }
45390
+ /**
45391
+ * Reconcile pivot tables by linking them to worksheets and their cache data.
45392
+ * This builds a complete pivot table model ready for writing.
45393
+ */
45394
+ _reconcilePivotTables(model) {
45395
+ const rawPivotTables = model.pivotTables || {};
45396
+ if (typeof rawPivotTables !== "object" || Object.keys(rawPivotTables).length === 0) {
45397
+ model.pivotTables = [];
45398
+ model.pivotTablesIndexed = {};
45399
+ return;
45400
+ }
45401
+ const definitionToCacheId = this._buildDefinitionToCacheIdMap(model);
45402
+ const cacheMap = /* @__PURE__ */ new Map();
45403
+ Object.entries(model.pivotCacheDefinitions || {}).forEach(([name, definition]) => {
45404
+ const cacheId = definitionToCacheId.get(name);
45405
+ if (cacheId !== void 0) {
45406
+ const recordsName = name.replace("Definition", "Records");
45407
+ cacheMap.set(cacheId, {
45408
+ definition,
45409
+ records: model.pivotCacheRecords?.[recordsName],
45410
+ definitionName: name
45411
+ });
45412
+ }
45413
+ });
45414
+ const loadedPivotTables = [];
45415
+ const pivotTablesIndexed = {};
45416
+ Object.entries(rawPivotTables).forEach(([pivotName, pivotTable]) => {
45417
+ const pt = pivotTable;
45418
+ const tableNumber = this._extractTableNumber(pivotName);
45419
+ const cacheData = cacheMap.get(pt.cacheId);
45420
+ const completePivotTable = {
45421
+ ...pt,
45422
+ tableNumber,
45423
+ cacheDefinition: cacheData?.definition,
45424
+ cacheRecords: cacheData?.records,
45425
+ cacheFields: cacheData?.definition?.cacheFields || [],
45426
+ rows: pt.rowFields.filter((f) => f >= 0),
45427
+ columns: pt.colFields.filter((f) => f >= 0 && f !== -2),
45428
+ values: pt.dataFields.map((df) => df.fld),
45429
+ metric: this._determineMetric(pt.dataFields),
45430
+ applyWidthHeightFormats: pt.applyWidthHeightFormats || "0"
45431
+ };
45432
+ loadedPivotTables.push(completePivotTable);
45433
+ pivotTablesIndexed[`../pivotTables/${pivotName}.xml`] = completePivotTable;
45434
+ });
45435
+ loadedPivotTables.sort((a, b) => a.tableNumber - b.tableNumber);
45436
+ model.pivotTables = loadedPivotTables;
45437
+ model.pivotTablesIndexed = pivotTablesIndexed;
45438
+ model.loadedPivotTables = loadedPivotTables;
45439
+ }
45440
+ /**
45441
+ * Extract table number from pivot table name (e.g., "pivotTable1" -> 1)
45442
+ */
45443
+ _extractTableNumber(name) {
45444
+ const match = name.match(/pivotTable(\d+)/);
45445
+ return match ? parseInt(match[1], 10) : 1;
45446
+ }
45447
+ /**
45448
+ * Build a mapping from rId to cacheId using pivotCaches from workbook.xml
45449
+ * and workbookRels to determine which definition file corresponds to which cacheId
45450
+ */
45451
+ _buildCacheIdMap(model) {
45452
+ const rIdToCacheId = /* @__PURE__ */ new Map();
45453
+ const pivotCaches = model.pivotCaches || [];
45454
+ for (const cache of pivotCaches) if (cache.cacheId && cache.rId) rIdToCacheId.set(cache.rId, parseInt(cache.cacheId, 10));
45455
+ return rIdToCacheId;
45456
+ }
45457
+ /**
45458
+ * Build a mapping from definition name to cacheId
45459
+ */
45460
+ _buildDefinitionToCacheIdMap(model) {
45461
+ const definitionToCacheId = /* @__PURE__ */ new Map();
45462
+ const rIdToCacheId = this._buildCacheIdMap(model);
45463
+ const workbookRels = model.workbookRels || [];
45464
+ for (const rel of workbookRels) if (rel.Type === XLSX.RelType.PivotCacheDefinition && rel.Target) {
45465
+ const match = rel.Target.match(/pivotCacheDefinition(\d+)\.xml/);
45466
+ if (match) {
45467
+ const defName = `pivotCacheDefinition${match[1]}`;
45468
+ const cacheId = rIdToCacheId.get(rel.Id);
45469
+ if (cacheId !== void 0) definitionToCacheId.set(defName, cacheId);
45470
+ }
45471
+ }
45472
+ return definitionToCacheId;
45473
+ }
45474
+ /**
45475
+ * Determine the aggregation metric from dataFields
45476
+ */
45477
+ _determineMetric(dataFields) {
45478
+ if (dataFields.length > 0 && dataFields[0].subtotal === "count") return "count";
45479
+ return "sum";
44689
45480
  }
44690
45481
  async _processWorksheetEntry(stream, model, sheetNo, options, path) {
44691
45482
  const worksheet = await new WorkSheetXform(options).parseStream(stream);
@@ -44777,6 +45568,26 @@ ${XMLNS_NAMESPACE}.`);
44777
45568
  stream.pipe(streamBuf);
44778
45569
  });
44779
45570
  }
45571
+ async _processPivotTableEntry(stream, model, name) {
45572
+ const pivotTable = await new PivotTableXform().parseStream(stream);
45573
+ if (pivotTable) model.pivotTables[name] = pivotTable;
45574
+ }
45575
+ async _processPivotTableRelsEntry(stream, model, name) {
45576
+ const relationships = await new RelationshipsXform().parseStream(stream);
45577
+ model.pivotTableRels[name] = relationships;
45578
+ }
45579
+ async _processPivotCacheDefinitionEntry(stream, model, name) {
45580
+ const cacheDefinition = await new PivotCacheDefinitionXform().parseStream(stream);
45581
+ if (cacheDefinition) model.pivotCacheDefinitions[name] = cacheDefinition;
45582
+ }
45583
+ async _processPivotCacheDefinitionRelsEntry(stream, model, name) {
45584
+ const relationships = await new RelationshipsXform().parseStream(stream);
45585
+ model.pivotCacheDefinitionRels[name] = relationships;
45586
+ }
45587
+ async _processPivotCacheRecordsEntry(stream, model, name) {
45588
+ const cacheRecords = await new PivotCacheRecordsXform().parseStream(stream);
45589
+ if (cacheRecords) model.pivotCacheRecords[name] = cacheRecords;
45590
+ }
44780
45591
  async read(stream, options) {
44781
45592
  const allFiles = {};
44782
45593
  await new Promise((resolve, reject) => {
@@ -44847,8 +45658,8 @@ ${XMLNS_NAMESPACE}.`);
44847
45658
  }
44848
45659
  async load(data, options) {
44849
45660
  let buffer;
44850
- if (!data || typeof data === "object" && !import_buffer$2.Buffer.isBuffer(data) && !(data instanceof Uint8Array) && !(data instanceof ArrayBuffer)) throw new Error("Can't read the data of 'the loaded zip file'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?");
44851
- if (options && options.base64) buffer = import_buffer$2.Buffer.from(data.toString(), "base64");
45661
+ if (!data || typeof data === "object" && !import_buffer$3.Buffer.isBuffer(data) && !(data instanceof Uint8Array) && !(data instanceof ArrayBuffer)) throw new Error("Can't read the data of 'the loaded zip file'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?");
45662
+ if (options && options.base64) buffer = import_buffer$3.Buffer.from(data.toString(), "base64");
44852
45663
  else buffer = data;
44853
45664
  const stream = new import_stream_browserify.PassThrough();
44854
45665
  stream.end(buffer);
@@ -44866,7 +45677,12 @@ ${XMLNS_NAMESPACE}.`);
44866
45677
  drawingRels: {},
44867
45678
  comments: {},
44868
45679
  tables: {},
44869
- vmlDrawings: {}
45680
+ vmlDrawings: {},
45681
+ pivotTables: {},
45682
+ pivotTableRels: {},
45683
+ pivotCacheDefinitions: {},
45684
+ pivotCacheDefinitionRels: {},
45685
+ pivotCacheRecords: {}
44870
45686
  };
44871
45687
  const entries = Object.keys(zipData).map((name) => ({
44872
45688
  name,
@@ -44879,13 +45695,13 @@ ${XMLNS_NAMESPACE}.`);
44879
45695
  let stream;
44880
45696
  if (entryName.match(/xl\/media\//) || entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/)) {
44881
45697
  stream = new import_stream_browserify.PassThrough();
44882
- stream.end(import_buffer$2.Buffer.from(entry.data));
45698
+ stream.end(import_buffer$3.Buffer.from(entry.data));
44883
45699
  } else {
44884
45700
  stream = new import_stream_browserify.PassThrough({
44885
45701
  readableObjectMode: true,
44886
45702
  writableObjectMode: true
44887
45703
  });
44888
- const content = bufferToString(import_buffer$2.Buffer.from(entry.data));
45704
+ const content = bufferToString(import_buffer$3.Buffer.from(entry.data));
44889
45705
  stream.end(content);
44890
45706
  }
44891
45707
  let match;
@@ -44904,6 +45720,7 @@ ${XMLNS_NAMESPACE}.`);
44904
45720
  model.views = workbook.views;
44905
45721
  model.properties = workbook.properties;
44906
45722
  model.calcProperties = workbook.calcProperties;
45723
+ model.pivotCaches = workbook.pivotCaches;
44907
45724
  break;
44908
45725
  }
44909
45726
  case "xl/sharedStrings.xml":
@@ -44970,6 +45787,31 @@ ${XMLNS_NAMESPACE}.`);
44970
45787
  await this._processThemeEntry(stream, model, match[1]);
44971
45788
  break;
44972
45789
  }
45790
+ match = entryName.match(/xl\/pivotTables\/(pivotTable\d+)[.]xml/);
45791
+ if (match) {
45792
+ await this._processPivotTableEntry(stream, model, match[1]);
45793
+ break;
45794
+ }
45795
+ match = entryName.match(/xl\/pivotTables\/_rels\/(pivotTable\d+)[.]xml[.]rels/);
45796
+ if (match) {
45797
+ await this._processPivotTableRelsEntry(stream, model, match[1]);
45798
+ break;
45799
+ }
45800
+ match = entryName.match(/xl\/pivotCache\/(pivotCacheDefinition\d+)[.]xml/);
45801
+ if (match) {
45802
+ await this._processPivotCacheDefinitionEntry(stream, model, match[1]);
45803
+ break;
45804
+ }
45805
+ match = entryName.match(/xl\/pivotCache\/_rels\/(pivotCacheDefinition\d+)[.]xml[.]rels/);
45806
+ if (match) {
45807
+ await this._processPivotCacheDefinitionRelsEntry(stream, model, match[1]);
45808
+ break;
45809
+ }
45810
+ match = entryName.match(/xl\/pivotCache\/(pivotCacheRecords\d+)[.]xml/);
45811
+ if (match) {
45812
+ await this._processPivotCacheRecordsEntry(stream, model, match[1]);
45813
+ break;
45814
+ }
44973
45815
  }
44974
45816
  }
44975
45817
  this.reconcile(model, options);
@@ -45032,21 +45874,21 @@ ${XMLNS_NAMESPACE}.`);
45032
45874
  Type: XLSX.RelType.SharedStrings,
45033
45875
  Target: "sharedStrings.xml"
45034
45876
  });
45035
- if ((model.pivotTables || []).length) {
45036
- const pivotTable = model.pivotTables[0];
45877
+ (model.pivotTables || []).forEach((pivotTable) => {
45037
45878
  pivotTable.rId = `rId${count++}`;
45038
45879
  relationships.push({
45039
45880
  Id: pivotTable.rId,
45040
45881
  Type: XLSX.RelType.PivotCacheDefinition,
45041
- Target: "pivotCache/pivotCacheDefinition1.xml"
45882
+ Target: `pivotCache/pivotCacheDefinition${pivotTable.tableNumber}.xml`
45042
45883
  });
45043
- }
45044
- model.worksheets.forEach((worksheet) => {
45884
+ });
45885
+ model.worksheets.forEach((worksheet, index) => {
45045
45886
  worksheet.rId = `rId${count++}`;
45887
+ worksheet.fileIndex = index + 1;
45046
45888
  relationships.push({
45047
45889
  Id: worksheet.rId,
45048
45890
  Type: XLSX.RelType.Worksheet,
45049
- Target: `worksheets/sheet${worksheet.id}.xml`
45891
+ Target: `worksheets/sheet${worksheet.fileIndex}.xml`
45050
45892
  });
45051
45893
  });
45052
45894
  const xml = new RelationshipsXform().toXml(relationships);
@@ -45068,22 +45910,23 @@ ${XMLNS_NAMESPACE}.`);
45068
45910
  const relationshipsXform = new RelationshipsXform();
45069
45911
  const commentsXform = new CommentsXform();
45070
45912
  const vmlNotesXform = new VmlNotesXform();
45071
- model.worksheets.forEach((worksheet) => {
45913
+ model.worksheets.forEach((worksheet, index) => {
45914
+ const fileIndex = worksheet.fileIndex || index + 1;
45072
45915
  let xmlStream = new XmlStream();
45073
45916
  worksheetXform.render(xmlStream, worksheet);
45074
- zip.append(xmlStream.xml, { name: `xl/worksheets/sheet${worksheet.id}.xml` });
45917
+ zip.append(xmlStream.xml, { name: `xl/worksheets/sheet${fileIndex}.xml` });
45075
45918
  if (worksheet.rels && worksheet.rels.length) {
45076
45919
  xmlStream = new XmlStream();
45077
45920
  relationshipsXform.render(xmlStream, worksheet.rels);
45078
- zip.append(xmlStream.xml, { name: `xl/worksheets/_rels/sheet${worksheet.id}.xml.rels` });
45921
+ zip.append(xmlStream.xml, { name: `xl/worksheets/_rels/sheet${fileIndex}.xml.rels` });
45079
45922
  }
45080
45923
  if (worksheet.comments.length > 0) {
45081
45924
  xmlStream = new XmlStream();
45082
45925
  commentsXform.render(xmlStream, worksheet);
45083
- zip.append(xmlStream.xml, { name: `xl/comments${worksheet.id}.xml` });
45926
+ zip.append(xmlStream.xml, { name: `xl/comments${fileIndex}.xml` });
45084
45927
  xmlStream = new XmlStream();
45085
45928
  vmlNotesXform.render(xmlStream, worksheet);
45086
- zip.append(xmlStream.xml, { name: `xl/drawings/vmlDrawing${worksheet.id}.vml` });
45929
+ zip.append(xmlStream.xml, { name: `xl/drawings/vmlDrawing${fileIndex}.vml` });
45087
45930
  }
45088
45931
  });
45089
45932
  }
@@ -45135,29 +45978,42 @@ ${XMLNS_NAMESPACE}.`);
45135
45978
  }
45136
45979
  addPivotTables(zip, model) {
45137
45980
  if (!model.pivotTables.length) return;
45138
- const pivotTable = model.pivotTables[0];
45139
45981
  const pivotCacheRecordsXform = new PivotCacheRecordsXform();
45140
45982
  const pivotCacheDefinitionXform = new PivotCacheDefinitionXform();
45141
45983
  const pivotTableXform = new PivotTableXform();
45142
45984
  const relsXform = new RelationshipsXform();
45143
- let xml = pivotCacheRecordsXform.toXml(pivotTable);
45144
- zip.append(xml, { name: "xl/pivotCache/pivotCacheRecords1.xml" });
45145
- xml = pivotCacheDefinitionXform.toXml(pivotTable);
45146
- zip.append(xml, { name: "xl/pivotCache/pivotCacheDefinition1.xml" });
45147
- xml = relsXform.toXml([{
45148
- Id: "rId1",
45149
- Type: XLSX.RelType.PivotCacheRecords,
45150
- Target: "pivotCacheRecords1.xml"
45151
- }]);
45152
- zip.append(xml, { name: "xl/pivotCache/_rels/pivotCacheDefinition1.xml.rels" });
45153
- xml = pivotTableXform.toXml(pivotTable);
45154
- zip.append(xml, { name: "xl/pivotTables/pivotTable1.xml" });
45155
- xml = relsXform.toXml([{
45156
- Id: "rId1",
45157
- Type: XLSX.RelType.PivotCacheDefinition,
45158
- Target: "../pivotCache/pivotCacheDefinition1.xml"
45159
- }]);
45160
- zip.append(xml, { name: "xl/pivotTables/_rels/pivotTable1.xml.rels" });
45985
+ model.pivotTables.forEach((pivotTable) => {
45986
+ const n = pivotTable.tableNumber;
45987
+ if (pivotTable.isLoaded) {
45988
+ if (pivotTable.cacheDefinition) {
45989
+ const xml$1 = pivotCacheDefinitionXform.toXml(pivotTable.cacheDefinition);
45990
+ zip.append(xml$1, { name: `xl/pivotCache/pivotCacheDefinition${n}.xml` });
45991
+ }
45992
+ if (pivotTable.cacheRecords) {
45993
+ const xml$1 = pivotCacheRecordsXform.toXml(pivotTable.cacheRecords);
45994
+ zip.append(xml$1, { name: `xl/pivotCache/pivotCacheRecords${n}.xml` });
45995
+ }
45996
+ } else {
45997
+ let xml$1 = pivotCacheRecordsXform.toXml(pivotTable);
45998
+ zip.append(xml$1, { name: `xl/pivotCache/pivotCacheRecords${n}.xml` });
45999
+ xml$1 = pivotCacheDefinitionXform.toXml(pivotTable);
46000
+ zip.append(xml$1, { name: `xl/pivotCache/pivotCacheDefinition${n}.xml` });
46001
+ }
46002
+ let xml = relsXform.toXml([{
46003
+ Id: "rId1",
46004
+ Type: XLSX.RelType.PivotCacheRecords,
46005
+ Target: `pivotCacheRecords${n}.xml`
46006
+ }]);
46007
+ zip.append(xml, { name: `xl/pivotCache/_rels/pivotCacheDefinition${n}.xml.rels` });
46008
+ xml = pivotTableXform.toXml(pivotTable);
46009
+ zip.append(xml, { name: `xl/pivotTables/pivotTable${n}.xml` });
46010
+ xml = relsXform.toXml([{
46011
+ Id: "rId1",
46012
+ Type: XLSX.RelType.PivotCacheDefinition,
46013
+ Target: `../pivotCache/pivotCacheDefinition${n}.xml`
46014
+ }]);
46015
+ zip.append(xml, { name: `xl/pivotTables/_rels/pivotTable${n}.xml.rels` });
46016
+ });
45161
46017
  }
45162
46018
  _finalize(zip) {
45163
46019
  return new Promise((resolve, reject) => {
@@ -50673,7 +51529,7 @@ ${XMLNS_NAMESPACE}.`);
50673
51529
  this.views = value.views;
50674
51530
  this._themes = value.themes;
50675
51531
  this.media = value.media || [];
50676
- this.pivotTables = value.pivotTables || [];
51532
+ this.pivotTables = value.pivotTables || value.loadedPivotTables || [];
50677
51533
  }
50678
51534
  };
50679
51535