ooxml-core 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/PptxHandler-5UURGJEV.mjs +2 -0
  2. package/dist/{PptxHandler-EX4WBIQQ.mjs → PptxHandler-ADEFY476.mjs} +2 -2
  3. package/dist/PptxHandler-U5XB2HUE.cjs +11 -0
  4. package/dist/automation/index.cjs +744 -192
  5. package/dist/automation/index.mjs +744 -192
  6. package/dist/{chunk-SWF7KVL5.cjs → chunk-3N6XMMTT.cjs} +1365 -1062
  7. package/dist/{chunk-FIELY5PI.mjs → chunk-5NVJN4E6.mjs} +30 -2
  8. package/dist/{chunk-IGOA57LE.mjs → chunk-A6P7G3UK.mjs} +1 -1
  9. package/dist/{chunk-CPKNMQLX.cjs → chunk-AWIDASUW.cjs} +25 -2
  10. package/dist/{chunk-SVQZXP3F.mjs → chunk-CBNKBVX5.mjs} +25 -2
  11. package/dist/{chunk-OXHMZS7B.mjs → chunk-CCHYFCPD.mjs} +649 -172
  12. package/dist/{chunk-OB277ZGE.mjs → chunk-R6KSBNKX.mjs} +27 -1
  13. package/dist/{chunk-AT66SA5M.cjs → chunk-S6DOCMQC.cjs} +28 -0
  14. package/dist/{chunk-WSO4T2LJ.mjs → chunk-WUE5ZHU3.mjs} +26 -3
  15. package/dist/{chunk-LCS3J3QI.mjs → chunk-ZE53K7DH.mjs} +474 -171
  16. package/dist/{chunk-M76PHYRR.mjs → chunk-ZOUGMAZG.mjs} +1 -1
  17. package/dist/docx/layout/adapt-table.d.ts +2 -2
  18. package/dist/docx/layout/adapt-table.d.ts.map +1 -1
  19. package/dist/docx/layout/flow-table.d.ts.map +1 -1
  20. package/dist/docx/layout/index.cjs +477 -75
  21. package/dist/docx/layout/index.mjs +477 -76
  22. package/dist/docx/layout/nested-frame-profile.d.ts +9 -0
  23. package/dist/docx/layout/nested-frame-profile.d.ts.map +1 -0
  24. package/dist/docx/layout/page-cursor.d.ts +2 -0
  25. package/dist/docx/layout/page-cursor.d.ts.map +1 -1
  26. package/dist/docx/layout/result.d.ts +13 -0
  27. package/dist/docx/layout/result.d.ts.map +1 -1
  28. package/dist/docx/layout/table-border-layout.d.ts +16 -0
  29. package/dist/docx/layout/table-border-layout.d.ts.map +1 -0
  30. package/dist/docx/layout/table-cell-layout.d.ts +2 -1
  31. package/dist/docx/layout/table-cell-layout.d.ts.map +1 -1
  32. package/dist/docx/layout/table-content.d.ts +4 -0
  33. package/dist/docx/layout/table-content.d.ts.map +1 -0
  34. package/dist/docx/layout/table-footnotes.d.ts +5 -0
  35. package/dist/docx/layout/table-footnotes.d.ts.map +1 -1
  36. package/dist/docx/layout/table-frames.d.ts +4 -0
  37. package/dist/docx/layout/table-frames.d.ts.map +1 -0
  38. package/dist/docx/layout/table-layout.d.ts +8 -3
  39. package/dist/docx/layout/table-layout.d.ts.map +1 -1
  40. package/dist/docx/layout/table-note-completion.d.ts +5 -0
  41. package/dist/docx/layout/table-note-completion.d.ts.map +1 -0
  42. package/dist/docx/layout/table-note-stories.d.ts +6 -0
  43. package/dist/docx/layout/table-note-stories.d.ts.map +1 -0
  44. package/dist/pptx/automation/index.cjs +535 -182
  45. package/dist/pptx/automation/index.d.ts +4 -4
  46. package/dist/pptx/automation/index.mjs +5 -5
  47. package/dist/pptx/chunks/{index-BZh-IMkN.d.ts → index-Cuxtr76Y.d.ts} +17 -3
  48. package/dist/pptx/chunks/index-Cuxtr76Y.d.ts.map +1 -0
  49. package/dist/pptx/chunks/{index-B4cnSPNz.d.ts → index-DUCGeZh7.d.ts} +65 -5
  50. package/dist/pptx/chunks/index-DUCGeZh7.d.ts.map +1 -0
  51. package/dist/pptx/chunks/{smart-art-Q2kZQtHh.d.ts → smart-art-D-sXa_Nb.d.ts} +11 -1
  52. package/dist/pptx/chunks/smart-art-D-sXa_Nb.d.ts.map +1 -0
  53. package/dist/pptx/chunks/{text-operations-BLodkuXE.d.ts → text-operations-BqHmLaLA.d.ts} +26 -2
  54. package/dist/pptx/chunks/text-operations-BqHmLaLA.d.ts.map +1 -0
  55. package/dist/pptx/cli/index.cjs +535 -182
  56. package/dist/pptx/cli/index.d.ts +1 -1
  57. package/dist/pptx/cli/index.mjs +4 -4
  58. package/dist/pptx/converter/index.cjs +1 -0
  59. package/dist/pptx/converter/index.d.ts +1 -1
  60. package/dist/pptx/converter/index.mjs +2 -2
  61. package/dist/pptx/editor/render/collaboration-live-patch-target.cjs +2 -2
  62. package/dist/pptx/editor/render/collaboration-live-patch-target.mjs +1 -1
  63. package/dist/pptx/editor/render/find-replace.cjs +18 -18
  64. package/dist/pptx/editor/render/find-replace.d.ts +2 -2
  65. package/dist/pptx/editor/render/find-replace.mjs +2 -2
  66. package/dist/pptx/editor/render/remap-text.cjs +2 -2
  67. package/dist/pptx/editor/render/remap-text.d.ts.map +1 -1
  68. package/dist/pptx/editor/render/remap-text.mjs +1 -1
  69. package/dist/pptx/editor/render/slide-operations.cjs +8 -8
  70. package/dist/pptx/editor/render/slide-operations.mjs +2 -2
  71. package/dist/pptx/index.cjs +762 -182
  72. package/dist/pptx/index.d.ts +5 -5
  73. package/dist/pptx/index.mjs +5 -5
  74. package/dist/pptx/smartart-layouts/index.d.ts +1 -1
  75. package/dist/teams/index.cjs +486 -114
  76. package/dist/teams/index.mjs +486 -114
  77. package/dist/visio/date-cache.d.ts +3 -0
  78. package/dist/visio/date-cache.d.ts.map +1 -0
  79. package/dist/visio/edit-text-field.d.ts.map +1 -1
  80. package/dist/visio/index.cjs +131 -22
  81. package/dist/visio/index.mjs +131 -22
  82. package/dist/visio/shape-metadata.d.ts.map +1 -1
  83. package/dist/visio/text-field-display.d.ts.map +1 -1
  84. package/dist/visio/text-field-fraction.d.ts +3 -0
  85. package/dist/visio/text-field-fraction.d.ts.map +1 -0
  86. package/dist/visio/text-field-numeric.d.ts +1 -1
  87. package/dist/visio/text-field-numeric.d.ts.map +1 -1
  88. package/dist/visio/text-field-system-date.d.ts +4 -0
  89. package/dist/visio/text-field-system-date.d.ts.map +1 -0
  90. package/dist/visio/text-fields.d.ts +1 -0
  91. package/dist/visio/text-fields.d.ts.map +1 -1
  92. package/dist/visio/ui/index.cjs +132 -22
  93. package/dist/visio/ui/index.mjs +132 -22
  94. package/dist/visio/ui/text-field-catalog.d.ts.map +1 -1
  95. package/dist/xlsx/edit/pivots.d.ts.map +1 -1
  96. package/dist/xlsx/index.cjs +614 -170
  97. package/dist/xlsx/index.mjs +614 -170
  98. package/dist/xlsx/load/index.cjs +575 -163
  99. package/dist/xlsx/load/index.mjs +575 -163
  100. package/dist/xlsx/model-pivots.d.ts +23 -2
  101. package/dist/xlsx/model-pivots.d.ts.map +1 -1
  102. package/dist/xlsx/pivot/admission.d.ts.map +1 -1
  103. package/dist/xlsx/pivot/aggregate.d.ts +3 -1
  104. package/dist/xlsx/pivot/aggregate.d.ts.map +1 -1
  105. package/dist/xlsx/pivot/data.d.ts +1 -1
  106. package/dist/xlsx/pivot/data.d.ts.map +1 -1
  107. package/dist/xlsx/pivot/hierarchy-first.d.ts +21 -0
  108. package/dist/xlsx/pivot/hierarchy-first.d.ts.map +1 -0
  109. package/dist/xlsx/pivot/hierarchy.d.ts +2 -4
  110. package/dist/xlsx/pivot/hierarchy.d.ts.map +1 -1
  111. package/dist/xlsx/pivot/measures.d.ts +13 -0
  112. package/dist/xlsx/pivot/measures.d.ts.map +1 -0
  113. package/dist/xlsx/pivot/read.d.ts.map +1 -1
  114. package/dist/xlsx/pivot/table-xml.d.ts.map +1 -1
  115. package/dist/xlsx/pivot/values-axis.d.ts +9 -0
  116. package/dist/xlsx/pivot/values-axis.d.ts.map +1 -0
  117. package/dist/xlsx/ui/commands/i18n/pivots.d.ts.map +1 -1
  118. package/dist/xlsx/ui/index.cjs +547 -127
  119. package/dist/xlsx/ui/index.mjs +547 -127
  120. package/package.json +1 -1
  121. package/dist/PptxHandler-AT7FVG5Q.mjs +0 -2
  122. package/dist/PptxHandler-VFSCECPL.cjs +0 -11
  123. package/dist/pptx/chunks/index-B4cnSPNz.d.ts.map +0 -1
  124. package/dist/pptx/chunks/index-BZh-IMkN.d.ts.map +0 -1
  125. package/dist/pptx/chunks/smart-art-Q2kZQtHh.d.ts.map +0 -1
  126. package/dist/pptx/chunks/text-operations-BLodkuXE.d.ts.map +0 -1
@@ -6451,25 +6451,198 @@ function validatePivotFields(pivot) {
6451
6451
  ...pivot.columnField ? [pivot.columnField] : [],
6452
6452
  pivot.valueField
6453
6453
  ];
6454
+ const extras = pivot.additionalValues ?? [];
6455
+ if (pivot.valuesAxis !== void 0 && !["columns", "rows"].includes(pivot.valuesAxis))
6456
+ throw new Error("Choose a valid Values axis.");
6457
+ if (pivot.valuesPosition !== void 0 && !["last", "between", "first"].includes(pivot.valuesPosition))
6458
+ throw new Error("Choose a valid Values position.");
6459
+ if ((pivot.valuesPosition === "between" || pivot.valuesPosition === "first") && (pivot.valuesAxis !== "rows" || !pivot.secondRowField))
6460
+ throw new Error("Values before or between fields require two row fields and Values on rows.");
6461
+ if (pivot.valuesAxis === "rows" && (!Array.isArray(extras) || !extras.length))
6462
+ throw new Error("Values on rows require multiple measures.");
6463
+ if (extras.length > 0 && pivot.sourceXml && parseXml(pivot.sourceXml).documentElement.getAttribute("dataCaption") !== "Values")
6464
+ throw new Error("This PivotTable uses unsupported Values header captions.");
6465
+ if (!Array.isArray(extras) || extras.length > 15 || extras.some(
6466
+ (measure) => !measure || !pivot.fields.includes(measure.field) || !PIVOT_AGGREGATES.includes(measure.aggregate) || typeof measure.caption !== "string" || !measure.caption.trim() || measure.caption.length > 255 || pivot.fields.some((field) => field.toLowerCase() === measure.caption.toLowerCase())
6467
+ ) || new Set(
6468
+ [pivot.valueCaption, ...extras.map((measure) => measure.caption)].map(
6469
+ (caption) => caption?.toLowerCase()
6470
+ )
6471
+ ).size !== extras.length + 1)
6472
+ throw new Error("Choose PivotTable value fields with valid aggregates and unique captions.");
6454
6473
  if (pivot.layout !== void 0 && !["tabular", "compact", "outline"].includes(pivot.layout) || pivot.subtotalPosition !== void 0 && !["top", "bottom"].includes(pivot.subtotalPosition) || !PIVOT_AGGREGATES.includes(pivot.aggregate) || used.some((field) => !pivot.fields.includes(field)) || new Set([pivot.rowField, pivot.secondRowField, pivot.columnField].filter(Boolean)).size !== [pivot.rowField, pivot.secondRowField, pivot.columnField].filter(Boolean).length || pivot.subtotals !== void 0 && typeof pivot.subtotals !== "boolean" || pivot.repeatLabels !== void 0 && typeof pivot.repeatLabels !== "boolean")
6455
6474
  throw new Error("Choose valid PivotTable fields; row and column fields must differ.");
6456
6475
  }
6457
6476
 
6477
+ // xlsx/pivot/measures.ts
6478
+ var pivotMeasures = (pivot) => [
6479
+ { field: pivot.valueField, aggregate: pivot.aggregate, caption: pivot.valueCaption },
6480
+ ...pivot.additionalValues ?? []
6481
+ ];
6482
+ function aggregate(records, field, type) {
6483
+ if (!records.length) return null;
6484
+ const values2 = records.map((record) => record[field] ?? null);
6485
+ if (type === "count") return values2.filter((value2) => value2 !== null && value2 !== "").length;
6486
+ const error = values2.find(isCellError);
6487
+ if (error) return error;
6488
+ const numbers3 = values2.filter((value2) => typeof value2 === "number");
6489
+ if (!numbers3.length) return type === "average" ? { error: "#DIV/0!" } : 0;
6490
+ if (type === "min") return numbers3.reduce((a2, b) => Math.min(a2, b));
6491
+ if (type === "max") return numbers3.reduce((a2, b) => Math.max(a2, b));
6492
+ const sum2 = numbers3.reduce((total2, value2) => total2 + value2, 0);
6493
+ return type === "average" ? sum2 / numbers3.length : sum2;
6494
+ }
6495
+ var pivotMeasureNumber = (pivot, records, measure) => aggregate(records, pivot.fields.indexOf(measure.field), measure.aggregate);
6496
+ var pivotNumbers = (pivot, records) => pivotMeasures(pivot).map((measure) => pivotMeasureNumber(pivot, records, measure));
6497
+ function pivotHeaderDimensions(pivot, columnItems, rowLabels) {
6498
+ const measures = 1 + (pivot.additionalValues?.length ?? 0);
6499
+ if (pivot.valuesAxis === "rows")
6500
+ return {
6501
+ rows: pivot.columnField ? 2 : 1,
6502
+ width: rowLabels + (pivot.columnField ? columnItems + 1 : 1)
6503
+ };
6504
+ return {
6505
+ rows: pivot.columnField ? measures > 1 ? 3 : 2 : 1,
6506
+ width: rowLabels + (pivot.columnField ? measures === 1 ? Math.max(1, columnItems) + 1 : (columnItems + 1) * measures : measures)
6507
+ };
6508
+ }
6509
+ function pivotHeaders(pivot, columns, labels, label3) {
6510
+ const measures = pivotMeasures(pivot);
6511
+ if (pivot.valuesAxis === "rows") {
6512
+ const rowLabels = pivot.layout === "compact" ? ["Row Labels"] : pivot.valuesPosition === "first" ? ["Values", ...labels] : pivot.valuesPosition === "between" ? [labels[0], "Values", labels[1]] : [...labels, "Values"];
6513
+ return pivot.columnField ? [
6514
+ [
6515
+ ...rowLabels.map(() => null),
6516
+ pivot.layout === "compact" ? "Column Labels" : pivot.columnField,
6517
+ ...columns.map(() => null)
6518
+ ],
6519
+ [...rowLabels, ...columns.map(label3), "Grand Total"]
6520
+ ] : [[...rowLabels, null]];
6521
+ }
6522
+ if (!pivot.columnField) return [[...labels, ...measures.map((measure) => measure.caption)]];
6523
+ if (measures.length === 1)
6524
+ return [
6525
+ [
6526
+ pivot.valueCaption,
6527
+ ...labels.slice(1).map(() => null),
6528
+ pivot.layout === "compact" ? "Column Labels" : pivot.columnField,
6529
+ ...columns.slice(1).map(() => null),
6530
+ null
6531
+ ],
6532
+ [...labels, ...columns.map(label3), "Grand Total"]
6533
+ ];
6534
+ const { width } = pivotHeaderDimensions(pivot, columns.length, labels.length);
6535
+ const first2 = Array(width).fill(null);
6536
+ first2[labels.length] = pivot.layout === "compact" ? "Column Labels" : pivot.columnField;
6537
+ if (pivot.layout !== "compact") first2[labels.length + 1] = "Values";
6538
+ return [
6539
+ first2,
6540
+ [
6541
+ ...labels.map(() => null),
6542
+ ...columns.flatMap((column) => [label3(column), ...measures.slice(1).map(() => null)]),
6543
+ ...measures.map((measure) => `Total ${measure.caption}`)
6544
+ ],
6545
+ [
6546
+ ...labels,
6547
+ ...columns.flatMap(() => measures.map((measure) => measure.caption)),
6548
+ ...measures.map(() => null)
6549
+ ]
6550
+ ];
6551
+ }
6552
+
6553
+ // xlsx/pivot/hierarchy-first.ts
6554
+ function appendFirstPivotValues(pivot, context) {
6555
+ const {
6556
+ rowItems,
6557
+ secondRowItems,
6558
+ columnItems,
6559
+ children: children2,
6560
+ innerIndices,
6561
+ groups,
6562
+ details,
6563
+ buckets,
6564
+ width,
6565
+ rowLabels,
6566
+ top,
6567
+ bottom,
6568
+ append
6569
+ } = context;
6570
+ const compact = pivot.layout === "compact";
6571
+ const tabular = !pivot.layout || pivot.layout === "tabular";
6572
+ const blank = () => Array(width - rowLabels).fill(null);
6573
+ pivotMeasures(pivot).forEach((measure, m) => {
6574
+ const numbers3 = (keys, records) => [
6575
+ ...columnItems.map(
6576
+ (column) => pivotMeasureNumber(
6577
+ pivot,
6578
+ buckets.get(JSON.stringify([...keys, pivotValueKey(column)])) ?? [],
6579
+ measure
6580
+ )
6581
+ ),
6582
+ pivotMeasureNumber(pivot, records, measure)
6583
+ ];
6584
+ if (!tabular)
6585
+ append([measure.caption, ...Array(rowLabels - 1).fill(null)], blank(), {
6586
+ indices: [m],
6587
+ measure: m
6588
+ });
6589
+ let first2 = true;
6590
+ rowItems.forEach((outer, outerIndex) => {
6591
+ const key = pivotValueKey(outer);
6592
+ const group = groups.get(key) ?? [];
6593
+ if (!tabular)
6594
+ append(
6595
+ compact ? [pivotItemLabel(outer)] : [null, pivotItemLabel(outer), null],
6596
+ top ? numbers3([key], group) : blank(),
6597
+ { indices: [m, outerIndex], measure: m },
6598
+ compact ? 1 : 0
6599
+ );
6600
+ const innerKeys = [...children2.get(key)].sort(
6601
+ (a2, b) => innerIndices.get(a2) - innerIndices.get(b)
6602
+ );
6603
+ innerKeys.forEach((innerKey, child4) => {
6604
+ const innerIndex = innerIndices.get(innerKey);
6605
+ append(
6606
+ compact ? [pivotItemLabel(secondRowItems[innerIndex])] : [
6607
+ tabular && first2 ? measure.caption : null,
6608
+ pivot.repeatLabels || tabular && child4 === 0 ? pivotItemLabel(outer) : null,
6609
+ pivotItemLabel(secondRowItems[innerIndex])
6610
+ ],
6611
+ numbers3([key, innerKey], details.get(JSON.stringify([key, innerKey]))),
6612
+ { indices: [m, outerIndex, innerIndex], measure: m },
6613
+ compact ? 2 : 0
6614
+ );
6615
+ first2 = false;
6616
+ });
6617
+ if (bottom)
6618
+ append(
6619
+ compact ? [`${String(pivotItemLabel(outer))} Total`] : [null, `${String(pivotItemLabel(outer))} Total`, null],
6620
+ numbers3([key], group),
6621
+ { indices: [m, outerIndex], measure: m, type: "default" },
6622
+ compact ? 1 : 0
6623
+ );
6624
+ });
6625
+ });
6626
+ }
6627
+
6458
6628
  // xlsx/pivot/hierarchy.ts
6459
6629
  var label = pivotItemLabel;
6460
- function hierarchicalPivotGrid(pivot, aggregate3) {
6630
+ function hierarchicalPivotGrid(pivot) {
6461
6631
  const rowItems = pivotItems(pivot, pivot.rowField);
6462
6632
  const secondRowItems = pivotItems(pivot, pivot.secondRowField);
6463
6633
  const columnItems = pivot.columnField ? pivotItems(pivot, pivot.columnField) : [];
6464
6634
  const outerField = pivot.fields.indexOf(pivot.rowField);
6465
6635
  const innerField = pivot.fields.indexOf(pivot.secondRowField);
6466
6636
  const columnField = pivot.columnField ? pivot.fields.indexOf(pivot.columnField) : -1;
6467
- const valueField = pivot.fields.indexOf(pivot.valueField);
6468
6637
  const layout3 = pivot.layout ?? "tabular";
6469
6638
  const compact = layout3 === "compact";
6470
- const top = layout3 !== "tabular" && pivot.subtotals !== false && (pivot.subtotalPosition ?? "top") === "top";
6639
+ const rowsAxis = pivot.valuesAxis === "rows";
6640
+ const firstValues = rowsAxis && pivot.valuesPosition === "first";
6641
+ const between = rowsAxis && pivot.valuesPosition === "between";
6642
+ const measures = pivotMeasures(pivot);
6643
+ const top = (!rowsAxis || firstValues) && layout3 !== "tabular" && pivot.subtotals !== false && (pivot.subtotalPosition ?? "top") === "top";
6471
6644
  const bottom = pivot.subtotals !== false && !top;
6472
- const rowLabelColumns = compact ? 1 : 2;
6645
+ const rowLabelColumns = compact ? 1 : rowsAxis ? 3 : 2;
6473
6646
  const groups = /* @__PURE__ */ new Map();
6474
6647
  const details = /* @__PURE__ */ new Map();
6475
6648
  const children2 = /* @__PURE__ */ new Map();
@@ -6493,20 +6666,12 @@ function hierarchicalPivotGrid(pivot, aggregate3) {
6493
6666
  collect(buckets, JSON.stringify([...key, column]), record);
6494
6667
  }
6495
6668
  }
6496
- const rows = details.size + rowItems.length * (Number(layout3 !== "tabular") + Number(bottom)) + 3;
6497
- if (rows * (columnItems.length + 3) > 1e6)
6498
- throw new Error("The PivotTable result is too large.");
6669
+ const dimensions = pivotHeaderDimensions(pivot, columnItems.length, rowLabelColumns);
6670
+ const rows = (details.size + rowItems.length * Number(bottom) + 1) * (rowsAxis ? measures.length : 1) + rowItems.length * Number(layout3 !== "tabular") * (firstValues ? measures.length : 1) + (firstValues ? measures.length : between ? rowItems.length * measures.length : details.size) * Number(rowsAxis && layout3 !== "tabular") + dimensions.rows;
6671
+ if (rows * dimensions.width > 1e6) throw new Error("The PivotTable result is too large.");
6499
6672
  const labels = compact ? ["Row Labels"] : [pivot.rowField, pivot.secondRowField];
6500
- const values2 = pivot.columnField ? [
6501
- [
6502
- pivot.valueCaption,
6503
- ...compact ? [] : [null],
6504
- compact ? "Column Labels" : pivot.columnField,
6505
- ...columnItems.slice(1).map(() => null),
6506
- null
6507
- ],
6508
- [...labels, ...columnItems.map(label), "Grand Total"]
6509
- ] : [[...labels, pivot.valueCaption]];
6673
+ const values2 = pivotHeaders(pivot, columnItems, labels, label);
6674
+ const firstDataRow = values2.length;
6510
6675
  const indents = values2.map(() => 0);
6511
6676
  const rowEntries = [];
6512
6677
  const append = (labels2, numbers4, entry3, indent = 0) => {
@@ -6514,91 +6679,184 @@ function hierarchicalPivotGrid(pivot, aggregate3) {
6514
6679
  rowEntries.push(entry3);
6515
6680
  indents.push(indent);
6516
6681
  };
6517
- const numbers3 = (keys, records) => [
6682
+ const bands = (keys, records) => [
6518
6683
  ...columnItems.map(
6519
- (column) => aggregate3(
6520
- buckets.get(JSON.stringify([...keys, pivotValueKey(column)])) ?? [],
6521
- valueField,
6522
- pivot.aggregate
6523
- )
6684
+ (column) => pivotNumbers(pivot, buckets.get(JSON.stringify([...keys, pivotValueKey(column)])) ?? [])
6524
6685
  ),
6525
- aggregate3(records, valueField, pivot.aggregate)
6686
+ pivotNumbers(pivot, records)
6526
6687
  ];
6527
- rowItems.forEach((outer, outerIndex) => {
6528
- const key = pivotValueKey(outer);
6529
- if (layout3 !== "tabular")
6530
- append(
6531
- [label(outer), ...compact ? [] : [null]],
6532
- top ? numbers3([key], groups.get(key) ?? []) : Array(columnItems.length + 1).fill(null),
6533
- { indices: [outerIndex] }
6534
- );
6535
- let first2 = true;
6536
- [...children2.get(key)].sort((a2, b) => innerIndices.get(a2) - innerIndices.get(b)).forEach((innerKey) => {
6537
- const innerIndex = innerIndices.get(innerKey);
6538
- const inner = secondRowItems[innerIndex];
6539
- const keys = [key, innerKey];
6540
- const records = details.get(JSON.stringify(keys));
6541
- if (!records) return;
6542
- append(
6543
- compact ? [label(inner)] : [
6544
- pivot.repeatLabels || layout3 === "tabular" && first2 ? label(outer) : null,
6545
- label(inner)
6688
+ const numbers3 = (keys, records) => bands(keys, records).flat();
6689
+ const appendMeasures = (labels2, keys, records, indices, type) => {
6690
+ const values3 = bands(keys, records);
6691
+ measures.forEach(
6692
+ (measure, m) => append(
6693
+ type ? [
6694
+ `${type === "grand" ? "Total" : String(labels2[0])} ${measure.caption}`,
6695
+ ...Array(rowLabelColumns - 1).fill(null)
6696
+ ] : compact ? [measure.caption] : [
6697
+ ...labels2.map(
6698
+ (label3) => layout3 === "tabular" && m === 0 || pivot.repeatLabels ? label3 : null
6699
+ ),
6700
+ measure.caption
6546
6701
  ],
6547
- numbers3(keys, records),
6548
- { indices: [outerIndex, innerIndex] },
6549
- compact ? 1 : 0
6550
- );
6551
- first2 = false;
6702
+ values3.map((band) => band[m] ?? null),
6703
+ { indices: type ? indices : [...indices, m], measure: m, ...type ? { type } : {} },
6704
+ compact && !type ? 2 : 0
6705
+ )
6706
+ );
6707
+ };
6708
+ if (firstValues)
6709
+ appendFirstPivotValues(pivot, {
6710
+ rowItems,
6711
+ secondRowItems,
6712
+ columnItems,
6713
+ children: children2,
6714
+ innerIndices,
6715
+ groups,
6716
+ details,
6717
+ buckets,
6718
+ width: dimensions.width,
6719
+ rowLabels: rowLabelColumns,
6720
+ top,
6721
+ bottom,
6722
+ append
6552
6723
  });
6553
- if (bottom) {
6554
- const caption = String(label(outer));
6555
- append(
6556
- [`${caption} Total`, ...compact ? [] : [null]],
6557
- numbers3([key], groups.get(key) ?? []),
6558
- { indices: [outerIndex], type: "default" }
6724
+ else
6725
+ rowItems.forEach((outer, outerIndex) => {
6726
+ const key = pivotValueKey(outer);
6727
+ if (layout3 !== "tabular")
6728
+ append(
6729
+ [label(outer), ...Array(rowLabelColumns - 1).fill(null)],
6730
+ top ? numbers3([key], groups.get(key) ?? []) : Array(dimensions.width - rowLabelColumns).fill(null),
6731
+ { indices: [outerIndex] }
6732
+ );
6733
+ let first2 = true;
6734
+ const innerKeys = [...children2.get(key)].sort(
6735
+ (a2, b) => innerIndices.get(a2) - innerIndices.get(b)
6559
6736
  );
6560
- }
6561
- });
6562
- append(["Grand Total", ...compact ? [] : [null]], numbers3([], pivot.records), {
6563
- indices: [0],
6564
- type: "grand"
6565
- });
6737
+ if (between)
6738
+ measures.forEach((measure, m) => {
6739
+ if (layout3 !== "tabular")
6740
+ append(
6741
+ compact ? [measure.caption] : [pivot.repeatLabels ? label(outer) : null, measure.caption, null],
6742
+ Array(dimensions.width - rowLabelColumns).fill(null),
6743
+ { indices: [outerIndex, m], measure: m },
6744
+ compact ? 1 : 0
6745
+ );
6746
+ innerKeys.forEach((innerKey, child4) => {
6747
+ const innerIndex = innerIndices.get(innerKey);
6748
+ const keys = [key, innerKey];
6749
+ const records = details.get(JSON.stringify(keys));
6750
+ append(
6751
+ compact ? [label(secondRowItems[innerIndex])] : [
6752
+ pivot.repeatLabels || layout3 === "tabular" && m === 0 && child4 === 0 ? label(outer) : null,
6753
+ layout3 === "tabular" && child4 === 0 ? measure.caption : null,
6754
+ label(secondRowItems[innerIndex])
6755
+ ],
6756
+ [
6757
+ ...columnItems.map(
6758
+ (column) => pivotMeasureNumber(
6759
+ pivot,
6760
+ buckets.get(JSON.stringify([...keys, pivotValueKey(column)])) ?? [],
6761
+ measure
6762
+ )
6763
+ ),
6764
+ pivotMeasureNumber(pivot, records, measure)
6765
+ ],
6766
+ { indices: [outerIndex, m, innerIndex], measure: m },
6767
+ compact ? 2 : 0
6768
+ );
6769
+ });
6770
+ });
6771
+ else
6772
+ innerKeys.forEach((innerKey) => {
6773
+ const innerIndex = innerIndices.get(innerKey);
6774
+ const inner = secondRowItems[innerIndex];
6775
+ const keys = [key, innerKey];
6776
+ const records = details.get(JSON.stringify(keys));
6777
+ if (!records) return;
6778
+ if (rowsAxis) {
6779
+ if (layout3 !== "tabular")
6780
+ append(
6781
+ compact ? [label(inner)] : [pivot.repeatLabels ? label(outer) : null, label(inner), null],
6782
+ Array(dimensions.width - rowLabelColumns).fill(null),
6783
+ { indices: [outerIndex, innerIndex] },
6784
+ compact ? 1 : 0
6785
+ );
6786
+ appendMeasures(
6787
+ [pivot.repeatLabels || first2 ? label(outer) : null, label(inner)],
6788
+ keys,
6789
+ records,
6790
+ [outerIndex, innerIndex]
6791
+ );
6792
+ first2 = false;
6793
+ return;
6794
+ }
6795
+ append(
6796
+ compact ? [label(inner)] : [
6797
+ pivot.repeatLabels || layout3 === "tabular" && first2 ? label(outer) : null,
6798
+ label(inner)
6799
+ ],
6800
+ numbers3(keys, records),
6801
+ { indices: [outerIndex, innerIndex] },
6802
+ compact ? 1 : 0
6803
+ );
6804
+ first2 = false;
6805
+ });
6806
+ if (bottom) {
6807
+ if (rowsAxis) {
6808
+ appendMeasures([label(outer)], [key], groups.get(key) ?? [], [outerIndex], "default");
6809
+ return;
6810
+ }
6811
+ const caption = String(label(outer));
6812
+ append(
6813
+ [`${caption} Total`, ...compact ? [] : [null]],
6814
+ numbers3([key], groups.get(key) ?? []),
6815
+ { indices: [outerIndex], type: "default" }
6816
+ );
6817
+ }
6818
+ });
6819
+ if (rowsAxis) appendMeasures([], [], pivot.records, [0], "grand");
6820
+ else
6821
+ append(["Grand Total", ...compact ? [] : [null]], numbers3([], pivot.records), {
6822
+ indices: [0],
6823
+ type: "grand"
6824
+ });
6566
6825
  return {
6567
6826
  values: values2,
6568
6827
  rowItems,
6569
6828
  secondRowItems,
6570
6829
  columnItems,
6571
6830
  rowEntries,
6572
- firstDataRow: pivot.columnField ? 2 : 1,
6831
+ firstDataRow,
6573
6832
  rowLabelColumns,
6574
- indents
6833
+ indents,
6834
+ ...rowsAxis ? { firstHeaderRow: 1 } : {}
6575
6835
  };
6576
6836
  }
6577
6837
 
6578
6838
  // xlsx/pivot/aggregate.ts
6579
- function aggregate(records, field, type) {
6580
- if (!records.length) return null;
6581
- const values2 = records.map((record) => record[field] ?? null);
6582
- if (type === "count") return values2.filter((value2) => value2 !== null && value2 !== "").length;
6583
- const error = values2.find(isCellError);
6584
- if (error) return error;
6585
- const numbers3 = values2.filter((value2) => typeof value2 === "number");
6586
- if (!numbers3.length) return type === "average" ? { error: "#DIV/0!" } : 0;
6587
- if (type === "min") return numbers3.reduce((a2, b) => Math.min(a2, b));
6588
- if (type === "max") return numbers3.reduce((a2, b) => Math.max(a2, b));
6589
- const sum2 = numbers3.reduce((total2, value2) => total2 + value2, 0);
6590
- return type === "average" ? sum2 / numbers3.length : sum2;
6591
- }
6592
6839
  function pivotGrid(pivot) {
6593
6840
  validatePivotFields(pivot);
6594
- if (pivot.secondRowField) return hierarchicalPivotGrid(pivot, aggregate);
6841
+ if (pivot.secondRowField) return hierarchicalPivotGrid(pivot);
6595
6842
  const rowItems = pivotItems(pivot, pivot.rowField);
6596
6843
  const columnItems = pivot.columnField ? pivotItems(pivot, pivot.columnField) : [];
6597
- if ((rowItems.length + 3) * (columnItems.length + 2) > 1e6)
6844
+ const rowsAxis = pivot.valuesAxis === "rows";
6845
+ const compact = pivot.layout === "compact";
6846
+ const headings = rowsAxis && pivot.layout !== void 0 && pivot.layout !== "tabular";
6847
+ const dimensions = pivotHeaderDimensions(pivot, columnItems.length, rowsAxis && !compact ? 2 : 1);
6848
+ const dataRows = (rowItems.length + 1) * (rowsAxis ? 1 + (pivot.additionalValues?.length ?? 0) : 1) + (headings ? rowItems.length : 0);
6849
+ if ((dataRows + dimensions.rows) * dimensions.width > 1e6)
6598
6850
  throw new Error("The PivotTable result is too large.");
6851
+ const label3 = pivotItemLabel;
6852
+ const values2 = pivotHeaders(
6853
+ pivot,
6854
+ columnItems,
6855
+ [pivot.layout === "compact" ? "Row Labels" : pivot.rowField],
6856
+ label3
6857
+ );
6599
6858
  const rowField = pivot.fields.indexOf(pivot.rowField);
6600
6859
  const colField = pivot.columnField ? pivot.fields.indexOf(pivot.columnField) : -1;
6601
- const valueField = pivot.fields.indexOf(pivot.valueField);
6602
6860
  const groups = /* @__PURE__ */ new Map();
6603
6861
  const cells = /* @__PURE__ */ new Map();
6604
6862
  const columns = /* @__PURE__ */ new Map();
@@ -6616,49 +6874,92 @@ function pivotGrid(pivot) {
6616
6874
  collect(cells, JSON.stringify([key, col]), record);
6617
6875
  }
6618
6876
  }
6619
- const label3 = pivotItemLabel;
6620
- const values2 = pivot.columnField ? [
6621
- [
6622
- pivot.valueCaption,
6623
- pivot.layout === "compact" ? "Column Labels" : pivot.columnField,
6624
- ...columnItems.slice(1).map(() => null),
6625
- null
6626
- ],
6627
- [
6628
- pivot.layout === "compact" ? "Row Labels" : pivot.rowField,
6629
- ...columnItems.map(label3),
6630
- "Grand Total"
6631
- ]
6632
- ] : [[pivot.layout === "compact" ? "Row Labels" : pivot.rowField, pivot.valueCaption]];
6877
+ const firstDataRow = values2.length;
6878
+ if (rowsAxis) {
6879
+ const measures = pivotMeasures(pivot);
6880
+ const rowEntries = [];
6881
+ const indents = values2.map(() => 0);
6882
+ const append = (caption, bands, index2, grand = false) => {
6883
+ measures.forEach((measure, m) => {
6884
+ values2.push([
6885
+ ...compact ? [grand ? `Total ${measure.caption}` : measure.caption] : [
6886
+ grand ? `Total ${measure.caption}` : pivot.repeatLabels || !headings && m === 0 ? caption : null,
6887
+ grand ? null : measure.caption
6888
+ ],
6889
+ ...bands.map((band) => band[m] ?? null)
6890
+ ]);
6891
+ indents.push(compact && !grand ? 1 : 0);
6892
+ rowEntries.push({
6893
+ indices: grand ? [0] : [index2, m],
6894
+ measure: m,
6895
+ ...grand ? { type: "grand" } : {}
6896
+ });
6897
+ });
6898
+ };
6899
+ rowItems.forEach((item, index2) => {
6900
+ const key = pivotValueKey(item);
6901
+ if (headings) {
6902
+ values2.push([label3(item), ...Array(dimensions.width - 1).fill(null)]);
6903
+ rowEntries.push({ indices: [index2] });
6904
+ indents.push(0);
6905
+ }
6906
+ append(
6907
+ label3(item),
6908
+ [
6909
+ ...columnItems.map(
6910
+ (col) => pivotNumbers(pivot, cells.get(JSON.stringify([key, pivotValueKey(col)])) ?? [])
6911
+ ),
6912
+ pivotNumbers(pivot, groups.get(key) ?? [])
6913
+ ],
6914
+ index2
6915
+ );
6916
+ });
6917
+ append(
6918
+ "Grand Total",
6919
+ [
6920
+ ...columnItems.map((col) => pivotNumbers(pivot, columns.get(pivotValueKey(col)) ?? [])),
6921
+ pivotNumbers(pivot, pivot.records)
6922
+ ],
6923
+ 0,
6924
+ true
6925
+ );
6926
+ return {
6927
+ values: values2,
6928
+ rowItems,
6929
+ columnItems,
6930
+ firstDataRow,
6931
+ rowLabelColumns: compact ? 1 : 2,
6932
+ indents,
6933
+ firstHeaderRow: 1,
6934
+ rowEntries
6935
+ };
6936
+ }
6633
6937
  for (const row2 of rowItems) {
6634
6938
  const records = groups.get(pivotValueKey(row2)) ?? [];
6635
6939
  values2.push([
6636
6940
  label3(row2),
6637
- ...columnItems.map(
6638
- (col) => aggregate(
6639
- cells.get(JSON.stringify([pivotValueKey(row2), pivotValueKey(col)])) ?? [],
6640
- valueField,
6641
- pivot.aggregate
6941
+ ...columnItems.flatMap(
6942
+ (col) => pivotNumbers(
6943
+ pivot,
6944
+ cells.get(JSON.stringify([pivotValueKey(row2), pivotValueKey(col)])) ?? []
6642
6945
  )
6643
6946
  ),
6644
- aggregate(records, valueField, pivot.aggregate)
6947
+ ...pivotNumbers(pivot, records)
6645
6948
  ]);
6646
6949
  }
6647
6950
  values2.push([
6648
6951
  "Grand Total",
6649
- ...columnItems.map(
6650
- (col) => aggregate(columns.get(pivotValueKey(col)) ?? [], valueField, pivot.aggregate)
6651
- ),
6652
- aggregate(pivot.records, valueField, pivot.aggregate)
6952
+ ...columnItems.flatMap((col) => pivotNumbers(pivot, columns.get(pivotValueKey(col)) ?? [])),
6953
+ ...pivotNumbers(pivot, pivot.records)
6653
6954
  ]);
6654
- return { values: values2, rowItems, columnItems, firstDataRow: pivot.columnField ? 2 : 1 };
6955
+ return { values: values2, rowItems, columnItems, firstDataRow };
6655
6956
  }
6656
6957
 
6657
6958
  // xlsx/pivot/admission.ts
6658
6959
  var X14 = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main";
6659
6960
  var LAYOUT = "http://schemas.microsoft.com/office/spreadsheetml/2016/pivotdefaultlayout";
6660
6961
  var TABLE = {
6661
- pivotTableDefinition: "name cacheId dataCaption updatedVersion minRefreshableVersion createdVersion applyNumberFormats applyBorderFormats applyFontFormats applyPatternFormats applyAlignmentFormats applyWidthHeightFormats useAutoFormatting itemPrintTitles indent compact compactData outline outlineData multipleFieldFilters rowGrandTotals colGrandTotals",
6962
+ pivotTableDefinition: "name cacheId dataCaption dataOnRows dataPosition updatedVersion minRefreshableVersion createdVersion applyNumberFormats applyBorderFormats applyFontFormats applyPatternFormats applyAlignmentFormats applyWidthHeightFormats useAutoFormatting itemPrintTitles indent compact compactData outline outlineData multipleFieldFilters rowGrandTotals colGrandTotals",
6662
6963
  location: "ref firstHeaderRow firstDataRow firstDataCol",
6663
6964
  pivotFields: "count",
6664
6965
  pivotField: "axis dataField compact outline showAll subtotalTop defaultSubtotal",
@@ -6669,7 +6970,7 @@ var TABLE = {
6669
6970
  field: "x",
6670
6971
  rowItems: "count",
6671
6972
  colItems: "count",
6672
- i: "t r",
6973
+ i: "t r i",
6673
6974
  x: "v",
6674
6975
  dataFields: "count",
6675
6976
  dataField: "name fld subtotal baseField baseItem showDataAs",
@@ -6700,7 +7001,7 @@ function inspect(node, profile, cache2) {
6700
7001
  for (let i2 = 0; i2 < node.attributes.length; i2++) {
6701
7002
  const attr2 = node.attributes.item(i2);
6702
7003
  if (attr2.name.startsWith("xmlns")) continue;
6703
- if (!cache2 && node.namespaceURI === X14 && node.localName === "pivotTableDefinition" && attr2.name === "hideValuesRow" && attr2.value === "1")
7004
+ if (!cache2 && node.namespaceURI === X14 && node.localName === "pivotTableDefinition" && attr2.name === "hideValuesRow" && ["0", "1"].includes(attr2.value))
6704
7005
  continue;
6705
7006
  if (!cache2 && node.namespaceURI === X14 && (node.localName === "pivotField" && attr2.name === "fillDownLabels" || node.localName === "pivotTableDefinition" && attr2.name === "fillDownLabelsDefault") && ["0", "1"].includes(attr2.value))
6706
7007
  continue;
@@ -6729,7 +7030,9 @@ function inspect(node, profile, cache2) {
6729
7030
  throw new Error("Unsupported PivotTable option");
6730
7031
  if (attr2.localName === "numFmtId" && attr2.value !== "0")
6731
7032
  throw new Error("Unsupported PivotTable field number format");
6732
- if (node.localName === "pivotTableDefinition" && ["compact", "compactData", "outline", "outlineData"].includes(attr2.localName) && !["0", "1"].includes(attr2.value))
7033
+ if (node.localName === "pivotTableDefinition" && ["compact", "compactData", "outline", "outlineData", "dataOnRows"].includes(
7034
+ attr2.localName
7035
+ ) && !["0", "1"].includes(attr2.value))
6733
7036
  throw new Error("Unsupported PivotTable global layout");
6734
7037
  if (node.localName === "item" && attr2.localName === "t" && !["default", "data"].includes(attr2.value))
6735
7038
  throw new Error("Unsupported PivotTable subtotal");
@@ -6752,6 +7055,88 @@ function assertPivotRecords(records) {
6752
7055
  );
6753
7056
  }
6754
7057
 
7058
+ // xlsx/write/xml-out.ts
7059
+ var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
7060
+ var CONTROL = "\0-\b\v\f-" + String.fromCharCode(65534, 65535);
7061
+ var NEEDS_ESCAPE = new RegExp(`[${CONTROL}\r]|_x[0-9A-Fa-f]{4}_`);
7062
+ var ESCAPABLE = new RegExp(`[${CONTROL}\r]|_(?=x[0-9A-Fa-f]{4}_)`, "g");
7063
+ function encodeEscapes(text) {
7064
+ if (!NEEDS_ESCAPE.test(text)) return text;
7065
+ return text.replace(
7066
+ ESCAPABLE,
7067
+ (ch) => `_x${ch.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}_`
7068
+ );
7069
+ }
7070
+ var INVALID_XML = new RegExp(`[${CONTROL}]`, "g");
7071
+ var escapeText2 = (text) => text.replace(INVALID_XML, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
7072
+ var escapeAttr3 = (text) => text.replace(INVALID_XML, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/\r/g, "&#13;").replace(/\n/g, "&#10;").replace(/\t/g, "&#9;");
7073
+ function attrs(values2) {
7074
+ let out = "";
7075
+ for (const [name, value2] of Object.entries(values2)) {
7076
+ if (value2 === void 0) continue;
7077
+ const text = typeof value2 === "boolean" ? value2 ? "1" : "0" : typeof value2 === "number" ? num(value2) : value2;
7078
+ out += ` ${name}="${escapeAttr3(text)}"`;
7079
+ }
7080
+ return out;
7081
+ }
7082
+ var el = (name, values2 = {}, content2 = "") => content2 ? `<${name}${attrs(values2)}>${content2}</${name}>` : `<${name}${attrs(values2)}/>`;
7083
+ var num = (value2) => Object.is(value2, -0) ? "0" : String(value2);
7084
+ function tElement(text, name = "t") {
7085
+ const encoded = escapeText2(encodeEscapes(text));
7086
+ const preserve = /^\s|\s$|\n|\t/.test(text) ? ' xml:space="preserve"' : "";
7087
+ return `<${name}${preserve}>${encoded}</${name}>`;
7088
+ }
7089
+ var MAIN_NS = ' xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"';
7090
+ function inlineFragment(xml) {
7091
+ const end = xml.indexOf(">");
7092
+ if (end < 0) return xml;
7093
+ const head = xml.slice(0, end);
7094
+ return head.includes(MAIN_NS) ? head.replace(MAIN_NS, "") + xml.slice(end) : xml;
7095
+ }
7096
+
7097
+ // xlsx/pivot/values-axis.ts
7098
+ function pivotFieldIndex(field) {
7099
+ const raw2 = field?.getAttribute("x");
7100
+ if (raw2 === null || raw2 === void 0 || !/^-?\d+$/.test(raw2.trim())) return NaN;
7101
+ const value2 = Number(raw2);
7102
+ return Number.isSafeInteger(value2) ? value2 : NaN;
7103
+ }
7104
+ function pivotValueIndex(root, axis) {
7105
+ const index2 = axis.findIndex((field) => pivotFieldIndex(field) === -2);
7106
+ const position = root.getAttribute("dataPosition");
7107
+ if (position !== null && (!/^\d+$/.test(position.trim()) || Number(position) !== index2))
7108
+ throw new Error("Inconsistent Values axis position");
7109
+ if (axis.length === 3 && index2 < 2 && position === null)
7110
+ throw new Error("Missing leading or between-field Values position");
7111
+ return index2;
7112
+ }
7113
+ function pivotValueAxisItems(measures, columns) {
7114
+ const entries = [];
7115
+ if (columns === void 0) {
7116
+ for (let measure = 0; measure < measures; measure++)
7117
+ entries.push(
7118
+ `<i${attrs({ i: measure || void 0 })}><x${attrs({ v: measure || void 0 })}/></i>`
7119
+ );
7120
+ } else {
7121
+ for (let column = 0; column < columns; column++)
7122
+ for (let measure = 0; measure < measures; measure++) {
7123
+ entries.push(
7124
+ `<i${attrs({ r: measure ? 1 : void 0, i: measure || void 0 })}>${measure ? "" : `<x${attrs({ v: column || void 0 })}/>`}<x${attrs({ v: measure || void 0 })}/></i>`
7125
+ );
7126
+ }
7127
+ for (let measure = 0; measure < measures; measure++)
7128
+ entries.push(`<i${attrs({ t: "grand", i: measure || void 0 })}><x/></i>`);
7129
+ }
7130
+ return `<colItems count="${entries.length}">${entries.join("")}</colItems>`;
7131
+ }
7132
+ function supportedPivotAxes(rows, columns, measures, valuesOnRows) {
7133
+ const index2 = pivotFieldIndex;
7134
+ if (valuesOnRows)
7135
+ return measures > 1 && (rows.length === 2 || rows.length === 3) && (index2(rows[0]) >= 0 || rows.length === 3) && rows.filter((field) => index2(field) === -2).length === 1 && rows.filter((field) => index2(field) !== -2).every((field) => index2(field) >= 0) && columns.length <= 1 && (!columns.length || index2(columns[0]) >= 0);
7136
+ if (rows.some((field) => !Number.isInteger(index2(field)) || index2(field) < 0)) return false;
7137
+ return measures === 1 ? columns.length <= 1 : columns.length >= 1 && columns.length <= 2 && index2(columns.at(-1)) === -2 && (columns.length !== 2 || index2(columns[0]) >= 0);
7138
+ }
7139
+
6755
7140
  // xlsx/pivot/read.ts
6756
7141
  function value(node) {
6757
7142
  const v = att(node, "v") ?? "";
@@ -6786,6 +7171,7 @@ function readOne(workbook, source2, part) {
6786
7171
  const dataSheet = sourceNode && att(sourceNode, "sheet");
6787
7172
  const dataRange = sourceNode && parseRange(att(sourceNode, "ref") ?? "");
6788
7173
  const recordPart = source2.targetOfType(cachePart, `${NS.r}/pivotCacheRecords`);
7174
+ const rowsAxis = att(root, "dataOnRows") === "1";
6789
7175
  if (!dataSheet || !dataRange || !recordPart || !workbook.sheets.some((sheet) => sheet.name === dataSheet))
6790
7176
  throw new Error("Unsupported pivot source");
6791
7177
  assertPivotRecords(parseXml(source2.text(recordPart)).documentElement);
@@ -6821,17 +7207,42 @@ function readOne(workbook, source2, part) {
6821
7207
  "dataField",
6822
7208
  NS.x
6823
7209
  );
6824
- if (rowFields.length < 1 || rowFields.length > 2 || colFields.length > 1 || dataFields.length !== 1 || first(root, "pageFields", NS.x) || first(root, "filters", NS.x) || root.getAttribute("rowGrandTotals") === "0" || root.getAttribute("colGrandTotals") === "0")
7210
+ if (rowFields.length < 1 || rowFields.length > (rowsAxis ? 3 : 2) || dataFields.length < 1 || dataFields.length > 16 || !supportedPivotAxes(rowFields, colFields, dataFields.length, rowsAxis) || first(root, "pageFields", NS.x) || first(root, "filters", NS.x) || root.getAttribute("rowGrandTotals") === "0" || root.getAttribute("colGrandTotals") === "0")
6825
7211
  throw new Error("Unsupported pivot layout");
7212
+ const valueIndex = pivotValueIndex(root, rowsAxis ? rowFields : colFields);
6826
7213
  const measure = dataFields[0];
7214
+ const definition = elements(first(root, "extLst", NS.x) ?? parseXml("<root/>").documentElement).map(
7215
+ (extension) => first(
7216
+ extension,
7217
+ "pivotTableDefinition",
7218
+ "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
7219
+ )
7220
+ ).find(Boolean);
7221
+ if (dataFields.length > 1 && att(definition, "hideValuesRow") !== "1")
7222
+ throw new Error("Visible Values header rows are preserved");
7223
+ for (const [axis, count2] of [
7224
+ ["rowItems", rowsAxis ? dataFields.length : 1],
7225
+ ["colItems", rowsAxis ? 1 : dataFields.length]
7226
+ ]) {
7227
+ for (const item of children(
7228
+ first(root, axis, NS.x) ?? parseXml("<root/>").documentElement,
7229
+ "i",
7230
+ NS.x
7231
+ )) {
7232
+ const index2 = Number(att(item, "i") ?? "0");
7233
+ if (!Number.isInteger(index2) || index2 < 0 || index2 >= count2)
7234
+ throw new Error("Unsupported Values axis item");
7235
+ }
7236
+ }
6827
7237
  const aggregate3 = att(measure, "subtotal") ?? "sum";
6828
7238
  if (!PIVOT_AGGREGATES.includes(aggregate3) || att(measure, "showDataAs") && att(measure, "showDataAs") !== "normal")
6829
7239
  throw new Error("Unsupported pivot aggregate");
6830
7240
  const names = fields.map((field) => decodeEscapes(att(field, "name") ?? ""));
6831
- const row2 = names[Number(att(rowFields[0], "x"))];
6832
- const second = rowFields[1] && names[Number(att(rowFields[1], "x"))];
7241
+ const realRows = rowsAxis ? rowFields.filter((field) => pivotFieldIndex(field) !== -2) : rowFields;
7242
+ const row2 = names[pivotFieldIndex(realRows[0])];
7243
+ const second = realRows[1] ? names[Number(att(realRows[1], "x"))] : void 0;
6833
7244
  const tableFields = children(first(root, "pivotFields", NS.x), "pivotField", NS.x);
6834
- const outer = tableFields[Number(att(rowFields[0], "x"))];
7245
+ const outer = tableFields[pivotFieldIndex(realRows[0])];
6835
7246
  const compact = att(outer, "compact") !== "0";
6836
7247
  const outline = att(outer, "outline") !== "0";
6837
7248
  const layout3 = compact ? "compact" : outline ? "outline" : "tabular";
@@ -6840,7 +7251,7 @@ function readOne(workbook, source2, part) {
6840
7251
  ) || att(root, "compact") !== "0" !== compact || att(root, "compactData") !== "0" !== compact || att(root, "outline") === "1" !== outline || att(root, "outlineData") === "1" !== outline || layout3 === "compact" && att(root, "indent") !== "0")
6841
7252
  throw new Error("Mixed field layouts or custom compact indentation are preserved");
6842
7253
  const subtotal = att(outer, "defaultSubtotal") !== "0";
6843
- const repeat = rowFields.map((field) => {
7254
+ const repeat = realRows.map((field) => {
6844
7255
  const node = tableFields[Number(att(field, "x"))];
6845
7256
  const extension = first(first(node, "extLst", NS.x), "ext", NS.x);
6846
7257
  return att(
@@ -6853,16 +7264,19 @@ function readOne(workbook, source2, part) {
6853
7264
  ) === "1";
6854
7265
  });
6855
7266
  if (repeat.some((entry4) => entry4 !== repeat[0])) throw new Error("Mixed field label repetition");
6856
- const col = colFields[0] && names[Number(att(colFields[0], "x"))];
7267
+ const hasColumn = colFields.length > (dataFields.length > 1 && !rowsAxis ? 1 : 0);
7268
+ const col = hasColumn ? names[Number(att(colFields[0], "x"))] : void 0;
6857
7269
  const data = names[Number(att(measure, "fld"))];
6858
7270
  const location = parseRange(att(first(root, "location", NS.x), "ref") ?? "");
6859
- if (!row2 || !data || !location || colFields.length && !col || rowFields.length === 2 && !second)
7271
+ if (!row2 || !data || !location || hasColumn && !col || realRows.length === 2 && !second)
6860
7272
  throw new Error("Invalid pivot fields");
6861
7273
  const pivot = {
6862
7274
  name: att(root, "name") ?? "PivotTable",
6863
7275
  source: `${quoteSheetName(dataSheet)}!${formatRange(dataRange)}`,
6864
7276
  rowField: row2,
6865
7277
  layout: layout3,
7278
+ ...rowsAxis ? { valuesAxis: "rows" } : {},
7279
+ ...rowsAxis && realRows.length === 2 && valueIndex < 2 ? { valuesPosition: valueIndex === 0 ? "first" : "between" } : {},
6866
7280
  subtotalPosition: att(outer, "subtotalTop") === "0" ? "bottom" : "top",
6867
7281
  ...second ? { secondRowField: second, subtotals: subtotal, repeatLabels: repeat[0] ?? false } : {
6868
7282
  ...subtotal ? {} : { subtotals: false },
@@ -6871,6 +7285,15 @@ function readOne(workbook, source2, part) {
6871
7285
  valueField: data,
6872
7286
  aggregate: aggregate3,
6873
7287
  valueCaption: decodeEscapes(att(measure, "name") ?? data),
7288
+ ...dataFields.length > 1 ? {
7289
+ additionalValues: dataFields.slice(1).map((measure2) => {
7290
+ const field = names[Number(att(measure2, "fld"))];
7291
+ const aggregate4 = att(measure2, "subtotal") ?? "sum";
7292
+ if (!field || !PIVOT_AGGREGATES.includes(aggregate4) || att(measure2, "showDataAs") && att(measure2, "showDataAs") !== "normal")
7293
+ throw new Error("Unsupported pivot measure");
7294
+ return { field, aggregate: aggregate4, caption: decodeEscapes(att(measure2, "name") ?? field) };
7295
+ })
7296
+ } : {},
6874
7297
  fields: names,
6875
7298
  records,
6876
7299
  location,
@@ -9545,45 +9968,6 @@ function readDataValidations(node) {
9545
9968
  return out;
9546
9969
  }
9547
9970
 
9548
- // xlsx/write/xml-out.ts
9549
- var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
9550
- var CONTROL = "\0-\b\v\f-" + String.fromCharCode(65534, 65535);
9551
- var NEEDS_ESCAPE = new RegExp(`[${CONTROL}\r]|_x[0-9A-Fa-f]{4}_`);
9552
- var ESCAPABLE = new RegExp(`[${CONTROL}\r]|_(?=x[0-9A-Fa-f]{4}_)`, "g");
9553
- function encodeEscapes(text) {
9554
- if (!NEEDS_ESCAPE.test(text)) return text;
9555
- return text.replace(
9556
- ESCAPABLE,
9557
- (ch) => `_x${ch.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}_`
9558
- );
9559
- }
9560
- var INVALID_XML = new RegExp(`[${CONTROL}]`, "g");
9561
- var escapeText2 = (text) => text.replace(INVALID_XML, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
9562
- var escapeAttr3 = (text) => text.replace(INVALID_XML, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/\r/g, "&#13;").replace(/\n/g, "&#10;").replace(/\t/g, "&#9;");
9563
- function attrs(values2) {
9564
- let out = "";
9565
- for (const [name, value2] of Object.entries(values2)) {
9566
- if (value2 === void 0) continue;
9567
- const text = typeof value2 === "boolean" ? value2 ? "1" : "0" : typeof value2 === "number" ? num(value2) : value2;
9568
- out += ` ${name}="${escapeAttr3(text)}"`;
9569
- }
9570
- return out;
9571
- }
9572
- var el = (name, values2 = {}, content2 = "") => content2 ? `<${name}${attrs(values2)}>${content2}</${name}>` : `<${name}${attrs(values2)}/>`;
9573
- var num = (value2) => Object.is(value2, -0) ? "0" : String(value2);
9574
- function tElement(text, name = "t") {
9575
- const encoded = escapeText2(encodeEscapes(text));
9576
- const preserve = /^\s|\s$|\n|\t/.test(text) ? ' xml:space="preserve"' : "";
9577
- return `<${name}${preserve}>${encoded}</${name}>`;
9578
- }
9579
- var MAIN_NS = ' xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"';
9580
- function inlineFragment(xml) {
9581
- const end = xml.indexOf(">");
9582
- if (end < 0) return xml;
9583
- const head = xml.slice(0, end);
9584
- return head.includes(MAIN_NS) ? head.replace(MAIN_NS, "") + xml.slice(end) : xml;
9585
- }
9586
-
9587
9971
  // xlsx/conditional-extensions.ts
9588
9972
  var XM = "http://schemas.microsoft.com/office/excel/2006/main";
9589
9973
  var URI = "{78C0D931-6437-407d-A8EE-F0AAD7539E65}";
@@ -23718,7 +24102,9 @@ function pivotTableXml(pivot, cacheId, cache2) {
23718
24102
  const row2 = pivot.fields.indexOf(pivot.rowField);
23719
24103
  const second = pivot.secondRowField ? pivot.fields.indexOf(pivot.secondRowField) : -1;
23720
24104
  const col = pivot.columnField ? pivot.fields.indexOf(pivot.columnField) : -1;
23721
- const value2 = pivot.fields.indexOf(pivot.valueField);
24105
+ const measures = pivotMeasures(pivot);
24106
+ const multiple = measures.length > 1;
24107
+ const rowsAxis = pivot.valuesAxis === "rows";
23722
24108
  const compact = pivot.layout === "compact";
23723
24109
  const outline = pivot.layout === "compact" || pivot.layout === "outline";
23724
24110
  const top = (pivot.subtotalPosition ?? (outline ? "top" : "bottom")) === "top";
@@ -23726,36 +24112,61 @@ function pivotTableXml(pivot, cacheId, cache2) {
23726
24112
  const items2 = index2 === row2 ? grid.rowItems : index2 === second ? grid.secondRowItems : index2 === col ? grid.columnItems : void 0;
23727
24113
  const subtotal = !(index2 === row2 && pivot.subtotals === false);
23728
24114
  const repeated = pivot.repeatLabels && (index2 === row2 || index2 === second) ? '<extLst><ext uri="{2946ED86-A175-432a-8AC1-64E0C546D7DE}"><x14:pivotField xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main" fillDownLabels="1"/></ext></extLst>' : "";
23729
- return `<pivotField${attrs({ axis: index2 === row2 || index2 === second ? "axisRow" : index2 === col ? "axisCol" : void 0, dataField: index2 === value2 ? true : void 0, compact, outline, showAll: false, subtotalTop: index2 === row2 ? top : void 0, defaultSubtotal: subtotal ? void 0 : false })}>${items2 ? `<items count="${items2.length + Number(subtotal)}">${items2.map((item) => `<item x="${cache2.indices[index2].get(pivotValueKey(item))}"/>`).join("")}${subtotal ? '<item t="default"/>' : ""}</items>` : ""}${repeated}</pivotField>`;
24115
+ return `<pivotField${attrs({ axis: index2 === row2 || index2 === second ? "axisRow" : index2 === col ? "axisCol" : void 0, dataField: measures.some((measure) => pivot.fields.indexOf(measure.field) === index2) ? true : void 0, compact, outline, showAll: false, subtotalTop: index2 === row2 ? top : void 0, defaultSubtotal: subtotal ? void 0 : false })}>${items2 ? `<items count="${items2.length + Number(subtotal)}">${items2.map((item) => `<item x="${cache2.indices[index2].get(pivotValueKey(item))}"/>`).join("")}${subtotal ? '<item t="default"/>' : ""}</items>` : ""}${repeated}</pivotField>`;
23730
24116
  }).join("");
23731
24117
  const items = (count2) => Array.from({ length: count2 }, (_v, i2) => `<i><x v="${i2}"/></i>`).join("") + '<i t="grand"><x/></i>';
23732
- const header = grid.firstDataRow - 1;
23733
- const rowIndices = [row2, ...second >= 0 ? [second] : []];
24118
+ const header = grid.firstHeaderRow ?? (multiple && col >= 0 ? 1 : grid.firstDataRow - 1);
24119
+ const rowIndices = rowsAxis && pivot.valuesPosition === "first" ? [-2, row2, second] : rowsAxis && pivot.valuesPosition === "between" ? [row2, -2, second] : [row2, ...second >= 0 ? [second] : [], ...rowsAxis ? [-2] : []];
23734
24120
  let previous = [];
23735
24121
  const rowItems = grid.rowEntries?.map((entry3) => {
23736
24122
  let prefix = 0;
23737
- if (!entry3.type)
24123
+ if (entry3.type === "default" && rowsAxis && pivot.valuesPosition === "first") prefix = 1;
24124
+ else if (!entry3.type)
23738
24125
  while (prefix < entry3.indices.length - 1 && entry3.indices[prefix] === previous[prefix])
23739
24126
  prefix++;
23740
- previous = entry3.type ? [] : entry3.indices;
23741
- return `<i${attrs({ t: entry3.type, r: prefix || void 0 })}>${entry3.indices.slice(prefix).map((index2) => `<x${attrs({ v: index2 || void 0 })}/>`).join("")}</i>`;
24127
+ previous = entry3.type && !(entry3.type === "default" && pivot.valuesPosition === "first") ? [] : entry3.indices;
24128
+ return `<i${attrs({ t: entry3.type, r: prefix || void 0, i: entry3.measure || void 0 })}>${entry3.indices.slice(prefix).map((index2) => `<x${attrs({ v: index2 || void 0 })}/>`).join("")}</i>`;
23742
24129
  }).join("") ?? items(grid.rowItems.length);
23743
24130
  let body = `<location${attrs({ ref: formatRange(pivot.location), firstHeaderRow: header, firstDataRow: grid.firstDataRow, firstDataCol: grid.rowLabelColumns ?? 1 })}/><pivotFields count="${pivot.fields.length}">${fields}</pivotFields><rowFields count="${rowIndices.length}">${rowIndices.map((index2) => `<field x="${index2}"/>`).join("")}</rowFields><rowItems count="${grid.rowEntries?.length ?? grid.rowItems.length + 1}">${rowItems}</rowItems>`;
23744
- if (col >= 0)
24131
+ if (multiple && !rowsAxis)
24132
+ body += `<colFields count="${col >= 0 ? 2 : 1}">${col >= 0 ? `<field x="${col}"/>` : ""}<field x="-2"/></colFields>${pivotValueAxisItems(measures.length, col >= 0 ? grid.columnItems.length : void 0)}`;
24133
+ else if (col >= 0)
23745
24134
  body += `<colFields count="1"><field x="${col}"/></colFields><colItems count="${grid.columnItems.length + 1}">${items(grid.columnItems.length)}</colItems>`;
23746
- else body += '<colItems count="1"><i><x/></i></colItems>';
23747
- body += `<dataFields count="1"><dataField${attrs({ name: encodeEscapes(pivot.valueCaption), fld: value2, subtotal: pivot.aggregate, baseField: 0, baseItem: 0 })}/></dataFields>`;
24135
+ else
24136
+ body += rowsAxis ? '<colItems count="1"><i/></colItems>' : '<colItems count="1"><i><x/></i></colItems>';
24137
+ body += `<dataFields count="${measures.length}">${measures.map((measure) => `<dataField${attrs({ name: encodeEscapes(measure.caption), fld: pivot.fields.indexOf(measure.field), subtotal: measure.aggregate, baseField: 0, baseItem: 0 })}/>`).join("")}</dataFields>`;
23748
24138
  const doc = parseXml(
23749
24139
  pivot.sourceXml ?? `<pivotTableDefinition xmlns="${NS.x}" dataCaption="Values" updatedVersion="6" minRefreshableVersion="3" createdVersion="6"><pivotTableStyleInfo name="PivotStyleLight16" showRowHeaders="1" showColHeaders="1" showRowStripes="0" showColStripes="0" showLastColumn="1"/></pivotTableDefinition>`
23750
24140
  );
23751
24141
  const root = doc.documentElement;
23752
24142
  root.setAttribute("name", pivot.name);
23753
24143
  root.setAttribute("cacheId", String(cacheId));
24144
+ root.setAttribute("dataOnRows", rowsAxis ? "1" : "0");
24145
+ if (rowsAxis && (pivot.valuesPosition === "between" || pivot.valuesPosition === "first"))
24146
+ root.setAttribute("dataPosition", pivot.valuesPosition === "first" ? "0" : "1");
24147
+ else root.removeAttribute("dataPosition");
23754
24148
  root.setAttribute("compact", compact ? "1" : "0");
23755
24149
  root.setAttribute("compactData", compact ? "1" : "0");
23756
24150
  root.setAttribute("outline", outline ? "1" : "0");
23757
24151
  root.setAttribute("outlineData", outline ? "1" : "0");
23758
24152
  if (compact) root.setAttribute("indent", "0");
24153
+ if (multiple && !elements(first(root, "extLst", NS.x) ?? parseXml("<root/>").documentElement).some(
24154
+ (extension) => first(
24155
+ extension,
24156
+ "pivotTableDefinition",
24157
+ "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
24158
+ )
24159
+ )) {
24160
+ let list = first(root, "extLst", NS.x);
24161
+ if (!list) {
24162
+ list = doc.createElementNS(NS.x, "extLst");
24163
+ root.appendChild(list);
24164
+ }
24165
+ const extension = parseXml(
24166
+ `<ext xmlns="${NS.x}" uri="{962EF5D1-5CA2-4c93-8EF4-DBF5C05439D2}"><x14:pivotTableDefinition xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main" hideValuesRow="1"/></ext>`
24167
+ ).documentElement;
24168
+ list.appendChild(doc.importNode(extension, true));
24169
+ }
23759
24170
  root.setAttribute("rowGrandTotals", "1");
23760
24171
  root.setAttribute("colGrandTotals", "1");
23761
24172
  for (const extension of elements(
@@ -23766,6 +24177,7 @@ function pivotTableXml(pivot, cacheId, cache2) {
23766
24177
  "pivotTableDefinition",
23767
24178
  "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
23768
24179
  );
24180
+ if (multiple && definition) definition.setAttribute("hideValuesRow", "1");
23769
24181
  if (definition?.hasAttribute("fillDownLabelsDefault"))
23770
24182
  definition.setAttribute("fillDownLabelsDefault", pivot.repeatLabels ? "1" : "0");
23771
24183
  }