@cj-tech-master/excelts 2.0.1 → 3.0.0-canary.20251228183403.d3eb98d

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 (58) hide show
  1. package/dist/browser/excelts.esm.js +181 -133
  2. package/dist/browser/excelts.esm.js.map +1 -1
  3. package/dist/browser/excelts.esm.min.js +30 -24
  4. package/dist/browser/excelts.iife.js +181 -133
  5. package/dist/browser/excelts.iife.js.map +1 -1
  6. package/dist/browser/excelts.iife.min.js +30 -24
  7. package/dist/cjs/doc/pivot-table.js +47 -6
  8. package/dist/cjs/doc/worksheet.js +0 -1
  9. package/dist/cjs/stream/xlsx/worksheet-writer.js +0 -1
  10. package/dist/cjs/xlsx/xform/book/sheet-xform.js +3 -2
  11. package/dist/cjs/xlsx/xform/book/workbook-properties-xform.js +1 -1
  12. package/dist/cjs/xlsx/xform/core/content-types-xform.js +12 -6
  13. package/dist/cjs/xlsx/xform/pivot-table/cache-field-xform.js +17 -21
  14. package/dist/cjs/xlsx/xform/pivot-table/cache-field.js +43 -7
  15. package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +1 -10
  16. package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-records-xform.js +1 -1
  17. package/dist/cjs/xlsx/xform/pivot-table/pivot-table-xform.js +51 -30
  18. package/dist/cjs/xlsx/xform/sheet/page-setup-xform.js +4 -3
  19. package/dist/cjs/xlsx/xform/sheet/row-xform.js +1 -1
  20. package/dist/cjs/xlsx/xform/sheet/sheet-format-properties-xform.js +6 -3
  21. package/dist/cjs/xlsx/xform/sheet/sheet-view-xform.js +8 -4
  22. package/dist/cjs/xlsx/xform/sheet/worksheet-xform.js +2 -2
  23. package/dist/cjs/xlsx/xform/style/font-xform.js +36 -23
  24. package/dist/cjs/xlsx/xform/table/auto-filter-xform.js +3 -1
  25. package/dist/cjs/xlsx/xform/table/table-column-xform.js +2 -1
  26. package/dist/cjs/xlsx/xform/table/table-xform.js +5 -9
  27. package/dist/esm/doc/pivot-table.js +47 -6
  28. package/dist/esm/doc/worksheet.js +0 -1
  29. package/dist/esm/stream/xlsx/worksheet-writer.js +0 -1
  30. package/dist/esm/xlsx/xform/book/sheet-xform.js +3 -2
  31. package/dist/esm/xlsx/xform/book/workbook-properties-xform.js +1 -1
  32. package/dist/esm/xlsx/xform/core/content-types-xform.js +12 -6
  33. package/dist/esm/xlsx/xform/pivot-table/cache-field-xform.js +17 -21
  34. package/dist/esm/xlsx/xform/pivot-table/cache-field.js +43 -7
  35. package/dist/esm/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +1 -10
  36. package/dist/esm/xlsx/xform/pivot-table/pivot-cache-records-xform.js +1 -1
  37. package/dist/esm/xlsx/xform/pivot-table/pivot-table-xform.js +51 -30
  38. package/dist/esm/xlsx/xform/sheet/page-setup-xform.js +4 -3
  39. package/dist/esm/xlsx/xform/sheet/row-xform.js +1 -1
  40. package/dist/esm/xlsx/xform/sheet/sheet-format-properties-xform.js +6 -3
  41. package/dist/esm/xlsx/xform/sheet/sheet-view-xform.js +8 -4
  42. package/dist/esm/xlsx/xform/sheet/worksheet-xform.js +2 -2
  43. package/dist/esm/xlsx/xform/style/font-xform.js +36 -23
  44. package/dist/esm/xlsx/xform/table/auto-filter-xform.js +3 -1
  45. package/dist/esm/xlsx/xform/table/table-column-xform.js +2 -1
  46. package/dist/esm/xlsx/xform/table/table-xform.js +5 -9
  47. package/dist/types/doc/pivot-table.d.ts +5 -1
  48. package/dist/types/stream/xlsx/worksheet-writer.d.ts +1 -1
  49. package/dist/types/types.d.ts +1 -1
  50. package/dist/types/xlsx/xform/pivot-table/cache-field-xform.d.ts +1 -1
  51. package/dist/types/xlsx/xform/pivot-table/cache-field.d.ts +6 -2
  52. package/dist/types/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +0 -5
  53. package/dist/types/xlsx/xform/pivot-table/pivot-table-xform.d.ts +0 -3
  54. package/dist/types/xlsx/xform/sheet/sheet-format-properties-xform.d.ts +1 -1
  55. package/dist/types/xlsx/xform/sheet/worksheet-xform.d.ts +1 -1
  56. package/dist/types/xlsx/xform/style/font-xform.d.ts +1 -0
  57. package/dist/types/xlsx/xform/table/table-xform.d.ts +0 -4
  58. package/package.json +1 -1
@@ -55,8 +55,6 @@ class PivotTableXform extends BaseXform {
55
55
  */
56
56
  renderNew(xmlStream, model) {
57
57
  const { rows, columns, values, cacheFields, cacheId, applyWidthHeightFormats } = model;
58
- // Generate unique UID for each pivot table to prevent Excel treating them as identical
59
- const uniqueUid = `{${crypto.randomUUID().toUpperCase()}}`;
60
58
  // Build rowItems - need one <i> for each unique value in row fields, plus grand total
61
59
  const rowItems = buildRowItems(rows, cacheFields);
62
60
  // Build colItems - need one <i> for each unique value in col fields, plus grand total
@@ -68,15 +66,20 @@ class PivotTableXform extends BaseXform {
68
66
  // - firstHeaderRow: 1 (column headers are in first row of pivot table)
69
67
  // - firstDataRow: 2 (data starts in second row)
70
68
  // - firstDataCol: 1 (data starts in second column, after row labels)
71
- // Calculate ref based on actual data size
72
- const endRow = 3 + rowFieldItemCount + 1; // start row + data rows + grand total
69
+ // Calculate ref based on actual data size:
70
+ // - Start row: 3
71
+ // - Header rows: 2 (column label row + subheader row)
72
+ // - Data rows: rowFieldItemCount
73
+ // - Grand total row: 1
74
+ // endRow = 3 + 2 + rowFieldItemCount + 1 - 1 = 5 + rowFieldItemCount
75
+ // Or simplified: startRow (3) + 1 (column labels) + rowFieldItemCount (data) + 1 (grand total)
76
+ const endRow = 3 + 1 + rowFieldItemCount + 1; // = 5 + rowFieldItemCount
73
77
  const endCol = 1 + colFieldItemCount + 1; // start col + data cols + grand total
74
78
  const endColLetter = String.fromCharCode(64 + endCol);
75
79
  const locationRef = `A3:${endColLetter}${endRow}`;
76
80
  xmlStream.openXml(XmlStream.StdDocAttributes);
77
81
  xmlStream.openNode(this.tag, {
78
82
  ...PivotTableXform.PIVOT_TABLE_ATTRIBUTES,
79
- "xr:uid": uniqueUid,
80
83
  name: "PivotTable2",
81
84
  cacheId,
82
85
  applyNumberFormats: "0",
@@ -153,11 +156,9 @@ class PivotTableXform extends BaseXform {
153
156
  * Render loaded pivot table (preserving original structure)
154
157
  */
155
158
  renderLoaded(xmlStream, model) {
156
- const uniqueUid = model.uid || `{${crypto.randomUUID().toUpperCase()}}`;
157
159
  xmlStream.openXml(XmlStream.StdDocAttributes);
158
160
  xmlStream.openNode(this.tag, {
159
161
  ...PivotTableXform.PIVOT_TABLE_ATTRIBUTES,
160
- "xr:uid": uniqueUid,
161
162
  name: model.name || "PivotTable1",
162
163
  cacheId: model.cacheId,
163
164
  applyNumberFormats: model.applyNumberFormats || "0",
@@ -470,17 +471,15 @@ class PivotTableXform extends BaseXform {
470
471
  }
471
472
  }
472
473
  PivotTableXform.PIVOT_TABLE_ATTRIBUTES = {
473
- xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
474
- "xmlns:mc": "http://schemas.openxmlformats.org/markup-compatibility/2006",
475
- "mc:Ignorable": "xr",
476
- "xmlns:xr": "http://schemas.microsoft.com/office/spreadsheetml/2014/revision"
474
+ xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
477
475
  };
478
476
  // Helpers
479
477
  /**
480
478
  * Build rowItems XML - one item for each unique value in row fields, plus grand total.
481
479
  * Each <i> represents a row in the pivot table.
482
- * - Regular items: <i><x v="index"/></i> where index is the position in sharedItems
480
+ * - Regular items: <i><x/></i> for index 0, <i><x v="index"/></i> for index > 0
483
481
  * - Grand total: <i t="grand"><x/></i>
482
+ * Note: When v=0, the v attribute should be omitted (Excel convention)
484
483
  */
485
484
  function buildRowItems(rows, cacheFields) {
486
485
  if (rows.length === 0) {
@@ -494,8 +493,14 @@ function buildRowItems(rows, cacheFields) {
494
493
  // Build items: one for each unique value + grand total
495
494
  const items = [];
496
495
  // Regular items - reference each unique value by index
496
+ // Note: v="0" should be omitted (Excel uses <x/> instead of <x v="0"/>)
497
497
  for (let i = 0; i < itemCount; i++) {
498
- items.push(`<i><x v="${i}" /></i>`);
498
+ if (i === 0) {
499
+ items.push("<i><x /></i>");
500
+ }
501
+ else {
502
+ items.push(`<i><x v="${i}" /></i>`);
503
+ }
499
504
  }
500
505
  // Grand total row
501
506
  items.push('<i t="grand"><x /></i>');
@@ -507,6 +512,7 @@ function buildRowItems(rows, cacheFields) {
507
512
  /**
508
513
  * Build colItems XML - one item for each unique value in column fields, plus grand total.
509
514
  * When there are multiple data fields (values), each column value may have sub-columns.
515
+ * Note: When v=0, the v attribute should be omitted (Excel convention)
510
516
  */
511
517
  function buildColItems(columns, cacheFields, valueCount) {
512
518
  if (columns.length === 0) {
@@ -515,7 +521,12 @@ function buildColItems(columns, cacheFields, valueCount) {
515
521
  // Multiple values: one column per value + grand total
516
522
  const items = [];
517
523
  for (let i = 0; i < valueCount; i++) {
518
- items.push(`<i><x v="${i}" /></i>`);
524
+ if (i === 0) {
525
+ items.push("<i><x /></i>");
526
+ }
527
+ else {
528
+ items.push(`<i><x v="${i}" /></i>`);
529
+ }
519
530
  }
520
531
  items.push('<i t="grand"><x /></i>');
521
532
  return { count: items.length, xml: items.join("\n ") };
@@ -530,8 +541,14 @@ function buildColItems(columns, cacheFields, valueCount) {
530
541
  // Build items: one for each unique value + grand total
531
542
  const items = [];
532
543
  // Regular items - reference each unique value by index
544
+ // Note: v="0" should be omitted (Excel uses <x/> instead of <x v="0"/>)
533
545
  for (let i = 0; i < itemCount; i++) {
534
- items.push(`<i><x v="${i}" /></i>`);
546
+ if (i === 0) {
547
+ items.push("<i><x /></i>");
548
+ }
549
+ else {
550
+ items.push(`<i><x v="${i}" /></i>`);
551
+ }
535
552
  }
536
553
  // Grand total column
537
554
  items.push('<i t="grand"><x /></i>');
@@ -564,38 +581,42 @@ function renderPivotFields(pivotTable) {
564
581
  const valueSet = new Set(pivotTable.values);
565
582
  return pivotTable.cacheFields
566
583
  .map((cacheField, fieldIndex) => {
567
- const fieldType = rowSet.has(fieldIndex)
568
- ? "row"
569
- : colSet.has(fieldIndex)
570
- ? "column"
571
- : valueSet.has(fieldIndex)
572
- ? "value"
573
- : null;
574
- return renderPivotField(fieldType, cacheField.sharedItems);
584
+ const isRow = rowSet.has(fieldIndex);
585
+ const isCol = colSet.has(fieldIndex);
586
+ const isValue = valueSet.has(fieldIndex);
587
+ return renderPivotField(isRow, isCol, isValue, cacheField.sharedItems);
575
588
  })
576
589
  .join("");
577
590
  }
578
- function renderPivotField(fieldType, sharedItems) {
579
- // fieldType: 'row', 'column', 'value', null
580
- const defaultAttributes = 'compact="0" outline="0" showAll="0" defaultSubtotal="0"';
581
- if (fieldType === "row" || fieldType === "column") {
582
- const axis = fieldType === "row" ? "axisRow" : "axisCol";
591
+ function renderPivotField(isRow, isCol, isValue, sharedItems) {
592
+ // A field can be both a row/column field AND a value field (issue #15)
593
+ // In this case, it needs both axis attribute AND dataField="1"
594
+ if (isRow || isCol) {
595
+ const axis = isRow ? "axisRow" : "axisCol";
596
+ // Row and column fields should NOT have defaultSubtotal="0"
597
+ let axisAttributes = 'compact="0" outline="0" showAll="0"';
598
+ // If also a value field, add dataField="1"
599
+ if (isValue) {
600
+ axisAttributes = `dataField="1" ${axisAttributes}`;
601
+ }
583
602
  // items = one for each shared item + one default item
584
603
  const itemsXml = [
585
604
  ...sharedItems.map((_item, index) => `<item x="${index}" />`),
586
605
  '<item t="default" />' // Required default item for subtotals/grand totals
587
606
  ].join("\n ");
588
607
  return `
589
- <pivotField axis="${axis}" ${defaultAttributes}>
608
+ <pivotField axis="${axis}" ${axisAttributes}>
590
609
  <items count="${sharedItems.length + 1}">
591
610
  ${itemsXml}
592
611
  </items>
593
612
  </pivotField>
594
613
  `;
595
614
  }
615
+ // Value fields and non-axis fields should have defaultSubtotal="0"
616
+ const defaultAttributes = 'compact="0" outline="0" showAll="0" defaultSubtotal="0"';
596
617
  return `
597
618
  <pivotField
598
- ${fieldType === "value" ? 'dataField="1"' : ""}
619
+ ${isValue ? 'dataField="1"' : ""}
599
620
  ${defaultAttributes}
600
621
  />
601
622
  `;
@@ -48,9 +48,10 @@ class PageSetupXform extends BaseXform {
48
48
  draft: booleanToXml(model.draft),
49
49
  cellComments: cellCommentsToXml(model.cellComments),
50
50
  errors: errorsToXml(model.errors),
51
- scale: model.scale,
52
- fitToWidth: model.fitToWidth,
53
- fitToHeight: model.fitToHeight,
51
+ // Only output non-default values (matches Excel behavior)
52
+ scale: model.scale !== 100 ? model.scale : undefined,
53
+ fitToWidth: model.fitToWidth !== 1 ? model.fitToWidth : undefined,
54
+ fitToHeight: model.fitToHeight !== 1 ? model.fitToHeight : undefined,
54
55
  firstPageNumber: model.firstPageNumber,
55
56
  useFirstPageNumber: booleanToXml(!!model.firstPageNumber),
56
57
  usePrinterDefaults: booleanToXml(model.usePrinterDefaults),
@@ -48,7 +48,7 @@ class RowXform extends BaseXform {
48
48
  xmlStream.addAttribute("s", model.styleId);
49
49
  xmlStream.addAttribute("customFormat", "1");
50
50
  }
51
- xmlStream.addAttribute("x14ac:dyDescent", "0.25");
51
+ // Note: dyDescent is MS extension, not output by default (Excel auto-calculates)
52
52
  if (model.outlineLevel) {
53
53
  xmlStream.addAttribute("outlineLevel", model.outlineLevel);
54
54
  }
@@ -7,10 +7,13 @@ class SheetFormatPropertiesXform extends BaseXform {
7
7
  if (model) {
8
8
  const attributes = {
9
9
  defaultRowHeight: model.defaultRowHeight,
10
- outlineLevelRow: model.outlineLevelRow,
11
- outlineLevelCol: model.outlineLevelCol,
12
- "x14ac:dyDescent": model.dyDescent
10
+ // Only output outlineLevelRow/Col when non-zero (matches Excel behavior)
11
+ outlineLevelRow: model.outlineLevelRow || undefined,
12
+ outlineLevelCol: model.outlineLevelCol || undefined,
13
+ // Only output dyDescent if explicitly set (MS extension, not ECMA-376 standard)
14
+ "x14ac:dyDescent": model.dyDescent || undefined
13
15
  };
16
+ // Only output defaultColWidth if explicitly set
14
17
  if (model.defaultColWidth) {
15
18
  attributes.defaultColWidth = model.defaultColWidth;
16
19
  }
@@ -20,16 +20,20 @@ class SheetViewXform extends BaseXform {
20
20
  }
21
21
  }
22
22
  render(xmlStream, model) {
23
- xmlStream.openNode("sheetView", {
24
- workbookViewId: model.workbookViewId || 0
25
- });
23
+ // Build initial attributes with correct order to match Excel output
24
+ const initialAttrs = {};
25
+ if (model.tabSelected) {
26
+ initialAttrs.tabSelected = "1";
27
+ }
28
+ initialAttrs.workbookViewId = model.workbookViewId || 0;
29
+ xmlStream.openNode("sheetView", initialAttrs);
26
30
  const add = function (name, value, included) {
27
31
  if (included) {
28
32
  xmlStream.addAttribute(name, value);
29
33
  }
30
34
  };
31
35
  add("rightToLeft", "1", model.rightToLeft === true);
32
- add("tabSelected", "1", model.tabSelected);
36
+ // tabSelected is now in initialAttrs
33
37
  add("showRuler", "0", model.showRuler === false);
34
38
  add("showRowColHeaders", "0", model.showRowColHeaders === false);
35
39
  add("showGridLines", "0", model.showGridLines === false);
@@ -511,7 +511,7 @@ WorkSheetXform.WORKSHEET_ATTRIBUTES = {
511
511
  xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
512
512
  "xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
513
513
  "xmlns:mc": "http://schemas.openxmlformats.org/markup-compatibility/2006",
514
- "mc:Ignorable": "x14ac",
515
- "xmlns:x14ac": "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"
514
+ "xmlns:x14ac": "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac",
515
+ "mc:Ignorable": "x14ac"
516
516
  };
517
517
  export { WorkSheetXform };
@@ -9,35 +9,48 @@ class FontXform extends BaseXform {
9
9
  constructor(options) {
10
10
  super();
11
11
  this.options = options || FontXform.OPTIONS;
12
- this.map = {
13
- b: { prop: "bold", xform: new BooleanXform({ tag: "b", attr: "val" }) },
14
- i: { prop: "italic", xform: new BooleanXform({ tag: "i", attr: "val" }) },
15
- u: { prop: "underline", xform: new UnderlineXform() },
16
- charset: { prop: "charset", xform: new IntegerXform({ tag: "charset", attr: "val" }) },
17
- color: { prop: "color", xform: new ColorXform() },
18
- condense: { prop: "condense", xform: new BooleanXform({ tag: "condense", attr: "val" }) },
19
- extend: { prop: "extend", xform: new BooleanXform({ tag: "extend", attr: "val" }) },
20
- family: { prop: "family", xform: new IntegerXform({ tag: "family", attr: "val" }) },
21
- outline: { prop: "outline", xform: new BooleanXform({ tag: "outline", attr: "val" }) },
22
- vertAlign: { prop: "vertAlign", xform: new StringXform({ tag: "vertAlign", attr: "val" }) },
23
- scheme: { prop: "scheme", xform: new StringXform({ tag: "scheme", attr: "val" }) },
24
- shadow: { prop: "shadow", xform: new BooleanXform({ tag: "shadow", attr: "val" }) },
25
- strike: { prop: "strike", xform: new BooleanXform({ tag: "strike", attr: "val" }) },
26
- sz: { prop: "size", xform: new IntegerXform({ tag: "sz", attr: "val" }) }
27
- };
28
- this.map[this.options.fontNameTag] = {
29
- prop: "name",
30
- xform: new StringXform({ tag: this.options.fontNameTag, attr: "val" })
31
- };
12
+ // Define properties in render order (Excel's expected order)
13
+ const fontProperties = [
14
+ { tag: "b", prop: "bold", xform: new BooleanXform({ tag: "b", attr: "val" }) },
15
+ { tag: "i", prop: "italic", xform: new BooleanXform({ tag: "i", attr: "val" }) },
16
+ { tag: "u", prop: "underline", xform: new UnderlineXform() },
17
+ { tag: "strike", prop: "strike", xform: new BooleanXform({ tag: "strike", attr: "val" }) },
18
+ {
19
+ tag: "condense",
20
+ prop: "condense",
21
+ xform: new BooleanXform({ tag: "condense", attr: "val" })
22
+ },
23
+ { tag: "extend", prop: "extend", xform: new BooleanXform({ tag: "extend", attr: "val" }) },
24
+ { tag: "outline", prop: "outline", xform: new BooleanXform({ tag: "outline", attr: "val" }) },
25
+ { tag: "shadow", prop: "shadow", xform: new BooleanXform({ tag: "shadow", attr: "val" }) },
26
+ { tag: "sz", prop: "size", xform: new IntegerXform({ tag: "sz", attr: "val" }) },
27
+ { tag: "color", prop: "color", xform: new ColorXform() },
28
+ {
29
+ tag: this.options.fontNameTag,
30
+ prop: "name",
31
+ xform: new StringXform({ tag: this.options.fontNameTag, attr: "val" })
32
+ },
33
+ { tag: "family", prop: "family", xform: new IntegerXform({ tag: "family", attr: "val" }) },
34
+ { tag: "scheme", prop: "scheme", xform: new StringXform({ tag: "scheme", attr: "val" }) },
35
+ { tag: "charset", prop: "charset", xform: new IntegerXform({ tag: "charset", attr: "val" }) },
36
+ {
37
+ tag: "vertAlign",
38
+ prop: "vertAlign",
39
+ xform: new StringXform({ tag: "vertAlign", attr: "val" })
40
+ }
41
+ ];
42
+ // Build map and renderOrder from single source of truth
43
+ this.map = Object.fromEntries(fontProperties.map(p => [p.tag, { prop: p.prop, xform: p.xform }]));
44
+ this.renderOrder = fontProperties.map(p => p.tag);
32
45
  }
33
46
  get tag() {
34
47
  return this.options.tagName;
35
48
  }
36
49
  render(xmlStream, model) {
37
- const { map } = this;
50
+ const { map, renderOrder } = this;
38
51
  xmlStream.openNode(this.options.tagName);
39
- Object.entries(this.map).forEach(([tag, defn]) => {
40
- map[tag].xform.render(xmlStream, model[defn.prop]);
52
+ renderOrder.forEach(tag => {
53
+ map[tag].xform.render(xmlStream, model[map[tag].prop]);
41
54
  });
42
55
  xmlStream.closeNode();
43
56
  }
@@ -17,7 +17,9 @@ class AutoFilterXform extends BaseXform {
17
17
  });
18
18
  }
19
19
  render(xmlStream, model) {
20
- xmlStream.openNode(this.tag, { ref: model.autoFilterRef });
20
+ xmlStream.openNode(this.tag, {
21
+ ref: model.autoFilterRef
22
+ });
21
23
  model.columns.forEach((column) => {
22
24
  this.map.filterColumn.render(xmlStream, column);
23
25
  });
@@ -15,7 +15,8 @@ class TableColumnXform extends BaseXform {
15
15
  id: model.id.toString(),
16
16
  name: model.name,
17
17
  totalsRowLabel: model.totalsRowLabel,
18
- totalsRowFunction: model.totalsRowFunction,
18
+ // Excel doesn't output totalsRowFunction when value is 'none'
19
+ totalsRowFunction: model.totalsRowFunction === "none" ? undefined : model.totalsRowFunction,
19
20
  dxfId: model.dxfId
20
21
  });
21
22
  }
@@ -40,8 +40,8 @@ class TableXform extends BaseXform {
40
40
  displayName: model.displayName || model.name,
41
41
  ref: model.tableRef,
42
42
  totalsRowCount: model.totalsRow ? "1" : undefined,
43
- totalsRowShown: model.totalsRow ? undefined : "1",
44
- headerRowCount: model.headerRow ? "1" : "0"
43
+ // Excel doesn't output headerRowCount when it's 1 (default) or when there's a header row
44
+ headerRowCount: model.headerRow ? undefined : "0"
45
45
  });
46
46
  this.map.autoFilter.render(xmlStream, model);
47
47
  this.map.tableColumns.render(xmlStream, model.columns);
@@ -62,7 +62,8 @@ class TableXform extends BaseXform {
62
62
  displayName: attributes.displayName || attributes.name,
63
63
  tableRef: attributes.ref,
64
64
  totalsRow: attributes.totalsRowCount === "1",
65
- headerRow: attributes.headerRowCount === "1"
65
+ // ECMA-376: headerRowCount defaults to 1, so missing attribute means has header
66
+ headerRow: attributes.headerRowCount !== "0"
66
67
  };
67
68
  break;
68
69
  default:
@@ -120,11 +121,6 @@ class TableXform extends BaseXform {
120
121
  }
121
122
  }
122
123
  TableXform.TABLE_ATTRIBUTES = {
123
- xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
124
- "xmlns:mc": "http://schemas.openxmlformats.org/markup-compatibility/2006",
125
- "mc:Ignorable": "xr xr3",
126
- "xmlns:xr": "http://schemas.microsoft.com/office/spreadsheetml/2014/revision",
127
- "xmlns:xr3": "http://schemas.microsoft.com/office/spreadsheetml/2016/revision3"
128
- // 'xr:uid': '{00000000-000C-0000-FFFF-FFFF00000000}',
124
+ xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
129
125
  };
130
126
  export { TableXform };
@@ -4,7 +4,7 @@ import type { Table } from "./table";
4
4
  * This allows both Worksheet and Table to be used as pivot table data sources.
5
5
  */
6
6
  export interface PivotTableSource {
7
- /** Name of the source (worksheet name or table name) */
7
+ /** Name of the worksheet containing the source data (used in pivotCacheDefinition) */
8
8
  name: string;
9
9
  /** Get row values by 1-indexed row number */
10
10
  getRow(rowNumber: number): {
@@ -71,6 +71,10 @@ export interface CacheField {
71
71
  name: string;
72
72
  /** Unique values for row/column fields, null for value fields */
73
73
  sharedItems: any[] | null;
74
+ /** Minimum value for numeric fields */
75
+ minValue?: number;
76
+ /** Maximum value for numeric fields */
77
+ maxValue?: number;
74
78
  }
75
79
  /** Aggregation function types for pivot table data fields */
76
80
  export type PivotTableSubtotal = "sum" | "count" | "average" | "max" | "min" | "product" | "countNums" | "stdDev" | "stdDevP" | "var" | "varP";
@@ -49,7 +49,7 @@ declare class WorksheetWriter {
49
49
  colBreaks: ColBreak[];
50
50
  properties: Partial<WorksheetProperties> & {
51
51
  defaultRowHeight: number;
52
- dyDescent: number;
52
+ dyDescent?: number;
53
53
  outlineLevelCol: number;
54
54
  outlineLevelRow: number;
55
55
  };
@@ -192,7 +192,7 @@ export interface WorksheetProperties {
192
192
  };
193
193
  defaultRowHeight: number;
194
194
  defaultColWidth?: number;
195
- dyDescent: number;
195
+ dyDescent?: number;
196
196
  showGridLines: boolean;
197
197
  }
198
198
  export type WorksheetState = "visible" | "hidden" | "veryHidden";
@@ -4,7 +4,7 @@ import { BaseXform } from "../base-xform";
4
4
  */
5
5
  interface CacheFieldModel {
6
6
  name: string;
7
- sharedItems: string[] | null;
7
+ sharedItems: any[] | null;
8
8
  containsNumber?: boolean;
9
9
  containsInteger?: boolean;
10
10
  minValue?: number;
@@ -1,11 +1,15 @@
1
1
  interface CacheFieldConfig {
2
2
  name: string;
3
- sharedItems: string[] | null;
3
+ sharedItems: any[] | null;
4
+ minValue?: number;
5
+ maxValue?: number;
4
6
  }
5
7
  declare class CacheField {
6
8
  private name;
7
9
  private sharedItems;
8
- constructor({ name, sharedItems }: CacheFieldConfig);
10
+ private minValue?;
11
+ private maxValue?;
12
+ constructor({ name, sharedItems, minValue, maxValue }: CacheFieldConfig);
9
13
  render(): string;
10
14
  }
11
15
  export { CacheField };
@@ -11,8 +11,6 @@ interface ParsedCacheDefinitionModel {
11
11
  recordCount?: number;
12
12
  rId?: string;
13
13
  refreshOnLoad?: string;
14
- refreshedBy?: string;
15
- refreshedDate?: string;
16
14
  createdVersion?: string;
17
15
  refreshedVersion?: string;
18
16
  minRefreshableVersion?: string;
@@ -57,9 +55,6 @@ declare class PivotCacheDefinitionXform extends BaseXform {
57
55
  static PIVOT_CACHE_DEFINITION_ATTRIBUTES: {
58
56
  xmlns: string;
59
57
  "xmlns:r": string;
60
- "xmlns:mc": string;
61
- "mc:Ignorable": string;
62
- "xmlns:xr": string;
63
58
  };
64
59
  }
65
60
  export { PivotCacheDefinitionXform, type ParsedCacheDefinitionModel };
@@ -114,9 +114,6 @@ declare class PivotTableXform extends BaseXform {
114
114
  reconcile(_model: any, _options: any): void;
115
115
  static PIVOT_TABLE_ATTRIBUTES: {
116
116
  xmlns: string;
117
- "xmlns:mc": string;
118
- "mc:Ignorable": string;
119
- "xmlns:xr": string;
120
117
  };
121
118
  }
122
119
  export { PivotTableXform, type ParsedPivotTableModel };
@@ -1,7 +1,7 @@
1
1
  import { BaseXform } from "../base-xform";
2
2
  interface SheetFormatPropertiesModel {
3
3
  defaultRowHeight: number;
4
- dyDescent: number;
4
+ dyDescent?: number;
5
5
  outlineLevelRow: number;
6
6
  outlineLevelCol: number;
7
7
  defaultColWidth?: number;
@@ -7,8 +7,8 @@ declare class WorkSheetXform extends BaseXform {
7
7
  xmlns: string;
8
8
  "xmlns:r": string;
9
9
  "xmlns:mc": string;
10
- "mc:Ignorable": string;
11
10
  "xmlns:x14ac": string;
11
+ "mc:Ignorable": string;
12
12
  };
13
13
  constructor(options?: any);
14
14
  prepare(model: any, options: any): void;
@@ -23,6 +23,7 @@ interface FontOptions {
23
23
  declare class FontXform extends BaseXform {
24
24
  private options;
25
25
  parser: any;
26
+ private renderOrder;
26
27
  constructor(options?: FontOptions);
27
28
  get tag(): string;
28
29
  render(xmlStream: any, model: FontModel): void;
@@ -28,10 +28,6 @@ declare class TableXform extends BaseXform {
28
28
  reconcile(model: TableModel, options: any): void;
29
29
  static TABLE_ATTRIBUTES: {
30
30
  xmlns: string;
31
- "xmlns:mc": string;
32
- "mc:Ignorable": string;
33
- "xmlns:xr": string;
34
- "xmlns:xr3": string;
35
31
  };
36
32
  }
37
33
  export { TableXform };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cj-tech-master/excelts",
3
- "version": "2.0.1",
3
+ "version": "3.0.0-canary.20251228183403.d3eb98d",
4
4
  "description": "TypeScript Excel Workbook Manager - Read and Write xlsx and csv Files.",
5
5
  "type": "module",
6
6
  "publishConfig": {