@cj-tech-master/excelts 1.5.0 → 1.6.1-canary.20251220005548.c4c1e36

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 (48) hide show
  1. package/README.md +0 -15
  2. package/README_zh.md +0 -15
  3. package/dist/browser/excelts.iife.js +1057 -222
  4. package/dist/browser/excelts.iife.js.map +1 -1
  5. package/dist/browser/excelts.iife.min.js +63 -33
  6. package/dist/cjs/doc/column.js +7 -3
  7. package/dist/cjs/doc/pivot-table.js +149 -61
  8. package/dist/cjs/doc/workbook.js +3 -1
  9. package/dist/cjs/doc/worksheet.js +2 -23
  10. package/dist/cjs/stream/xlsx/worksheet-writer.js +1 -1
  11. package/dist/cjs/utils/unzip/zip-parser.js +2 -5
  12. package/dist/cjs/xlsx/xform/book/workbook-xform.js +3 -0
  13. package/dist/cjs/xlsx/xform/core/content-types-xform.js +19 -14
  14. package/dist/cjs/xlsx/xform/pivot-table/cache-field-xform.js +135 -0
  15. package/dist/cjs/xlsx/xform/pivot-table/cache-field.js +7 -4
  16. package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +135 -13
  17. package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-records-xform.js +193 -45
  18. package/dist/cjs/xlsx/xform/pivot-table/pivot-table-xform.js +390 -39
  19. package/dist/cjs/xlsx/xform/sheet/cell-xform.js +6 -0
  20. package/dist/cjs/xlsx/xform/sheet/worksheet-xform.js +14 -3
  21. package/dist/cjs/xlsx/xlsx.js +261 -38
  22. package/dist/esm/doc/column.js +7 -3
  23. package/dist/esm/doc/pivot-table.js +150 -62
  24. package/dist/esm/doc/workbook.js +3 -1
  25. package/dist/esm/doc/worksheet.js +2 -23
  26. package/dist/esm/stream/xlsx/worksheet-writer.js +1 -1
  27. package/dist/esm/utils/unzip/zip-parser.js +2 -5
  28. package/dist/esm/xlsx/xform/book/workbook-xform.js +3 -0
  29. package/dist/esm/xlsx/xform/core/content-types-xform.js +19 -14
  30. package/dist/esm/xlsx/xform/pivot-table/cache-field-xform.js +132 -0
  31. package/dist/esm/xlsx/xform/pivot-table/cache-field.js +7 -4
  32. package/dist/esm/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +135 -13
  33. package/dist/esm/xlsx/xform/pivot-table/pivot-cache-records-xform.js +193 -45
  34. package/dist/esm/xlsx/xform/pivot-table/pivot-table-xform.js +390 -39
  35. package/dist/esm/xlsx/xform/sheet/cell-xform.js +6 -0
  36. package/dist/esm/xlsx/xform/sheet/worksheet-xform.js +14 -3
  37. package/dist/esm/xlsx/xlsx.js +261 -38
  38. package/dist/types/doc/column.d.ts +13 -6
  39. package/dist/types/doc/pivot-table.d.ts +135 -9
  40. package/dist/types/doc/workbook.d.ts +2 -0
  41. package/dist/types/doc/worksheet.d.ts +6 -27
  42. package/dist/types/index.d.ts +1 -0
  43. package/dist/types/xlsx/xform/pivot-table/cache-field-xform.d.ts +42 -0
  44. package/dist/types/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +45 -6
  45. package/dist/types/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +52 -5
  46. package/dist/types/xlsx/xform/pivot-table/pivot-table-xform.d.ts +98 -5
  47. package/dist/types/xlsx/xlsx.d.ts +27 -0
  48. 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-canary.20251220005548.c4c1e36
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
  }
@@ -26835,27 +26901,17 @@ var ExcelTS = (function(exports) {
26835
26901
  });
26836
26902
  return count;
26837
26903
  }
26838
- /**
26839
- * Get or create row by 1-based index
26840
- */
26841
26904
  getRow(r) {
26842
26905
  let row = this._rows[r - 1];
26843
26906
  if (!row) row = this._rows[r - 1] = new Row(this, r);
26844
26907
  return row;
26845
26908
  }
26846
- /**
26847
- * Get or create rows by 1-based index
26848
- */
26849
26909
  getRows(start, length) {
26850
26910
  if (length < 1) return;
26851
26911
  const rows = [];
26852
26912
  for (let i$1 = start; i$1 < start + length; i$1++) rows.push(this.getRow(i$1));
26853
26913
  return rows;
26854
26914
  }
26855
- /**
26856
- * Add a couple of Rows by key-value, after the last current row, using the column keys,
26857
- * or add a row by contiguous Array (assign to columns A, B & C)
26858
- */
26859
26915
  addRow(value, style = "n") {
26860
26916
  const rowNo = this._nextRow;
26861
26917
  const row = this.getRow(rowNo);
@@ -26863,9 +26919,6 @@ var ExcelTS = (function(exports) {
26863
26919
  this._setStyleOption(rowNo, style[0] === "i" ? style : "n");
26864
26920
  return row;
26865
26921
  }
26866
- /**
26867
- * Add multiple rows by providing an array of arrays or key-value pairs
26868
- */
26869
26922
  addRows(value, style = "n") {
26870
26923
  const rows = [];
26871
26924
  value.forEach((row) => {
@@ -26873,19 +26926,11 @@ var ExcelTS = (function(exports) {
26873
26926
  });
26874
26927
  return rows;
26875
26928
  }
26876
- /**
26877
- * Insert a Row by key-value, at the position (shifting down all rows from position),
26878
- * using the column keys, or add a row by contiguous Array (assign to columns A, B & C)
26879
- */
26880
26929
  insertRow(pos, value, style = "n") {
26881
26930
  this.spliceRows(pos, 0, value);
26882
26931
  this._setStyleOption(pos, style);
26883
26932
  return this.getRow(pos);
26884
26933
  }
26885
- /**
26886
- * Insert multiple rows at position (shifting down all rows from position)
26887
- * by providing an array of arrays or key-value pairs
26888
- */
26889
26934
  insertRows(pos, values, style = "n") {
26890
26935
  this.spliceRows(pos, 0, ...values);
26891
26936
  if (style !== "n") {
@@ -27170,8 +27215,6 @@ var ExcelTS = (function(exports) {
27170
27215
  return Object.values(this.tables);
27171
27216
  }
27172
27217
  addPivotTable(model) {
27173
- console.warn(`Warning: Pivot Table support is experimental.
27174
- Please leave feedback at https://github.com/excelts/excelts/discussions/2575`);
27175
27218
  const pivotTable = makePivotTable(this, model);
27176
27219
  this.pivotTables.push(pivotTable);
27177
27220
  this.workbook.pivotTables.push(pivotTable);
@@ -27209,7 +27252,7 @@ Please leave feedback at https://github.com/excelts/excelts/discussions/2575`);
27209
27252
  pivotTables: this.pivotTables,
27210
27253
  conditionalFormattings: this.conditionalFormattings
27211
27254
  };
27212
- model.cols = Column.toModel(this.columns || []);
27255
+ model.cols = Column$1.toModel(this.columns || []);
27213
27256
  const rows = model.rows = [];
27214
27257
  const dimensions = model.dimensions = new Range();
27215
27258
  this._rows.forEach((row) => {
@@ -27240,7 +27283,7 @@ Please leave feedback at https://github.com/excelts/excelts/discussions/2575`);
27240
27283
  }
27241
27284
  set model(value) {
27242
27285
  this.name = value.name;
27243
- this._columns = Column.fromModel(this, value.cols);
27286
+ this._columns = Column$1.fromModel(this, value.cols);
27244
27287
  this._parseRows(value);
27245
27288
  this._parseMergeCells(value);
27246
27289
  this.dataValidations = new DataValidations(value.dataValidations);
@@ -33085,7 +33128,7 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
33085
33128
  //#endregion
33086
33129
  //#region node_modules/.pnpm/browserify-zlib@0.2.0/node_modules/browserify-zlib/lib/binding.js
33087
33130
  var require_binding = /* @__PURE__ */ __commonJSMin(((exports) => {
33088
- var import_buffer$7 = require_buffer$1();
33131
+ var import_buffer$2 = require_buffer$1();
33089
33132
  init_process();
33090
33133
  var assert = require_assert();
33091
33134
  var Zstream = require_zstream();
@@ -33151,7 +33194,7 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
33151
33194
  this.write_in_progress = true;
33152
33195
  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
33196
  if (input == null) {
33154
- input = import_buffer$7.Buffer.alloc(0);
33197
+ input = import_buffer$2.Buffer.alloc(0);
33155
33198
  in_len = 0;
33156
33199
  in_off = 0;
33157
33200
  }
@@ -33759,7 +33802,7 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
33759
33802
 
33760
33803
  //#endregion
33761
33804
  //#region src/utils/zip/crc32.ts
33762
- var import_stream_browserify$1 = require_stream_browserify();
33805
+ var import_stream_browserify = require_stream_browserify();
33763
33806
  var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
33764
33807
  init_process();
33765
33808
  const isNode$1 = typeof api !== "undefined" && api.versions?.node;
@@ -33815,7 +33858,6 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
33815
33858
 
33816
33859
  //#endregion
33817
33860
  //#region src/utils/zip/compress.ts
33818
- var import_buffer$6 = require_buffer$1();
33819
33861
  init_process();
33820
33862
  const isNode = typeof api !== "undefined" && api.versions?.node;
33821
33863
  let _zlib = null;
@@ -33865,7 +33907,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
33865
33907
  if (level === 0) return data;
33866
33908
  const zlib = await ensureZlib();
33867
33909
  if (zlib && typeof zlib.deflateRawSync === "function") {
33868
- const result = zlib.deflateRawSync(import_buffer$6.Buffer.from(data), { level });
33910
+ const result = zlib.deflateRawSync(import_buffer$3.Buffer.from(data), { level });
33869
33911
  return new Uint8Array(result.buffer, result.byteOffset, result.byteLength);
33870
33912
  }
33871
33913
  if (typeof CompressionStream !== "undefined") return compressWithCompressionStream(data);
@@ -33886,7 +33928,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
33886
33928
  if (level === 0) return data;
33887
33929
  const zlib = getZlib();
33888
33930
  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 });
33931
+ const result = zlib.deflateRawSync(import_buffer$3.Buffer.from(data), { level });
33890
33932
  return new Uint8Array(result.buffer, result.byteOffset, result.byteLength);
33891
33933
  }
33892
33934
  /**
@@ -34131,10 +34173,9 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34131
34173
 
34132
34174
  //#endregion
34133
34175
  //#region src/utils/string-buf.ts
34134
- var import_buffer$5 = require_buffer$1();
34135
34176
  var StringBuf = class {
34136
34177
  constructor(options) {
34137
- this._buf = import_buffer$5.Buffer.alloc(options && options.size || 16384);
34178
+ this._buf = import_buffer$3.Buffer.alloc(options && options.size || 16384);
34138
34179
  this._encoding = options && options.encoding || "utf8";
34139
34180
  this._inPos = 0;
34140
34181
  this._buffer = void 0;
@@ -34150,7 +34191,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34150
34191
  }
34151
34192
  toBuffer() {
34152
34193
  if (!this._buffer) {
34153
- this._buffer = import_buffer$5.Buffer.alloc(this.length);
34194
+ this._buffer = import_buffer$3.Buffer.alloc(this.length);
34154
34195
  this._buf.copy(this._buffer, 0, 0, this.length);
34155
34196
  }
34156
34197
  return this._buffer;
@@ -34163,7 +34204,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34163
34204
  _grow(min) {
34164
34205
  let size = this._buf.length * 2;
34165
34206
  while (size < min) size *= 2;
34166
- const buf = import_buffer$5.Buffer.alloc(size);
34207
+ const buf = import_buffer$3.Buffer.alloc(size);
34167
34208
  this._buf.copy(buf, 0);
34168
34209
  this._buf = buf;
34169
34210
  }
@@ -34188,7 +34229,6 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34188
34229
 
34189
34230
  //#endregion
34190
34231
  //#region src/utils/stream-buf.ts
34191
- var import_buffer$4 = require_buffer$1();
34192
34232
  var StringChunk = class {
34193
34233
  constructor(data, encoding) {
34194
34234
  this._data = data;
@@ -34201,7 +34241,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34201
34241
  return this.toBuffer().copy(target, targetOffset, offset, length);
34202
34242
  }
34203
34243
  toBuffer() {
34204
- if (!this._buffer) this._buffer = import_buffer$4.Buffer.from(this._data, this._encoding);
34244
+ if (!this._buffer) this._buffer = import_buffer$3.Buffer.from(this._data, this._encoding);
34205
34245
  return this._buffer;
34206
34246
  }
34207
34247
  };
@@ -34236,13 +34276,13 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34236
34276
  var ReadWriteBuf = class {
34237
34277
  constructor(size) {
34238
34278
  this.size = size;
34239
- this.buffer = import_buffer$4.Buffer.alloc(size);
34279
+ this.buffer = import_buffer$3.Buffer.alloc(size);
34240
34280
  this.iRead = 0;
34241
34281
  this.iWrite = 0;
34242
34282
  }
34243
34283
  toBuffer() {
34244
34284
  if (this.iRead === 0 && this.iWrite === this.size) return this.buffer;
34245
- const buf = import_buffer$4.Buffer.alloc(this.iWrite - this.iRead);
34285
+ const buf = import_buffer$3.Buffer.alloc(this.iWrite - this.iRead);
34246
34286
  this.buffer.copy(buf, 0, this.iRead, this.iWrite);
34247
34287
  return buf;
34248
34288
  }
@@ -34263,7 +34303,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34263
34303
  this.iRead = this.iWrite;
34264
34304
  return buf;
34265
34305
  }
34266
- buf = import_buffer$4.Buffer.alloc(size);
34306
+ buf = import_buffer$3.Buffer.alloc(size);
34267
34307
  this.buffer.copy(buf, 0, this.iRead, size);
34268
34308
  this.iRead += size;
34269
34309
  return buf;
@@ -34277,7 +34317,7 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34277
34317
  };
34278
34318
  const StreamBuf = function(options) {
34279
34319
  if (!(this instanceof StreamBuf)) return new StreamBuf(options);
34280
- import_stream_browserify$1.Duplex.call(this, options);
34320
+ import_stream_browserify.Duplex.call(this, options);
34281
34321
  options = options || {};
34282
34322
  this.bufSize = options.bufSize || 1024 * 1024;
34283
34323
  this.buffers = [];
@@ -34289,12 +34329,12 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34289
34329
  this.paused = false;
34290
34330
  this.encoding = null;
34291
34331
  };
34292
- inherits(StreamBuf, import_stream_browserify$1.Duplex, {
34332
+ inherits(StreamBuf, import_stream_browserify.Duplex, {
34293
34333
  toBuffer() {
34294
34334
  switch (this.buffers.length) {
34295
34335
  case 0: return null;
34296
34336
  case 1: return this.buffers[0].toBuffer();
34297
- default: return import_buffer$4.Buffer.concat(this.buffers.map((rwBuf) => rwBuf.toBuffer()));
34337
+ default: return import_buffer$3.Buffer.concat(this.buffers.map((rwBuf) => rwBuf.toBuffer()));
34298
34338
  }
34299
34339
  },
34300
34340
  _getWritableBuffer() {
@@ -34332,9 +34372,9 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34332
34372
  callback = callback || nop;
34333
34373
  let chunk;
34334
34374
  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));
34375
+ else if (import_buffer$3.Buffer.isBuffer(data)) chunk = new BufferChunk(data);
34376
+ else if (ArrayBuffer.isView(data)) chunk = new BufferChunk(import_buffer$3.Buffer.from(data.buffer, data.byteOffset, data.byteLength));
34377
+ else if (data instanceof ArrayBuffer) chunk = new BufferChunk(import_buffer$3.Buffer.from(data));
34338
34378
  else if (typeof data === "string" || data instanceof String) chunk = new StringChunk(String(data), encoding);
34339
34379
  else throw new Error("Chunk must be one of type String, Buffer, Uint8Array, ArrayBuffer or StringBuf.");
34340
34380
  if (this.pipes.length) if (this.batch) {
@@ -34389,11 +34429,11 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34389
34429
  buffers.push(buffer);
34390
34430
  if (first.eod && first.full) this.buffers.shift();
34391
34431
  }
34392
- return import_buffer$4.Buffer.concat(buffers);
34432
+ return import_buffer$3.Buffer.concat(buffers);
34393
34433
  }
34394
34434
  buffers = this.buffers.map((buf) => buf.toBuffer()).filter(Boolean);
34395
34435
  this.buffers = [];
34396
- return import_buffer$4.Buffer.concat(buffers);
34436
+ return import_buffer$3.Buffer.concat(buffers);
34397
34437
  },
34398
34438
  setEncoding(encoding) {
34399
34439
  this.encoding = encoding;
@@ -34425,7 +34465,6 @@ var import_events = /* @__PURE__ */ __toESM(require_events(), 1);
34425
34465
 
34426
34466
  //#endregion
34427
34467
  //#region src/utils/zip-stream.ts
34428
- var import_buffer$3 = require_buffer$1();
34429
34468
  var ZipWriter = class extends import_events.default.EventEmitter {
34430
34469
  constructor(options) {
34431
34470
  super();
@@ -38998,27 +39037,28 @@ ${XMLNS_NAMESPACE}.`);
38998
39037
  PartName: "/xl/workbook.xml",
38999
39038
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"
39000
39039
  });
39001
- model.worksheets.forEach((worksheet) => {
39002
- const name = `/xl/worksheets/sheet${worksheet.id}.xml`;
39040
+ model.worksheets.forEach((worksheet, index) => {
39041
+ const name = `/xl/worksheets/sheet${worksheet.fileIndex || index + 1}.xml`;
39003
39042
  xmlStream.leafNode("Override", {
39004
39043
  PartName: name,
39005
39044
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"
39006
39045
  });
39007
39046
  });
39008
- if ((model.pivotTables || []).length) {
39047
+ if ((model.pivotTables || []).length) (model.pivotTables || []).forEach((pivotTable) => {
39048
+ const n = pivotTable.tableNumber;
39009
39049
  xmlStream.leafNode("Override", {
39010
- PartName: "/xl/pivotCache/pivotCacheDefinition1.xml",
39050
+ PartName: `/xl/pivotCache/pivotCacheDefinition${n}.xml`,
39011
39051
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml"
39012
39052
  });
39013
39053
  xmlStream.leafNode("Override", {
39014
- PartName: "/xl/pivotCache/pivotCacheRecords1.xml",
39054
+ PartName: `/xl/pivotCache/pivotCacheRecords${n}.xml`,
39015
39055
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml"
39016
39056
  });
39017
39057
  xmlStream.leafNode("Override", {
39018
- PartName: "/xl/pivotTables/pivotTable1.xml",
39058
+ PartName: `/xl/pivotTables/pivotTable${n}.xml`,
39019
39059
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml"
39020
39060
  });
39021
- }
39061
+ });
39022
39062
  xmlStream.leafNode("Override", {
39023
39063
  PartName: "/xl/theme/theme1.xml",
39024
39064
  ContentType: "application/vnd.openxmlformats-officedocument.theme+xml"
@@ -39539,6 +39579,7 @@ ${XMLNS_NAMESPACE}.`);
39539
39579
  calcProperties: {}
39540
39580
  };
39541
39581
  if (this.map.definedNames.model) this.model.definedNames = this.map.definedNames.model;
39582
+ if (this.map.pivotCaches.model && this.map.pivotCaches.model.length > 0) this.model.pivotCaches = this.map.pivotCaches.model;
39542
39583
  return false;
39543
39584
  default: return true;
39544
39585
  }
@@ -39935,6 +39976,10 @@ ${XMLNS_NAMESPACE}.`);
39935
39976
  model.type = Enums.ValueType.Error;
39936
39977
  model.value = { error: model.value };
39937
39978
  break;
39979
+ case "d":
39980
+ model.type = Enums.ValueType.Date;
39981
+ model.value = new Date(model.value);
39982
+ break;
39938
39983
  default:
39939
39984
  model.type = Enums.ValueType.Number;
39940
39985
  model.value = parseFloat(model.value);
@@ -42521,10 +42566,12 @@ ${XMLNS_NAMESPACE}.`);
42521
42566
  if (style) column.dxfId = options.styles.addDxfStyle(style);
42522
42567
  });
42523
42568
  });
42524
- if ((model.pivotTables || []).length) rels.push({
42525
- Id: nextRid(rels),
42526
- Type: RelType.PivotTable,
42527
- Target: "../pivotTables/pivotTable1.xml"
42569
+ (model.pivotTables || []).forEach((pivotTable) => {
42570
+ rels.push({
42571
+ Id: nextRid(rels),
42572
+ Type: RelType.PivotTable,
42573
+ Target: `../pivotTables/pivotTable${pivotTable.tableNumber}.xml`
42574
+ });
42528
42575
  });
42529
42576
  this.map.extLst.prepare(model, options);
42530
42577
  }
@@ -42695,6 +42742,13 @@ ${XMLNS_NAMESPACE}.`);
42695
42742
  const rel = rels[tablePart.rId];
42696
42743
  return options.tables[rel.Target];
42697
42744
  });
42745
+ model.pivotTables = [];
42746
+ (model.relationships || []).forEach((rel) => {
42747
+ if (rel.Type === RelType.PivotTable && options.pivotTables) {
42748
+ const pivotTable = options.pivotTables[rel.Target];
42749
+ if (pivotTable) model.pivotTables.push(pivotTable);
42750
+ }
42751
+ });
42698
42752
  delete model.relationships;
42699
42753
  delete model.hyperlinks;
42700
42754
  delete model.comments;
@@ -43782,50 +43836,164 @@ ${XMLNS_NAMESPACE}.`);
43782
43836
  constructor() {
43783
43837
  super();
43784
43838
  this.map = {};
43839
+ this.model = null;
43840
+ this.currentRecord = null;
43785
43841
  }
43786
43842
  prepare(_model) {}
43787
43843
  get tag() {
43788
43844
  return "pivotCacheRecords";
43789
43845
  }
43846
+ reset() {
43847
+ this.model = null;
43848
+ this.currentRecord = null;
43849
+ }
43850
+ /**
43851
+ * Render pivot cache records XML.
43852
+ * Supports both newly created models (with PivotTableSource) and loaded models.
43853
+ */
43790
43854
  render(xmlStream, model) {
43791
- const { sourceSheet, cacheFields } = model;
43792
- const sourceBodyRows = sourceSheet.getSheetValues().slice(2);
43855
+ if (model.isLoaded || !("source" in model)) this.renderLoaded(xmlStream, model);
43856
+ else this.renderNew(xmlStream, model);
43857
+ }
43858
+ /**
43859
+ * Render newly created pivot cache records
43860
+ */
43861
+ renderNew(xmlStream, model) {
43862
+ const { source, cacheFields } = model;
43863
+ const sourceBodyRows = source.getSheetValues().slice(2);
43793
43864
  xmlStream.openXml(XmlStream.StdDocAttributes);
43794
43865
  xmlStream.openNode(this.tag, {
43795
43866
  ...PivotCacheRecordsXform.PIVOT_CACHE_RECORDS_ATTRIBUTES,
43796
43867
  count: sourceBodyRows.length
43797
43868
  });
43798
- xmlStream.writeXml(renderTable());
43869
+ xmlStream.writeXml(this.renderTableNew(sourceBodyRows, cacheFields));
43799
43870
  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);
43871
+ }
43872
+ /**
43873
+ * Render loaded pivot cache records
43874
+ */
43875
+ renderLoaded(xmlStream, model) {
43876
+ xmlStream.openXml(XmlStream.StdDocAttributes);
43877
+ xmlStream.openNode(this.tag, {
43878
+ ...PivotCacheRecordsXform.PIVOT_CACHE_RECORDS_ATTRIBUTES,
43879
+ count: model.count
43880
+ });
43881
+ for (const record of model.records) {
43882
+ xmlStream.writeXml("\n <r>");
43883
+ for (const value of record) {
43884
+ xmlStream.writeXml("\n ");
43885
+ xmlStream.writeXml(this.renderRecordValue(value));
43810
43886
  }
43811
- yield "\n </r>";
43887
+ xmlStream.writeXml("\n </r>");
43812
43888
  }
43813
- function renderCell(value, sharedItems) {
43814
- if (sharedItems === null) {
43815
- if (Number.isFinite(value)) return `<n v="${value}" />`;
43816
- return `<s v="${value}" />`;
43889
+ xmlStream.closeNode();
43890
+ }
43891
+ /**
43892
+ * Render a single record value to XML
43893
+ */
43894
+ renderRecordValue(value) {
43895
+ switch (value.type) {
43896
+ case "x": return `<x v="${value.value}" />`;
43897
+ case "n": return `<n v="${value.value}" />`;
43898
+ case "s": return `<s v="${xmlEncode(String(value.value))}" />`;
43899
+ case "b": return `<b v="${value.value ? "1" : "0"}" />`;
43900
+ case "m": return "<m />";
43901
+ case "d": return `<d v="${value.value.toISOString()}" />`;
43902
+ case "e": return `<e v="${value.value}" />`;
43903
+ default: return "<m />";
43904
+ }
43905
+ }
43906
+ renderTableNew(sourceBodyRows, cacheFields) {
43907
+ const parts = [];
43908
+ for (const row of sourceBodyRows) {
43909
+ const realRow = row.slice(1);
43910
+ parts.push("\n <r>");
43911
+ for (let i$1 = 0; i$1 < realRow.length; i$1++) {
43912
+ parts.push("\n ");
43913
+ parts.push(this.renderCellNew(realRow[i$1], cacheFields[i$1].sharedItems));
43817
43914
  }
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}" />`;
43915
+ parts.push("\n </r>");
43821
43916
  }
43917
+ return parts.join("");
43822
43918
  }
43823
- parseOpen(_node) {
43824
- return false;
43919
+ renderCellNew(value, sharedItems) {
43920
+ if (value === null || value === void 0) return "<m />";
43921
+ if (sharedItems === null) {
43922
+ if (Number.isFinite(value)) return `<n v="${value}" />`;
43923
+ return `<s v="${xmlEncode(String(value))}" />`;
43924
+ }
43925
+ const sharedItemsIndex = sharedItems.indexOf(value);
43926
+ if (sharedItemsIndex < 0) throw new Error(`${JSON.stringify(value)} not in sharedItems ${JSON.stringify(sharedItems)}`);
43927
+ return `<x v="${sharedItemsIndex}" />`;
43928
+ }
43929
+ parseOpen(node) {
43930
+ const { name, attributes } = node;
43931
+ switch (name) {
43932
+ case this.tag:
43933
+ this.reset();
43934
+ this.model = {
43935
+ records: [],
43936
+ count: parseInt(attributes.count || "0", 10),
43937
+ isLoaded: true
43938
+ };
43939
+ break;
43940
+ case "r":
43941
+ this.currentRecord = [];
43942
+ break;
43943
+ case "x":
43944
+ if (this.currentRecord) this.currentRecord.push({
43945
+ type: "x",
43946
+ value: parseInt(attributes.v || "0", 10)
43947
+ });
43948
+ break;
43949
+ case "n":
43950
+ if (this.currentRecord) this.currentRecord.push({
43951
+ type: "n",
43952
+ value: parseFloat(attributes.v || "0")
43953
+ });
43954
+ break;
43955
+ case "s":
43956
+ if (this.currentRecord) this.currentRecord.push({
43957
+ type: "s",
43958
+ value: xmlDecode(attributes.v || "")
43959
+ });
43960
+ break;
43961
+ case "b":
43962
+ if (this.currentRecord) this.currentRecord.push({
43963
+ type: "b",
43964
+ value: attributes.v === "1"
43965
+ });
43966
+ break;
43967
+ case "m":
43968
+ if (this.currentRecord) this.currentRecord.push({ type: "m" });
43969
+ break;
43970
+ case "d":
43971
+ if (this.currentRecord) this.currentRecord.push({
43972
+ type: "d",
43973
+ value: new Date(attributes.v || "")
43974
+ });
43975
+ break;
43976
+ case "e":
43977
+ if (this.currentRecord) this.currentRecord.push({
43978
+ type: "e",
43979
+ value: attributes.v || ""
43980
+ });
43981
+ break;
43982
+ }
43983
+ return true;
43825
43984
  }
43826
43985
  parseText(_text) {}
43827
- parseClose(_name) {
43828
- return false;
43986
+ parseClose(name) {
43987
+ switch (name) {
43988
+ case this.tag: return false;
43989
+ case "r":
43990
+ if (this.model && this.currentRecord) {
43991
+ this.model.records.push(this.currentRecord);
43992
+ this.currentRecord = null;
43993
+ }
43994
+ break;
43995
+ }
43996
+ return true;
43829
43997
  }
43830
43998
  reconcile(_model, _options) {}
43831
43999
  static {
@@ -43847,30 +44015,157 @@ ${XMLNS_NAMESPACE}.`);
43847
44015
  this.sharedItems = sharedItems;
43848
44016
  }
43849
44017
  render() {
43850
- if (this.sharedItems === null) return `<cacheField name="${this.name}" numFmtId="0">
44018
+ const escapedName = xmlEncode(this.name);
44019
+ if (this.sharedItems === null) return `<cacheField name="${escapedName}" numFmtId="0">
43851
44020
  <sharedItems containsSemiMixedTypes="0" containsString="0" containsNumber="1" containsInteger="1" />
43852
44021
  </cacheField>`;
43853
- return `<cacheField name="${this.name}" numFmtId="0">
44022
+ return `<cacheField name="${escapedName}" numFmtId="0">
43854
44023
  <sharedItems count="${this.sharedItems.length}">
43855
- ${this.sharedItems.map((item) => `<s v="${item}" />`).join("")}
44024
+ ${this.sharedItems.map((item) => `<s v="${xmlEncode(String(item))}" />`).join("")}
43856
44025
  </sharedItems>
43857
44026
  </cacheField>`;
43858
44027
  }
43859
44028
  };
43860
44029
 
44030
+ //#endregion
44031
+ //#region src/xlsx/xform/pivot-table/cache-field-xform.ts
44032
+ /**
44033
+ * Xform for parsing individual <cacheField> elements within a pivot cache definition.
44034
+ *
44035
+ * Example XML:
44036
+ * ```xml
44037
+ * <cacheField name="Category" numFmtId="0">
44038
+ * <sharedItems count="3">
44039
+ * <s v="A" />
44040
+ * <s v="B" />
44041
+ * <s v="C" />
44042
+ * </sharedItems>
44043
+ * </cacheField>
44044
+ *
44045
+ * <cacheField name="Value" numFmtId="0">
44046
+ * <sharedItems containsSemiMixedTypes="0" containsString="0"
44047
+ * containsNumber="1" containsInteger="1" minValue="5" maxValue="45" />
44048
+ * </cacheField>
44049
+ * ```
44050
+ */
44051
+ var CacheFieldXform = class extends BaseXform {
44052
+ constructor() {
44053
+ super();
44054
+ this.model = null;
44055
+ this.inSharedItems = false;
44056
+ }
44057
+ get tag() {
44058
+ return "cacheField";
44059
+ }
44060
+ reset() {
44061
+ this.model = null;
44062
+ this.inSharedItems = false;
44063
+ }
44064
+ parseOpen(node) {
44065
+ const { name, attributes } = node;
44066
+ switch (name) {
44067
+ case "cacheField":
44068
+ this.model = {
44069
+ name: xmlDecode(attributes.name || ""),
44070
+ sharedItems: null
44071
+ };
44072
+ break;
44073
+ case "sharedItems":
44074
+ this.inSharedItems = true;
44075
+ if (attributes.containsNumber === "1" || attributes.containsInteger === "1") {
44076
+ if (this.model) {
44077
+ this.model.containsNumber = attributes.containsNumber === "1";
44078
+ this.model.containsInteger = attributes.containsInteger === "1";
44079
+ if (attributes.minValue !== void 0) this.model.minValue = parseFloat(attributes.minValue);
44080
+ if (attributes.maxValue !== void 0) this.model.maxValue = parseFloat(attributes.maxValue);
44081
+ this.model.sharedItems = null;
44082
+ }
44083
+ } else if (this.model) {
44084
+ if (parseInt(attributes.count || "0", 10) > 0) this.model.sharedItems = [];
44085
+ }
44086
+ break;
44087
+ case "s":
44088
+ if (this.inSharedItems && this.model?.sharedItems !== null) {
44089
+ const value = xmlDecode(attributes.v || "");
44090
+ this.model.sharedItems.push(value);
44091
+ }
44092
+ break;
44093
+ case "n":
44094
+ if (this.inSharedItems && this.model?.sharedItems !== null) {
44095
+ const value = parseFloat(attributes.v || "0");
44096
+ this.model.sharedItems.push(value);
44097
+ }
44098
+ break;
44099
+ case "b":
44100
+ if (this.inSharedItems && this.model?.sharedItems !== null) {
44101
+ const value = attributes.v === "1";
44102
+ this.model.sharedItems.push(value);
44103
+ }
44104
+ break;
44105
+ case "e":
44106
+ if (this.inSharedItems && this.model?.sharedItems !== null) {
44107
+ const value = `#${attributes.v || "ERROR!"}`;
44108
+ this.model.sharedItems.push(value);
44109
+ }
44110
+ break;
44111
+ case "m":
44112
+ if (this.inSharedItems && this.model?.sharedItems !== null) this.model.sharedItems.push(null);
44113
+ break;
44114
+ case "d":
44115
+ if (this.inSharedItems && this.model?.sharedItems !== null) {
44116
+ const value = new Date(attributes.v || "");
44117
+ this.model.sharedItems.push(value);
44118
+ }
44119
+ break;
44120
+ }
44121
+ return true;
44122
+ }
44123
+ parseText(_text) {}
44124
+ parseClose(name) {
44125
+ switch (name) {
44126
+ case "cacheField": return false;
44127
+ case "sharedItems":
44128
+ this.inSharedItems = false;
44129
+ break;
44130
+ }
44131
+ return true;
44132
+ }
44133
+ };
44134
+
43861
44135
  //#endregion
43862
44136
  //#region src/xlsx/xform/pivot-table/pivot-cache-definition-xform.ts
43863
44137
  var PivotCacheDefinitionXform = class PivotCacheDefinitionXform extends BaseXform {
43864
44138
  constructor() {
43865
44139
  super();
43866
44140
  this.map = {};
44141
+ this.model = null;
44142
+ this.currentCacheField = null;
44143
+ this.inCacheFields = false;
44144
+ this.inCacheSource = false;
43867
44145
  }
43868
44146
  prepare(_model) {}
43869
44147
  get tag() {
43870
44148
  return "pivotCacheDefinition";
43871
44149
  }
44150
+ reset() {
44151
+ this.model = null;
44152
+ this.currentCacheField = null;
44153
+ this.inCacheFields = false;
44154
+ this.inCacheSource = false;
44155
+ }
44156
+ /**
44157
+ * Render pivot cache definition XML.
44158
+ * Supports both newly created models (with PivotTableSource) and loaded models.
44159
+ */
43872
44160
  render(xmlStream, model) {
43873
- const { sourceSheet, cacheFields } = model;
44161
+ if (model.isLoaded || !("source" in model)) this.renderLoaded(xmlStream, model);
44162
+ else this.renderNew(xmlStream, model);
44163
+ }
44164
+ /**
44165
+ * Render newly created pivot cache definition
44166
+ */
44167
+ renderNew(xmlStream, model) {
44168
+ const { source, cacheFields } = model;
43874
44169
  xmlStream.openXml(XmlStream.StdDocAttributes);
43875
44170
  xmlStream.openNode(this.tag, {
43876
44171
  ...PivotCacheDefinitionXform.PIVOT_CACHE_DEFINITION_ATTRIBUTES,
@@ -43885,8 +44180,8 @@ ${XMLNS_NAMESPACE}.`);
43885
44180
  });
43886
44181
  xmlStream.openNode("cacheSource", { type: "worksheet" });
43887
44182
  xmlStream.leafNode("worksheetSource", {
43888
- ref: sourceSheet.dimensions.shortRange,
43889
- sheet: sourceSheet.name
44183
+ ref: source.dimensions.shortRange,
44184
+ sheet: source.name
43890
44185
  });
43891
44186
  xmlStream.closeNode();
43892
44187
  xmlStream.openNode("cacheFields", { count: cacheFields.length });
@@ -43894,12 +44189,98 @@ ${XMLNS_NAMESPACE}.`);
43894
44189
  xmlStream.closeNode();
43895
44190
  xmlStream.closeNode();
43896
44191
  }
43897
- parseOpen(_node) {
43898
- return false;
44192
+ /**
44193
+ * Render loaded pivot cache definition (preserving original structure)
44194
+ */
44195
+ renderLoaded(xmlStream, model) {
44196
+ const { cacheFields, sourceRef, sourceSheet, recordCount } = model;
44197
+ xmlStream.openXml(XmlStream.StdDocAttributes);
44198
+ xmlStream.openNode(this.tag, {
44199
+ ...PivotCacheDefinitionXform.PIVOT_CACHE_DEFINITION_ATTRIBUTES,
44200
+ "r:id": model.rId || "rId1",
44201
+ refreshOnLoad: model.refreshOnLoad || "1",
44202
+ refreshedBy: model.refreshedBy || "Author",
44203
+ refreshedDate: model.refreshedDate || "45125.026046874998",
44204
+ createdVersion: model.createdVersion || "8",
44205
+ refreshedVersion: model.refreshedVersion || "8",
44206
+ minRefreshableVersion: model.minRefreshableVersion || "3",
44207
+ recordCount: recordCount || cacheFields.length + 1
44208
+ });
44209
+ xmlStream.openNode("cacheSource", { type: "worksheet" });
44210
+ xmlStream.leafNode("worksheetSource", {
44211
+ ref: sourceRef,
44212
+ sheet: sourceSheet
44213
+ });
44214
+ xmlStream.closeNode();
44215
+ xmlStream.openNode("cacheFields", { count: cacheFields.length });
44216
+ xmlStream.writeXml(cacheFields.map((cacheField) => new CacheField(cacheField).render()).join("\n "));
44217
+ xmlStream.closeNode();
44218
+ xmlStream.closeNode();
43899
44219
  }
43900
- parseText(_text) {}
43901
- parseClose(_name) {
43902
- return false;
44220
+ parseOpen(node) {
44221
+ const { name, attributes } = node;
44222
+ if (this.currentCacheField) {
44223
+ this.currentCacheField.parseOpen(node);
44224
+ return true;
44225
+ }
44226
+ switch (name) {
44227
+ case this.tag:
44228
+ this.reset();
44229
+ this.model = {
44230
+ cacheFields: [],
44231
+ rId: attributes["r:id"],
44232
+ refreshOnLoad: attributes.refreshOnLoad,
44233
+ refreshedBy: attributes.refreshedBy,
44234
+ refreshedDate: attributes.refreshedDate,
44235
+ createdVersion: attributes.createdVersion,
44236
+ refreshedVersion: attributes.refreshedVersion,
44237
+ minRefreshableVersion: attributes.minRefreshableVersion,
44238
+ recordCount: attributes.recordCount ? parseInt(attributes.recordCount, 10) : void 0,
44239
+ isLoaded: true
44240
+ };
44241
+ break;
44242
+ case "cacheSource":
44243
+ this.inCacheSource = true;
44244
+ break;
44245
+ case "worksheetSource":
44246
+ if (this.inCacheSource && this.model) {
44247
+ this.model.sourceRef = attributes.ref;
44248
+ this.model.sourceSheet = attributes.sheet;
44249
+ }
44250
+ break;
44251
+ case "cacheFields":
44252
+ this.inCacheFields = true;
44253
+ break;
44254
+ case "cacheField":
44255
+ if (this.inCacheFields) {
44256
+ this.currentCacheField = new CacheFieldXform();
44257
+ this.currentCacheField.parseOpen(node);
44258
+ }
44259
+ break;
44260
+ }
44261
+ return true;
44262
+ }
44263
+ parseText(text) {
44264
+ if (this.currentCacheField) this.currentCacheField.parseText(text);
44265
+ }
44266
+ parseClose(name) {
44267
+ if (this.currentCacheField) {
44268
+ if (!this.currentCacheField.parseClose(name)) {
44269
+ if (this.model && this.currentCacheField.model) this.model.cacheFields.push(this.currentCacheField.model);
44270
+ this.currentCacheField = null;
44271
+ }
44272
+ return true;
44273
+ }
44274
+ switch (name) {
44275
+ case this.tag: return false;
44276
+ case "cacheSource":
44277
+ this.inCacheSource = false;
44278
+ break;
44279
+ case "cacheFields":
44280
+ this.inCacheFields = false;
44281
+ break;
44282
+ }
44283
+ return true;
43903
44284
  }
43904
44285
  reconcile(_model, _options) {}
43905
44286
  static {
@@ -43919,17 +44300,53 @@ ${XMLNS_NAMESPACE}.`);
43919
44300
  constructor() {
43920
44301
  super();
43921
44302
  this.map = {};
44303
+ this.model = null;
44304
+ this.inPivotFields = false;
44305
+ this.inRowFields = false;
44306
+ this.inColFields = false;
44307
+ this.inDataFields = false;
44308
+ this.inRowItems = false;
44309
+ this.inColItems = false;
44310
+ this.inLocation = false;
44311
+ this.currentPivotField = null;
44312
+ this.inItems = false;
44313
+ this.inPivotTableStyleInfo = false;
43922
44314
  }
43923
44315
  prepare(_model) {}
43924
44316
  get tag() {
43925
44317
  return "pivotTableDefinition";
43926
44318
  }
44319
+ reset() {
44320
+ this.model = null;
44321
+ this.inPivotFields = false;
44322
+ this.inRowFields = false;
44323
+ this.inColFields = false;
44324
+ this.inDataFields = false;
44325
+ this.inRowItems = false;
44326
+ this.inColItems = false;
44327
+ this.inLocation = false;
44328
+ this.currentPivotField = null;
44329
+ this.inItems = false;
44330
+ this.inPivotTableStyleInfo = false;
44331
+ }
44332
+ /**
44333
+ * Render pivot table XML.
44334
+ * Supports both newly created models and loaded models.
44335
+ */
43927
44336
  render(xmlStream, model) {
43928
- const { rows, columns, values, cacheFields, cacheId } = model;
44337
+ if (model.isLoaded) this.renderLoaded(xmlStream, model);
44338
+ else this.renderNew(xmlStream, model);
44339
+ }
44340
+ /**
44341
+ * Render newly created pivot table
44342
+ */
44343
+ renderNew(xmlStream, model) {
44344
+ const { rows, columns, values, cacheFields, cacheId, applyWidthHeightFormats } = model;
44345
+ const uniqueUid = `{${v4_default().toUpperCase()}}`;
43929
44346
  xmlStream.openXml(XmlStream.StdDocAttributes);
43930
44347
  xmlStream.openNode(this.tag, {
43931
44348
  ...PivotTableXform.PIVOT_TABLE_ATTRIBUTES,
43932
- "xr:uid": "{267EE50F-B116-784D-8DC2-BA77DE3F4F4A}",
44349
+ "xr:uid": uniqueUid,
43933
44350
  name: "PivotTable2",
43934
44351
  cacheId,
43935
44352
  applyNumberFormats: "0",
@@ -43937,7 +44354,7 @@ ${XMLNS_NAMESPACE}.`);
43937
44354
  applyFontFormats: "0",
43938
44355
  applyPatternFormats: "0",
43939
44356
  applyAlignmentFormats: "0",
43940
- applyWidthHeightFormats: "1",
44357
+ applyWidthHeightFormats,
43941
44358
  dataCaption: "Values",
43942
44359
  updatedVersion: "8",
43943
44360
  minRefreshableVersion: "3",
@@ -43960,19 +44377,14 @@ ${XMLNS_NAMESPACE}.`);
43960
44377
  <rowItems count="1">
43961
44378
  <i t="grand"><x /></i>
43962
44379
  </rowItems>
43963
- <colFields count="${columns.length}">
43964
- ${columns.map((columnIndex) => `<field x="${columnIndex}" />`).join("\n ")}
44380
+ <colFields count="${columns.length === 0 ? 1 : columns.length}">
44381
+ ${columns.length === 0 ? "<field x=\"-2\" />" : columns.map((columnIndex) => `<field x="${columnIndex}" />`).join("\n ")}
43965
44382
  </colFields>
43966
44383
  <colItems count="1">
43967
44384
  <i t="grand"><x /></i>
43968
44385
  </colItems>
43969
44386
  <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
- />
44387
+ ${buildDataFields(cacheFields, values, model.metric)}
43976
44388
  </dataFields>
43977
44389
  <pivotTableStyleInfo
43978
44390
  name="PivotStyleLight16"
@@ -44005,12 +44417,260 @@ ${XMLNS_NAMESPACE}.`);
44005
44417
  `);
44006
44418
  xmlStream.closeNode();
44007
44419
  }
44008
- parseOpen(_node) {
44009
- return false;
44420
+ /**
44421
+ * Render loaded pivot table (preserving original structure)
44422
+ */
44423
+ renderLoaded(xmlStream, model) {
44424
+ const uniqueUid = model.uid || `{${v4_default().toUpperCase()}}`;
44425
+ xmlStream.openXml(XmlStream.StdDocAttributes);
44426
+ xmlStream.openNode(this.tag, {
44427
+ ...PivotTableXform.PIVOT_TABLE_ATTRIBUTES,
44428
+ "xr:uid": uniqueUid,
44429
+ name: model.name || "PivotTable1",
44430
+ cacheId: model.cacheId,
44431
+ applyNumberFormats: model.applyNumberFormats || "0",
44432
+ applyBorderFormats: model.applyBorderFormats || "0",
44433
+ applyFontFormats: model.applyFontFormats || "0",
44434
+ applyPatternFormats: model.applyPatternFormats || "0",
44435
+ applyAlignmentFormats: model.applyAlignmentFormats || "0",
44436
+ applyWidthHeightFormats: model.applyWidthHeightFormats || "0",
44437
+ dataCaption: model.dataCaption || "Values",
44438
+ updatedVersion: model.updatedVersion || "8",
44439
+ minRefreshableVersion: model.minRefreshableVersion || "3",
44440
+ useAutoFormatting: model.useAutoFormatting ? "1" : "0",
44441
+ itemPrintTitles: model.itemPrintTitles ? "1" : "0",
44442
+ createdVersion: model.createdVersion || "8",
44443
+ indent: model.indent !== void 0 ? String(model.indent) : "0",
44444
+ compact: model.compact ? "1" : "0",
44445
+ compactData: model.compactData ? "1" : "0",
44446
+ multipleFieldFilters: model.multipleFieldFilters ? "1" : "0"
44447
+ });
44448
+ if (model.location) xmlStream.leafNode("location", {
44449
+ ref: model.location.ref,
44450
+ firstHeaderRow: model.location.firstHeaderRow,
44451
+ firstDataRow: model.location.firstDataRow,
44452
+ firstDataCol: model.location.firstDataCol
44453
+ });
44454
+ if (model.pivotFields.length > 0) {
44455
+ xmlStream.openNode("pivotFields", { count: model.pivotFields.length });
44456
+ for (const pivotField of model.pivotFields) this.renderPivotFieldLoaded(xmlStream, pivotField);
44457
+ xmlStream.closeNode();
44458
+ }
44459
+ if (model.rowFields.length > 0) {
44460
+ xmlStream.openNode("rowFields", { count: model.rowFields.length });
44461
+ for (const fieldIndex of model.rowFields) xmlStream.leafNode("field", { x: fieldIndex });
44462
+ xmlStream.closeNode();
44463
+ }
44464
+ xmlStream.writeXml(`
44465
+ <rowItems count="1">
44466
+ <i t="grand"><x /></i>
44467
+ </rowItems>`);
44468
+ const colFieldCount = model.colFields.length === 0 ? 1 : model.colFields.length;
44469
+ xmlStream.openNode("colFields", { count: colFieldCount });
44470
+ if (model.colFields.length === 0) xmlStream.leafNode("field", { x: -2 });
44471
+ else for (const fieldIndex of model.colFields) xmlStream.leafNode("field", { x: fieldIndex });
44472
+ xmlStream.closeNode();
44473
+ xmlStream.writeXml(`
44474
+ <colItems count="1">
44475
+ <i t="grand"><x /></i>
44476
+ </colItems>`);
44477
+ if (model.dataFields.length > 0) {
44478
+ xmlStream.openNode("dataFields", { count: model.dataFields.length });
44479
+ for (const dataField of model.dataFields) {
44480
+ const attrs = {
44481
+ name: dataField.name,
44482
+ fld: dataField.fld,
44483
+ baseField: dataField.baseField ?? 0,
44484
+ baseItem: dataField.baseItem ?? 0
44485
+ };
44486
+ if (dataField.subtotal && dataField.subtotal !== "sum") attrs.subtotal = dataField.subtotal;
44487
+ xmlStream.leafNode("dataField", attrs);
44488
+ }
44489
+ xmlStream.closeNode();
44490
+ }
44491
+ xmlStream.leafNode("pivotTableStyleInfo", {
44492
+ name: model.styleName || "PivotStyleLight16",
44493
+ showRowHeaders: "1",
44494
+ showColHeaders: "1",
44495
+ showRowStripes: "0",
44496
+ showColStripes: "0",
44497
+ showLastColumn: "1"
44498
+ });
44499
+ xmlStream.writeXml(`
44500
+ <extLst>
44501
+ <ext
44502
+ uri="{962EF5D1-5CA2-4c93-8EF4-DBF5C05439D2}"
44503
+ xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
44504
+ >
44505
+ <x14:pivotTableDefinition
44506
+ hideValuesRow="1"
44507
+ xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main"
44508
+ />
44509
+ </ext>
44510
+ <ext
44511
+ uri="{747A6164-185A-40DC-8AA5-F01512510D54}"
44512
+ xmlns:xpdl="http://schemas.microsoft.com/office/spreadsheetml/2016/pivotdefaultlayout"
44513
+ >
44514
+ <xpdl:pivotTableDefinition16
44515
+ EnabledSubtotalsDefault="0"
44516
+ SubtotalsOnTopDefault="0"
44517
+ />
44518
+ </ext>
44519
+ </extLst>
44520
+ `);
44521
+ xmlStream.closeNode();
44522
+ }
44523
+ /**
44524
+ * Render a loaded pivot field
44525
+ */
44526
+ renderPivotFieldLoaded(xmlStream, field) {
44527
+ const attrs = {
44528
+ compact: field.compact ? "1" : "0",
44529
+ outline: field.outline ? "1" : "0",
44530
+ showAll: field.showAll ? "1" : "0",
44531
+ defaultSubtotal: field.defaultSubtotal ? "1" : "0"
44532
+ };
44533
+ if (field.axis) attrs.axis = field.axis;
44534
+ if (field.dataField) attrs.dataField = "1";
44535
+ if (field.items && field.items.length > 0) {
44536
+ xmlStream.openNode("pivotField", attrs);
44537
+ xmlStream.openNode("items", { count: field.items.length + 1 });
44538
+ for (const itemIndex of field.items) xmlStream.leafNode("item", { x: itemIndex });
44539
+ xmlStream.writeXml("<item t=\"default\" />");
44540
+ xmlStream.closeNode();
44541
+ xmlStream.closeNode();
44542
+ } else xmlStream.leafNode("pivotField", attrs);
44543
+ }
44544
+ parseOpen(node) {
44545
+ const { name, attributes } = node;
44546
+ switch (name) {
44547
+ case this.tag:
44548
+ this.reset();
44549
+ this.model = {
44550
+ name: attributes.name,
44551
+ cacheId: parseInt(attributes.cacheId || "0", 10),
44552
+ uid: attributes["xr:uid"],
44553
+ pivotFields: [],
44554
+ rowFields: [],
44555
+ colFields: [],
44556
+ dataFields: [],
44557
+ applyNumberFormats: attributes.applyNumberFormats,
44558
+ applyBorderFormats: attributes.applyBorderFormats,
44559
+ applyFontFormats: attributes.applyFontFormats,
44560
+ applyPatternFormats: attributes.applyPatternFormats,
44561
+ applyAlignmentFormats: attributes.applyAlignmentFormats,
44562
+ applyWidthHeightFormats: attributes.applyWidthHeightFormats,
44563
+ dataCaption: attributes.dataCaption,
44564
+ updatedVersion: attributes.updatedVersion,
44565
+ minRefreshableVersion: attributes.minRefreshableVersion,
44566
+ createdVersion: attributes.createdVersion,
44567
+ useAutoFormatting: attributes.useAutoFormatting === "1",
44568
+ itemPrintTitles: attributes.itemPrintTitles === "1",
44569
+ indent: attributes.indent ? parseInt(attributes.indent, 10) : 0,
44570
+ compact: attributes.compact === "1",
44571
+ compactData: attributes.compactData === "1",
44572
+ multipleFieldFilters: attributes.multipleFieldFilters === "1",
44573
+ isLoaded: true
44574
+ };
44575
+ break;
44576
+ case "location":
44577
+ if (this.model) this.model.location = {
44578
+ ref: attributes.ref,
44579
+ firstHeaderRow: attributes.firstHeaderRow ? parseInt(attributes.firstHeaderRow, 10) : void 0,
44580
+ firstDataRow: attributes.firstDataRow ? parseInt(attributes.firstDataRow, 10) : void 0,
44581
+ firstDataCol: attributes.firstDataCol ? parseInt(attributes.firstDataCol, 10) : void 0
44582
+ };
44583
+ break;
44584
+ case "pivotFields":
44585
+ this.inPivotFields = true;
44586
+ break;
44587
+ case "pivotField":
44588
+ if (this.inPivotFields) this.currentPivotField = {
44589
+ axis: attributes.axis,
44590
+ dataField: attributes.dataField === "1",
44591
+ items: [],
44592
+ compact: attributes.compact === "1",
44593
+ outline: attributes.outline === "1",
44594
+ showAll: attributes.showAll === "1",
44595
+ defaultSubtotal: attributes.defaultSubtotal === "1"
44596
+ };
44597
+ break;
44598
+ case "items":
44599
+ if (this.currentPivotField) this.inItems = true;
44600
+ break;
44601
+ case "item":
44602
+ if (this.inItems && this.currentPivotField && attributes.x !== void 0) this.currentPivotField.items.push(parseInt(attributes.x, 10));
44603
+ break;
44604
+ case "rowFields":
44605
+ this.inRowFields = true;
44606
+ break;
44607
+ case "colFields":
44608
+ this.inColFields = true;
44609
+ break;
44610
+ case "dataFields":
44611
+ this.inDataFields = true;
44612
+ break;
44613
+ case "rowItems":
44614
+ this.inRowItems = true;
44615
+ break;
44616
+ case "colItems":
44617
+ this.inColItems = true;
44618
+ break;
44619
+ case "field":
44620
+ if (this.model) {
44621
+ const fieldIndex = parseInt(attributes.x || "0", 10);
44622
+ if (this.inRowFields) this.model.rowFields.push(fieldIndex);
44623
+ else if (this.inColFields) this.model.colFields.push(fieldIndex);
44624
+ }
44625
+ break;
44626
+ case "dataField":
44627
+ if (this.inDataFields && this.model) this.model.dataFields.push({
44628
+ name: xmlDecode(attributes.name || ""),
44629
+ fld: parseInt(attributes.fld || "0", 10),
44630
+ baseField: attributes.baseField ? parseInt(attributes.baseField, 10) : 0,
44631
+ baseItem: attributes.baseItem ? parseInt(attributes.baseItem, 10) : 0,
44632
+ subtotal: attributes.subtotal
44633
+ });
44634
+ break;
44635
+ case "pivotTableStyleInfo":
44636
+ if (this.model) this.model.styleName = attributes.name;
44637
+ break;
44638
+ }
44639
+ return true;
44010
44640
  }
44011
44641
  parseText(_text) {}
44012
- parseClose(_name) {
44013
- return false;
44642
+ parseClose(name) {
44643
+ switch (name) {
44644
+ case this.tag: return false;
44645
+ case "pivotFields":
44646
+ this.inPivotFields = false;
44647
+ break;
44648
+ case "pivotField":
44649
+ if (this.currentPivotField && this.model) {
44650
+ this.model.pivotFields.push(this.currentPivotField);
44651
+ this.currentPivotField = null;
44652
+ }
44653
+ break;
44654
+ case "items":
44655
+ this.inItems = false;
44656
+ break;
44657
+ case "rowFields":
44658
+ this.inRowFields = false;
44659
+ break;
44660
+ case "colFields":
44661
+ this.inColFields = false;
44662
+ break;
44663
+ case "dataFields":
44664
+ this.inDataFields = false;
44665
+ break;
44666
+ case "rowItems":
44667
+ this.inRowItems = false;
44668
+ break;
44669
+ case "colItems":
44670
+ this.inColItems = false;
44671
+ break;
44672
+ }
44673
+ return true;
44014
44674
  }
44015
44675
  reconcile(_model, _options) {}
44016
44676
  static {
@@ -44022,9 +44682,26 @@ ${XMLNS_NAMESPACE}.`);
44022
44682
  };
44023
44683
  }
44024
44684
  };
44685
+ /**
44686
+ * Build dataField XML elements for all values in the pivot table.
44687
+ * Supports multiple values when columns is empty.
44688
+ */
44689
+ function buildDataFields(cacheFields, values, metric) {
44690
+ const metricName = metric === "count" ? "Count" : "Sum";
44691
+ const subtotalAttr = metric === "count" ? " subtotal=\"count\"" : "";
44692
+ return values.map((valueIndex) => `<dataField
44693
+ name="${metricName} of ${xmlEncode(cacheFields[valueIndex].name)}"
44694
+ fld="${valueIndex}"
44695
+ baseField="0"
44696
+ baseItem="0"${subtotalAttr}
44697
+ />`).join("");
44698
+ }
44025
44699
  function renderPivotFields(pivotTable) {
44700
+ const rowSet = new Set(pivotTable.rows);
44701
+ const colSet = new Set(pivotTable.columns);
44702
+ const valueSet = new Set(pivotTable.values);
44026
44703
  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);
44704
+ return renderPivotField(rowSet.has(fieldIndex) ? "row" : colSet.has(fieldIndex) ? "column" : valueSet.has(fieldIndex) ? "value" : null, cacheField.sharedItems);
44028
44705
  }).join("");
44029
44706
  }
44030
44707
  function renderPivotField(fieldType, sharedItems) {
@@ -44592,9 +45269,7 @@ ${XMLNS_NAMESPACE}.`);
44592
45269
 
44593
45270
  //#endregion
44594
45271
  //#region src/xlsx/xlsx.ts
44595
- var import_buffer$2 = require_buffer$1();
44596
45272
  init_empty();
44597
- var import_stream_browserify = require_stream_browserify();
44598
45273
  function fsReadFileAsync(filename, options) {
44599
45274
  return new Promise((resolve, reject) => {
44600
45275
  empty.readFile(filename, options, (error, data) => {
@@ -44660,6 +45335,7 @@ ${XMLNS_NAMESPACE}.`);
44660
45335
  Object.values(model.tables).forEach((table) => {
44661
45336
  tableXform.reconcile(table, tableOptions);
44662
45337
  });
45338
+ this._reconcilePivotTables(model);
44663
45339
  const sheetOptions = {
44664
45340
  styles: model.styles,
44665
45341
  sharedStrings: model.sharedStrings,
@@ -44669,7 +45345,8 @@ ${XMLNS_NAMESPACE}.`);
44669
45345
  drawings: model.drawings,
44670
45346
  comments: model.comments,
44671
45347
  tables: model.tables,
44672
- vmlDrawings: model.vmlDrawings
45348
+ vmlDrawings: model.vmlDrawings,
45349
+ pivotTables: model.pivotTablesIndexed
44673
45350
  };
44674
45351
  model.worksheets.forEach((worksheet) => {
44675
45352
  worksheet.relationships = model.worksheetRels[worksheet.sheetNo];
@@ -44686,6 +45363,99 @@ ${XMLNS_NAMESPACE}.`);
44686
45363
  delete model.drawings;
44687
45364
  delete model.drawingRels;
44688
45365
  delete model.vmlDrawings;
45366
+ delete model.pivotTableRels;
45367
+ delete model.pivotCacheDefinitionRels;
45368
+ }
45369
+ /**
45370
+ * Reconcile pivot tables by linking them to worksheets and their cache data.
45371
+ * This builds a complete pivot table model ready for writing.
45372
+ */
45373
+ _reconcilePivotTables(model) {
45374
+ const rawPivotTables = model.pivotTables || {};
45375
+ if (typeof rawPivotTables !== "object" || Object.keys(rawPivotTables).length === 0) {
45376
+ model.pivotTables = [];
45377
+ model.pivotTablesIndexed = {};
45378
+ return;
45379
+ }
45380
+ const definitionToCacheId = this._buildDefinitionToCacheIdMap(model);
45381
+ const cacheMap = /* @__PURE__ */ new Map();
45382
+ Object.entries(model.pivotCacheDefinitions || {}).forEach(([name, definition]) => {
45383
+ const cacheId = definitionToCacheId.get(name);
45384
+ if (cacheId !== void 0) {
45385
+ const recordsName = name.replace("Definition", "Records");
45386
+ cacheMap.set(cacheId, {
45387
+ definition,
45388
+ records: model.pivotCacheRecords?.[recordsName],
45389
+ definitionName: name
45390
+ });
45391
+ }
45392
+ });
45393
+ const loadedPivotTables = [];
45394
+ const pivotTablesIndexed = {};
45395
+ Object.entries(rawPivotTables).forEach(([pivotName, pivotTable]) => {
45396
+ const pt = pivotTable;
45397
+ const tableNumber = this._extractTableNumber(pivotName);
45398
+ const cacheData = cacheMap.get(pt.cacheId);
45399
+ const completePivotTable = {
45400
+ ...pt,
45401
+ tableNumber,
45402
+ cacheDefinition: cacheData?.definition,
45403
+ cacheRecords: cacheData?.records,
45404
+ cacheFields: cacheData?.definition?.cacheFields || [],
45405
+ rows: pt.rowFields.filter((f) => f >= 0),
45406
+ columns: pt.colFields.filter((f) => f >= 0 && f !== -2),
45407
+ values: pt.dataFields.map((df) => df.fld),
45408
+ metric: this._determineMetric(pt.dataFields),
45409
+ applyWidthHeightFormats: pt.applyWidthHeightFormats || "0"
45410
+ };
45411
+ loadedPivotTables.push(completePivotTable);
45412
+ pivotTablesIndexed[`../pivotTables/${pivotName}.xml`] = completePivotTable;
45413
+ });
45414
+ loadedPivotTables.sort((a, b) => a.tableNumber - b.tableNumber);
45415
+ model.pivotTables = loadedPivotTables;
45416
+ model.pivotTablesIndexed = pivotTablesIndexed;
45417
+ model.loadedPivotTables = loadedPivotTables;
45418
+ }
45419
+ /**
45420
+ * Extract table number from pivot table name (e.g., "pivotTable1" -> 1)
45421
+ */
45422
+ _extractTableNumber(name) {
45423
+ const match = name.match(/pivotTable(\d+)/);
45424
+ return match ? parseInt(match[1], 10) : 1;
45425
+ }
45426
+ /**
45427
+ * Build a mapping from rId to cacheId using pivotCaches from workbook.xml
45428
+ * and workbookRels to determine which definition file corresponds to which cacheId
45429
+ */
45430
+ _buildCacheIdMap(model) {
45431
+ const rIdToCacheId = /* @__PURE__ */ new Map();
45432
+ const pivotCaches = model.pivotCaches || [];
45433
+ for (const cache of pivotCaches) if (cache.cacheId && cache.rId) rIdToCacheId.set(cache.rId, parseInt(cache.cacheId, 10));
45434
+ return rIdToCacheId;
45435
+ }
45436
+ /**
45437
+ * Build a mapping from definition name to cacheId
45438
+ */
45439
+ _buildDefinitionToCacheIdMap(model) {
45440
+ const definitionToCacheId = /* @__PURE__ */ new Map();
45441
+ const rIdToCacheId = this._buildCacheIdMap(model);
45442
+ const workbookRels = model.workbookRels || [];
45443
+ for (const rel of workbookRels) if (rel.Type === XLSX.RelType.PivotCacheDefinition && rel.Target) {
45444
+ const match = rel.Target.match(/pivotCacheDefinition(\d+)\.xml/);
45445
+ if (match) {
45446
+ const defName = `pivotCacheDefinition${match[1]}`;
45447
+ const cacheId = rIdToCacheId.get(rel.Id);
45448
+ if (cacheId !== void 0) definitionToCacheId.set(defName, cacheId);
45449
+ }
45450
+ }
45451
+ return definitionToCacheId;
45452
+ }
45453
+ /**
45454
+ * Determine the aggregation metric from dataFields
45455
+ */
45456
+ _determineMetric(dataFields) {
45457
+ if (dataFields.length > 0 && dataFields[0].subtotal === "count") return "count";
45458
+ return "sum";
44689
45459
  }
44690
45460
  async _processWorksheetEntry(stream, model, sheetNo, options, path) {
44691
45461
  const worksheet = await new WorkSheetXform(options).parseStream(stream);
@@ -44777,6 +45547,26 @@ ${XMLNS_NAMESPACE}.`);
44777
45547
  stream.pipe(streamBuf);
44778
45548
  });
44779
45549
  }
45550
+ async _processPivotTableEntry(stream, model, name) {
45551
+ const pivotTable = await new PivotTableXform().parseStream(stream);
45552
+ if (pivotTable) model.pivotTables[name] = pivotTable;
45553
+ }
45554
+ async _processPivotTableRelsEntry(stream, model, name) {
45555
+ const relationships = await new RelationshipsXform().parseStream(stream);
45556
+ model.pivotTableRels[name] = relationships;
45557
+ }
45558
+ async _processPivotCacheDefinitionEntry(stream, model, name) {
45559
+ const cacheDefinition = await new PivotCacheDefinitionXform().parseStream(stream);
45560
+ if (cacheDefinition) model.pivotCacheDefinitions[name] = cacheDefinition;
45561
+ }
45562
+ async _processPivotCacheDefinitionRelsEntry(stream, model, name) {
45563
+ const relationships = await new RelationshipsXform().parseStream(stream);
45564
+ model.pivotCacheDefinitionRels[name] = relationships;
45565
+ }
45566
+ async _processPivotCacheRecordsEntry(stream, model, name) {
45567
+ const cacheRecords = await new PivotCacheRecordsXform().parseStream(stream);
45568
+ if (cacheRecords) model.pivotCacheRecords[name] = cacheRecords;
45569
+ }
44780
45570
  async read(stream, options) {
44781
45571
  const allFiles = {};
44782
45572
  await new Promise((resolve, reject) => {
@@ -44847,8 +45637,8 @@ ${XMLNS_NAMESPACE}.`);
44847
45637
  }
44848
45638
  async load(data, options) {
44849
45639
  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");
45640
+ 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) ?");
45641
+ if (options && options.base64) buffer = import_buffer$3.Buffer.from(data.toString(), "base64");
44852
45642
  else buffer = data;
44853
45643
  const stream = new import_stream_browserify.PassThrough();
44854
45644
  stream.end(buffer);
@@ -44866,7 +45656,12 @@ ${XMLNS_NAMESPACE}.`);
44866
45656
  drawingRels: {},
44867
45657
  comments: {},
44868
45658
  tables: {},
44869
- vmlDrawings: {}
45659
+ vmlDrawings: {},
45660
+ pivotTables: {},
45661
+ pivotTableRels: {},
45662
+ pivotCacheDefinitions: {},
45663
+ pivotCacheDefinitionRels: {},
45664
+ pivotCacheRecords: {}
44870
45665
  };
44871
45666
  const entries = Object.keys(zipData).map((name) => ({
44872
45667
  name,
@@ -44879,13 +45674,13 @@ ${XMLNS_NAMESPACE}.`);
44879
45674
  let stream;
44880
45675
  if (entryName.match(/xl\/media\//) || entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/)) {
44881
45676
  stream = new import_stream_browserify.PassThrough();
44882
- stream.end(import_buffer$2.Buffer.from(entry.data));
45677
+ stream.end(import_buffer$3.Buffer.from(entry.data));
44883
45678
  } else {
44884
45679
  stream = new import_stream_browserify.PassThrough({
44885
45680
  readableObjectMode: true,
44886
45681
  writableObjectMode: true
44887
45682
  });
44888
- const content = bufferToString(import_buffer$2.Buffer.from(entry.data));
45683
+ const content = bufferToString(import_buffer$3.Buffer.from(entry.data));
44889
45684
  stream.end(content);
44890
45685
  }
44891
45686
  let match;
@@ -44904,6 +45699,7 @@ ${XMLNS_NAMESPACE}.`);
44904
45699
  model.views = workbook.views;
44905
45700
  model.properties = workbook.properties;
44906
45701
  model.calcProperties = workbook.calcProperties;
45702
+ model.pivotCaches = workbook.pivotCaches;
44907
45703
  break;
44908
45704
  }
44909
45705
  case "xl/sharedStrings.xml":
@@ -44970,6 +45766,31 @@ ${XMLNS_NAMESPACE}.`);
44970
45766
  await this._processThemeEntry(stream, model, match[1]);
44971
45767
  break;
44972
45768
  }
45769
+ match = entryName.match(/xl\/pivotTables\/(pivotTable\d+)[.]xml/);
45770
+ if (match) {
45771
+ await this._processPivotTableEntry(stream, model, match[1]);
45772
+ break;
45773
+ }
45774
+ match = entryName.match(/xl\/pivotTables\/_rels\/(pivotTable\d+)[.]xml[.]rels/);
45775
+ if (match) {
45776
+ await this._processPivotTableRelsEntry(stream, model, match[1]);
45777
+ break;
45778
+ }
45779
+ match = entryName.match(/xl\/pivotCache\/(pivotCacheDefinition\d+)[.]xml/);
45780
+ if (match) {
45781
+ await this._processPivotCacheDefinitionEntry(stream, model, match[1]);
45782
+ break;
45783
+ }
45784
+ match = entryName.match(/xl\/pivotCache\/_rels\/(pivotCacheDefinition\d+)[.]xml[.]rels/);
45785
+ if (match) {
45786
+ await this._processPivotCacheDefinitionRelsEntry(stream, model, match[1]);
45787
+ break;
45788
+ }
45789
+ match = entryName.match(/xl\/pivotCache\/(pivotCacheRecords\d+)[.]xml/);
45790
+ if (match) {
45791
+ await this._processPivotCacheRecordsEntry(stream, model, match[1]);
45792
+ break;
45793
+ }
44973
45794
  }
44974
45795
  }
44975
45796
  this.reconcile(model, options);
@@ -45032,21 +45853,21 @@ ${XMLNS_NAMESPACE}.`);
45032
45853
  Type: XLSX.RelType.SharedStrings,
45033
45854
  Target: "sharedStrings.xml"
45034
45855
  });
45035
- if ((model.pivotTables || []).length) {
45036
- const pivotTable = model.pivotTables[0];
45856
+ (model.pivotTables || []).forEach((pivotTable) => {
45037
45857
  pivotTable.rId = `rId${count++}`;
45038
45858
  relationships.push({
45039
45859
  Id: pivotTable.rId,
45040
45860
  Type: XLSX.RelType.PivotCacheDefinition,
45041
- Target: "pivotCache/pivotCacheDefinition1.xml"
45861
+ Target: `pivotCache/pivotCacheDefinition${pivotTable.tableNumber}.xml`
45042
45862
  });
45043
- }
45044
- model.worksheets.forEach((worksheet) => {
45863
+ });
45864
+ model.worksheets.forEach((worksheet, index) => {
45045
45865
  worksheet.rId = `rId${count++}`;
45866
+ worksheet.fileIndex = index + 1;
45046
45867
  relationships.push({
45047
45868
  Id: worksheet.rId,
45048
45869
  Type: XLSX.RelType.Worksheet,
45049
- Target: `worksheets/sheet${worksheet.id}.xml`
45870
+ Target: `worksheets/sheet${worksheet.fileIndex}.xml`
45050
45871
  });
45051
45872
  });
45052
45873
  const xml = new RelationshipsXform().toXml(relationships);
@@ -45068,22 +45889,23 @@ ${XMLNS_NAMESPACE}.`);
45068
45889
  const relationshipsXform = new RelationshipsXform();
45069
45890
  const commentsXform = new CommentsXform();
45070
45891
  const vmlNotesXform = new VmlNotesXform();
45071
- model.worksheets.forEach((worksheet) => {
45892
+ model.worksheets.forEach((worksheet, index) => {
45893
+ const fileIndex = worksheet.fileIndex || index + 1;
45072
45894
  let xmlStream = new XmlStream();
45073
45895
  worksheetXform.render(xmlStream, worksheet);
45074
- zip.append(xmlStream.xml, { name: `xl/worksheets/sheet${worksheet.id}.xml` });
45896
+ zip.append(xmlStream.xml, { name: `xl/worksheets/sheet${fileIndex}.xml` });
45075
45897
  if (worksheet.rels && worksheet.rels.length) {
45076
45898
  xmlStream = new XmlStream();
45077
45899
  relationshipsXform.render(xmlStream, worksheet.rels);
45078
- zip.append(xmlStream.xml, { name: `xl/worksheets/_rels/sheet${worksheet.id}.xml.rels` });
45900
+ zip.append(xmlStream.xml, { name: `xl/worksheets/_rels/sheet${fileIndex}.xml.rels` });
45079
45901
  }
45080
45902
  if (worksheet.comments.length > 0) {
45081
45903
  xmlStream = new XmlStream();
45082
45904
  commentsXform.render(xmlStream, worksheet);
45083
- zip.append(xmlStream.xml, { name: `xl/comments${worksheet.id}.xml` });
45905
+ zip.append(xmlStream.xml, { name: `xl/comments${fileIndex}.xml` });
45084
45906
  xmlStream = new XmlStream();
45085
45907
  vmlNotesXform.render(xmlStream, worksheet);
45086
- zip.append(xmlStream.xml, { name: `xl/drawings/vmlDrawing${worksheet.id}.vml` });
45908
+ zip.append(xmlStream.xml, { name: `xl/drawings/vmlDrawing${fileIndex}.vml` });
45087
45909
  }
45088
45910
  });
45089
45911
  }
@@ -45135,29 +45957,42 @@ ${XMLNS_NAMESPACE}.`);
45135
45957
  }
45136
45958
  addPivotTables(zip, model) {
45137
45959
  if (!model.pivotTables.length) return;
45138
- const pivotTable = model.pivotTables[0];
45139
45960
  const pivotCacheRecordsXform = new PivotCacheRecordsXform();
45140
45961
  const pivotCacheDefinitionXform = new PivotCacheDefinitionXform();
45141
45962
  const pivotTableXform = new PivotTableXform();
45142
45963
  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" });
45964
+ model.pivotTables.forEach((pivotTable) => {
45965
+ const n = pivotTable.tableNumber;
45966
+ if (pivotTable.isLoaded) {
45967
+ if (pivotTable.cacheDefinition) {
45968
+ const xml$1 = pivotCacheDefinitionXform.toXml(pivotTable.cacheDefinition);
45969
+ zip.append(xml$1, { name: `xl/pivotCache/pivotCacheDefinition${n}.xml` });
45970
+ }
45971
+ if (pivotTable.cacheRecords) {
45972
+ const xml$1 = pivotCacheRecordsXform.toXml(pivotTable.cacheRecords);
45973
+ zip.append(xml$1, { name: `xl/pivotCache/pivotCacheRecords${n}.xml` });
45974
+ }
45975
+ } else {
45976
+ let xml$1 = pivotCacheRecordsXform.toXml(pivotTable);
45977
+ zip.append(xml$1, { name: `xl/pivotCache/pivotCacheRecords${n}.xml` });
45978
+ xml$1 = pivotCacheDefinitionXform.toXml(pivotTable);
45979
+ zip.append(xml$1, { name: `xl/pivotCache/pivotCacheDefinition${n}.xml` });
45980
+ }
45981
+ let xml = relsXform.toXml([{
45982
+ Id: "rId1",
45983
+ Type: XLSX.RelType.PivotCacheRecords,
45984
+ Target: `pivotCacheRecords${n}.xml`
45985
+ }]);
45986
+ zip.append(xml, { name: `xl/pivotCache/_rels/pivotCacheDefinition${n}.xml.rels` });
45987
+ xml = pivotTableXform.toXml(pivotTable);
45988
+ zip.append(xml, { name: `xl/pivotTables/pivotTable${n}.xml` });
45989
+ xml = relsXform.toXml([{
45990
+ Id: "rId1",
45991
+ Type: XLSX.RelType.PivotCacheDefinition,
45992
+ Target: `../pivotCache/pivotCacheDefinition${n}.xml`
45993
+ }]);
45994
+ zip.append(xml, { name: `xl/pivotTables/_rels/pivotTable${n}.xml.rels` });
45995
+ });
45161
45996
  }
45162
45997
  _finalize(zip) {
45163
45998
  return new Promise((resolve, reject) => {
@@ -50673,7 +51508,7 @@ ${XMLNS_NAMESPACE}.`);
50673
51508
  this.views = value.views;
50674
51509
  this._themes = value.themes;
50675
51510
  this.media = value.media || [];
50676
- this.pivotTables = value.pivotTables || [];
51511
+ this.pivotTables = value.pivotTables || value.loadedPivotTables || [];
50677
51512
  }
50678
51513
  };
50679
51514