@cj-tech-master/excelts 4.0.4 → 4.1.0-canary.20260110032830.e7d8c4e

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 (92) hide show
  1. package/dist/browser/index.browser.d.ts +2 -0
  2. package/dist/browser/index.browser.js +1 -0
  3. package/dist/browser/index.d.ts +2 -0
  4. package/dist/browser/index.js +1 -0
  5. package/dist/browser/modules/excel/cell.js +39 -1
  6. package/dist/browser/modules/excel/enums.d.ts +2 -1
  7. package/dist/browser/modules/excel/enums.js +2 -1
  8. package/dist/browser/modules/excel/form-control.d.ts +157 -0
  9. package/dist/browser/modules/excel/form-control.js +267 -0
  10. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +1 -0
  11. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +19 -1
  12. package/dist/browser/modules/excel/table.d.ts +6 -2
  13. package/dist/browser/modules/excel/table.js +33 -5
  14. package/dist/browser/modules/excel/types.d.ts +5 -1
  15. package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +4 -0
  16. package/dist/browser/modules/excel/utils/ooxml-paths.js +12 -2
  17. package/dist/browser/modules/excel/worksheet.d.ts +32 -0
  18. package/dist/browser/modules/excel/worksheet.js +44 -1
  19. package/dist/browser/modules/excel/xlsx/rel-type.d.ts +2 -0
  20. package/dist/browser/modules/excel/xlsx/rel-type.js +3 -1
  21. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +24 -1
  22. package/dist/browser/modules/excel/xlsx/xform/core/feature-property-bag-xform.d.ts +8 -0
  23. package/dist/browser/modules/excel/xlsx/xform/core/feature-property-bag-xform.js +36 -0
  24. package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +22 -0
  25. package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +52 -0
  26. package/dist/browser/modules/excel/xlsx/xform/drawing/vml-drawing-xform.d.ts +44 -0
  27. package/dist/browser/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +181 -0
  28. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +5 -0
  29. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +24 -1
  30. package/dist/browser/modules/excel/xlsx/xform/style/style-xform.d.ts +2 -0
  31. package/dist/browser/modules/excel/xlsx/xform/style/style-xform.js +11 -0
  32. package/dist/browser/modules/excel/xlsx/xform/style/styles-xform.d.ts +2 -0
  33. package/dist/browser/modules/excel/xlsx/xform/style/styles-xform.js +28 -4
  34. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +3 -0
  35. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +43 -5
  36. package/dist/cjs/index.js +3 -1
  37. package/dist/cjs/modules/excel/cell.js +39 -1
  38. package/dist/cjs/modules/excel/enums.js +2 -1
  39. package/dist/cjs/modules/excel/form-control.js +270 -0
  40. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +19 -1
  41. package/dist/cjs/modules/excel/table.js +33 -5
  42. package/dist/cjs/modules/excel/utils/ooxml-paths.js +14 -2
  43. package/dist/cjs/modules/excel/worksheet.js +44 -1
  44. package/dist/cjs/modules/excel/xlsx/rel-type.js +3 -1
  45. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +23 -0
  46. package/dist/cjs/modules/excel/xlsx/xform/core/feature-property-bag-xform.js +39 -0
  47. package/dist/cjs/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +55 -0
  48. package/dist/cjs/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +184 -0
  49. package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +5 -0
  50. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +23 -0
  51. package/dist/cjs/modules/excel/xlsx/xform/style/style-xform.js +11 -0
  52. package/dist/cjs/modules/excel/xlsx/xform/style/styles-xform.js +28 -4
  53. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +42 -4
  54. package/dist/esm/index.browser.js +1 -0
  55. package/dist/esm/index.js +1 -0
  56. package/dist/esm/modules/excel/cell.js +39 -1
  57. package/dist/esm/modules/excel/enums.js +2 -1
  58. package/dist/esm/modules/excel/form-control.js +267 -0
  59. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +19 -1
  60. package/dist/esm/modules/excel/table.js +33 -5
  61. package/dist/esm/modules/excel/utils/ooxml-paths.js +12 -2
  62. package/dist/esm/modules/excel/worksheet.js +44 -1
  63. package/dist/esm/modules/excel/xlsx/rel-type.js +3 -1
  64. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +24 -1
  65. package/dist/esm/modules/excel/xlsx/xform/core/feature-property-bag-xform.js +36 -0
  66. package/dist/esm/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +52 -0
  67. package/dist/esm/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +181 -0
  68. package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +5 -0
  69. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +24 -1
  70. package/dist/esm/modules/excel/xlsx/xform/style/style-xform.js +11 -0
  71. package/dist/esm/modules/excel/xlsx/xform/style/styles-xform.js +28 -4
  72. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +43 -5
  73. package/dist/iife/excelts.iife.js +629 -40
  74. package/dist/iife/excelts.iife.js.map +1 -1
  75. package/dist/iife/excelts.iife.min.js +30 -30
  76. package/dist/types/index.browser.d.ts +2 -0
  77. package/dist/types/index.d.ts +2 -0
  78. package/dist/types/modules/excel/enums.d.ts +2 -1
  79. package/dist/types/modules/excel/form-control.d.ts +157 -0
  80. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +1 -0
  81. package/dist/types/modules/excel/table.d.ts +6 -2
  82. package/dist/types/modules/excel/types.d.ts +5 -1
  83. package/dist/types/modules/excel/utils/ooxml-paths.d.ts +4 -0
  84. package/dist/types/modules/excel/worksheet.d.ts +32 -0
  85. package/dist/types/modules/excel/xlsx/rel-type.d.ts +2 -0
  86. package/dist/types/modules/excel/xlsx/xform/core/feature-property-bag-xform.d.ts +8 -0
  87. package/dist/types/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +22 -0
  88. package/dist/types/modules/excel/xlsx/xform/drawing/vml-drawing-xform.d.ts +44 -0
  89. package/dist/types/modules/excel/xlsx/xform/style/style-xform.d.ts +2 -0
  90. package/dist/types/modules/excel/xlsx/xform/style/styles-xform.d.ts +2 -0
  91. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +3 -0
  92. package/package.json +9 -9
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @cj-tech-master/excelts v4.0.4
2
+ * @cj-tech-master/excelts v4.1.0-canary.20260110032830.e7d8c4e
3
3
  * TypeScript Excel Workbook Manager - Read and Write xlsx and csv Files.
4
4
  * (c) 2026 cjnoname
5
5
  * Released under the MIT License
@@ -448,6 +448,7 @@ var ExcelTS = (function(exports) {
448
448
  ValueType$1[ValueType$1["Boolean"] = 9] = "Boolean";
449
449
  ValueType$1[ValueType$1["Error"] = 10] = "Error";
450
450
  ValueType$1[ValueType$1["JSON"] = 11] = "JSON";
451
+ ValueType$1[ValueType$1["Checkbox"] = 12] = "Checkbox";
451
452
  return ValueType$1;
452
453
  }({});
453
454
  let FormulaType = /* @__PURE__ */ function(FormulaType$1) {
@@ -1336,6 +1337,40 @@ var ExcelTS = (function(exports) {
1336
1337
  return this.model.value.toString();
1337
1338
  }
1338
1339
  };
1340
+ var CheckboxValue = class {
1341
+ constructor(cell, value) {
1342
+ this.model = {
1343
+ address: cell.address,
1344
+ type: Cell.Types.Checkbox,
1345
+ value: value.checkbox
1346
+ };
1347
+ }
1348
+ get value() {
1349
+ return { checkbox: this.model.value };
1350
+ }
1351
+ set value(value) {
1352
+ this.model.value = value.checkbox;
1353
+ }
1354
+ get type() {
1355
+ return Cell.Types.Checkbox;
1356
+ }
1357
+ get effectiveType() {
1358
+ return Cell.Types.Boolean;
1359
+ }
1360
+ get address() {
1361
+ return this.model.address;
1362
+ }
1363
+ set address(value) {
1364
+ this.model.address = value;
1365
+ }
1366
+ toCsvString() {
1367
+ return this.model.value ? 1 : 0;
1368
+ }
1369
+ release() {}
1370
+ toString() {
1371
+ return this.model.value.toString();
1372
+ }
1373
+ };
1339
1374
  var ErrorValue$1 = class {
1340
1375
  constructor(cell, value) {
1341
1376
  this.model = {
@@ -1414,6 +1449,7 @@ var ExcelTS = (function(exports) {
1414
1449
  if (typeof value === "boolean") return Cell.Types.Boolean;
1415
1450
  if (value instanceof Date) return Cell.Types.Date;
1416
1451
  if (typeof value === "object") {
1452
+ if ("checkbox" in value && typeof value.checkbox === "boolean") return Cell.Types.Checkbox;
1417
1453
  if ("text" in value && value.text && "hyperlink" in value && value.hyperlink) return Cell.Types.Hyperlink;
1418
1454
  if ("formula" in value && value.formula || "sharedFormula" in value && value.sharedFormula) return Cell.Types.Formula;
1419
1455
  if ("richText" in value && value.richText) return Cell.Types.RichText;
@@ -1470,6 +1506,10 @@ var ExcelTS = (function(exports) {
1470
1506
  {
1471
1507
  t: Cell.Types.Error,
1472
1508
  f: ErrorValue$1
1509
+ },
1510
+ {
1511
+ t: Cell.Types.Checkbox,
1512
+ f: CheckboxValue
1473
1513
  }
1474
1514
  ].reduce((p, t) => {
1475
1515
  p[t.t] = t.f;
@@ -2309,6 +2349,19 @@ var ExcelTS = (function(exports) {
2309
2349
  this.worksheet = worksheet;
2310
2350
  if (table) {
2311
2351
  this.table = table;
2352
+ if (Array.isArray(table.rows) && table.rows.length === 0 && table.tableRef) {
2353
+ const decoded = colCache.decode(table.tableRef);
2354
+ if ("dimensions" in decoded) {
2355
+ const startRow = decoded.top + (table.headerRow === false ? 0 : 1);
2356
+ const endRow = decoded.bottom - (table.totalsRow === true ? 1 : 0);
2357
+ if (endRow >= startRow) for (let r = startRow; r <= endRow; r++) {
2358
+ const row = worksheet.getRow(r);
2359
+ const values = [];
2360
+ for (let c = decoded.left; c <= decoded.right; c++) values.push(row.getCell(c).value);
2361
+ table.rows.push(values);
2362
+ }
2363
+ }
2364
+ }
2312
2365
  this.validate();
2313
2366
  this.store();
2314
2367
  }
@@ -2363,8 +2416,8 @@ var ExcelTS = (function(exports) {
2363
2416
  const { row, col } = table.tl;
2364
2417
  assert(row > 0, "Table must be on valid row");
2365
2418
  assert(col > 0, "Table must be on valid col");
2366
- const { width, filterHeight, tableHeight } = this;
2367
- table.autoFilterRef = colCache.encode(row, col, row + filterHeight - 1, col + width - 1);
2419
+ const { width, tableHeight } = this;
2420
+ table.autoFilterRef = colCache.encode(row, col, row, col + width - 1);
2368
2421
  table.tableRef = colCache.encode(row, col, row + tableHeight - 1, col + width - 1);
2369
2422
  table.columns.forEach((column, i) => {
2370
2423
  assert(!!column.name, `Column ${i} must have a name`);
@@ -2491,15 +2544,18 @@ var ExcelTS = (function(exports) {
2491
2544
  }
2492
2545
  }
2493
2546
  this.store();
2547
+ this._cache = void 0;
2494
2548
  }
2495
- addRow(values, rowNumber) {
2549
+ addRow(values, rowNumber, options) {
2496
2550
  this.cacheState();
2497
2551
  if (rowNumber === void 0) this.table.rows.push(values);
2498
2552
  else this.table.rows.splice(rowNumber, 0, values);
2553
+ if (options?.commit !== false) this.commit();
2499
2554
  }
2500
- removeRows(rowIndex, count = 1) {
2555
+ removeRows(rowIndex, count = 1, options) {
2501
2556
  this.cacheState();
2502
2557
  this.table.rows.splice(rowIndex, count);
2558
+ if (options?.commit !== false) this.commit();
2503
2559
  }
2504
2560
  getColumn(colIndex) {
2505
2561
  const column = this.table.columns[colIndex];
@@ -2621,6 +2677,228 @@ var ExcelTS = (function(exports) {
2621
2677
  }
2622
2678
  };
2623
2679
 
2680
+ //#endregion
2681
+ //#region src/modules/excel/form-control.ts
2682
+ /**
2683
+ * Form Control Checkbox - Legacy checkbox control compatible with Office 2007+ and WPS/LibreOffice
2684
+ *
2685
+ * Unlike the modern In-Cell Checkbox (which only works in Microsoft 365),
2686
+ * Form Control Checkboxes are floating controls that work in virtually all
2687
+ * spreadsheet applications.
2688
+ */
2689
+ /** EMU (English Metric Units) to pixels conversion factor at 96 DPI */
2690
+ const EMU_PER_PIXEL = 9525;
2691
+ /** EMU to points conversion factor */
2692
+ const EMU_PER_POINT = 12700;
2693
+ /** Default column offset in EMUs (~15 pixels) */
2694
+ const DEFAULT_COL_OFF = 142875;
2695
+ /** Default row offset in EMUs (~3 pixels) */
2696
+ const DEFAULT_ROW_OFF = 28575;
2697
+ /** Default end column offset in EMUs (~29 pixels) */
2698
+ const DEFAULT_END_COL_OFF = 276225;
2699
+ /** Default end row offset in EMUs (~20 pixels) */
2700
+ const DEFAULT_END_ROW_OFF = 190500;
2701
+ var FormCheckbox = class FormCheckbox {
2702
+ constructor(worksheet, range$1, options) {
2703
+ this.worksheet = worksheet;
2704
+ const { tl, br } = this._parseRange(range$1);
2705
+ const shapeId = 1025 + (worksheet.formControls?.length || 0);
2706
+ let link;
2707
+ if (options?.link) link = this._toAbsoluteRef(options.link);
2708
+ this.model = {
2709
+ shapeId,
2710
+ ctrlPropId: 0,
2711
+ tl,
2712
+ br,
2713
+ link,
2714
+ checked: options?.checked ? "Checked" : "Unchecked",
2715
+ text: options?.text ?? "",
2716
+ noThreeD: options?.noThreeD ?? true,
2717
+ print: options?.print ?? false
2718
+ };
2719
+ }
2720
+ /**
2721
+ * Get the checked state
2722
+ */
2723
+ get checked() {
2724
+ return this.model.checked === "Checked";
2725
+ }
2726
+ /**
2727
+ * Set the checked state
2728
+ */
2729
+ set checked(value) {
2730
+ this.model.checked = value ? "Checked" : "Unchecked";
2731
+ }
2732
+ /**
2733
+ * Get the linked cell address
2734
+ */
2735
+ get link() {
2736
+ return this.model.link;
2737
+ }
2738
+ /**
2739
+ * Set the linked cell address
2740
+ */
2741
+ set link(value) {
2742
+ this.model.link = value ? this._toAbsoluteRef(value) : void 0;
2743
+ }
2744
+ /**
2745
+ * Get the label text
2746
+ */
2747
+ get text() {
2748
+ return this.model.text;
2749
+ }
2750
+ /**
2751
+ * Set the label text
2752
+ */
2753
+ set text(value) {
2754
+ this.model.text = value;
2755
+ }
2756
+ /**
2757
+ * Convert cell reference to absolute format (e.g., "A1" -> "$A$1")
2758
+ */
2759
+ _toAbsoluteRef(ref) {
2760
+ if (ref.includes("$")) return ref;
2761
+ const addr = colCache.decodeAddress(ref);
2762
+ return `$${colCache.n2l(addr.col)}$${addr.row}`;
2763
+ }
2764
+ /**
2765
+ * Parse range input into anchor positions
2766
+ */
2767
+ _parseRange(range$1) {
2768
+ let tl;
2769
+ let br;
2770
+ if (typeof range$1 === "string") {
2771
+ const decoded = colCache.decode(range$1);
2772
+ if ("top" in decoded) {
2773
+ tl = {
2774
+ col: decoded.left - 1,
2775
+ colOff: DEFAULT_COL_OFF,
2776
+ row: decoded.top - 1,
2777
+ rowOff: DEFAULT_ROW_OFF
2778
+ };
2779
+ br = {
2780
+ col: decoded.right - 1,
2781
+ colOff: DEFAULT_END_COL_OFF,
2782
+ row: decoded.bottom - 1,
2783
+ rowOff: DEFAULT_END_ROW_OFF
2784
+ };
2785
+ } else {
2786
+ tl = {
2787
+ col: decoded.col - 1,
2788
+ colOff: DEFAULT_COL_OFF,
2789
+ row: decoded.row - 1,
2790
+ rowOff: DEFAULT_ROW_OFF
2791
+ };
2792
+ br = {
2793
+ col: decoded.col + 1,
2794
+ colOff: DEFAULT_END_COL_OFF,
2795
+ row: decoded.row,
2796
+ rowOff: DEFAULT_END_ROW_OFF
2797
+ };
2798
+ }
2799
+ } else if ("startCol" in range$1) {
2800
+ tl = {
2801
+ col: range$1.startCol,
2802
+ colOff: range$1.startColOff ?? DEFAULT_COL_OFF,
2803
+ row: range$1.startRow,
2804
+ rowOff: range$1.startRowOff ?? DEFAULT_ROW_OFF
2805
+ };
2806
+ br = {
2807
+ col: range$1.endCol,
2808
+ colOff: range$1.endColOff ?? DEFAULT_END_COL_OFF,
2809
+ row: range$1.endRow,
2810
+ rowOff: range$1.endRowOff ?? DEFAULT_END_ROW_OFF
2811
+ };
2812
+ } else {
2813
+ if (typeof range$1.tl === "string") {
2814
+ const decoded = colCache.decodeAddress(range$1.tl);
2815
+ tl = {
2816
+ col: decoded.col - 1,
2817
+ colOff: DEFAULT_COL_OFF,
2818
+ row: decoded.row - 1,
2819
+ rowOff: DEFAULT_ROW_OFF
2820
+ };
2821
+ } else tl = {
2822
+ col: range$1.tl.col,
2823
+ colOff: range$1.tl.colOff ?? DEFAULT_COL_OFF,
2824
+ row: range$1.tl.row,
2825
+ rowOff: range$1.tl.rowOff ?? DEFAULT_ROW_OFF
2826
+ };
2827
+ if (range$1.br) if (typeof range$1.br === "string") {
2828
+ const decoded = colCache.decodeAddress(range$1.br);
2829
+ br = {
2830
+ col: decoded.col - 1,
2831
+ colOff: DEFAULT_END_COL_OFF,
2832
+ row: decoded.row - 1,
2833
+ rowOff: DEFAULT_END_ROW_OFF
2834
+ };
2835
+ } else br = {
2836
+ col: range$1.br.col,
2837
+ colOff: range$1.br.colOff ?? DEFAULT_END_COL_OFF,
2838
+ row: range$1.br.row,
2839
+ rowOff: range$1.br.rowOff ?? DEFAULT_END_ROW_OFF
2840
+ };
2841
+ else br = {
2842
+ col: tl.col + 2,
2843
+ colOff: DEFAULT_END_COL_OFF,
2844
+ row: tl.row + 1,
2845
+ rowOff: DEFAULT_END_ROW_OFF
2846
+ };
2847
+ }
2848
+ return {
2849
+ tl,
2850
+ br
2851
+ };
2852
+ }
2853
+ /**
2854
+ * Convert anchor to VML anchor string format
2855
+ * Format: "fromCol, fromColOff, fromRow, fromRowOff, toCol, toColOff, toRow, toRowOff"
2856
+ * VML uses pixels for offsets
2857
+ */
2858
+ getVmlAnchor() {
2859
+ return FormCheckbox.getVmlAnchor(this.model);
2860
+ }
2861
+ /**
2862
+ * Get VML style string for positioning
2863
+ */
2864
+ getVmlStyle() {
2865
+ return FormCheckbox.getVmlStyle(this.model);
2866
+ }
2867
+ /**
2868
+ * Get the numeric checked value for VML (0, 1, or 2)
2869
+ */
2870
+ getVmlCheckedValue() {
2871
+ return FormCheckbox.getVmlCheckedValue(this.model);
2872
+ }
2873
+ /**
2874
+ * Convert anchor to VML anchor string format from model
2875
+ */
2876
+ static getVmlAnchor(model) {
2877
+ const { tl, br } = model;
2878
+ const tlColOff = Math.round(tl.colOff / EMU_PER_PIXEL);
2879
+ const tlRowOff = Math.round(tl.rowOff / EMU_PER_PIXEL);
2880
+ const brColOff = Math.round(br.colOff / EMU_PER_PIXEL);
2881
+ const brRowOff = Math.round(br.rowOff / EMU_PER_PIXEL);
2882
+ return `${tl.col}, ${tlColOff}, ${tl.row}, ${tlRowOff}, ${br.col}, ${brColOff}, ${br.row}, ${brRowOff}`;
2883
+ }
2884
+ /**
2885
+ * Get VML style string for positioning from model
2886
+ */
2887
+ static getVmlStyle(model) {
2888
+ return `position:absolute;margin-left:${Math.round(model.tl.colOff / EMU_PER_POINT)}pt;margin-top:${Math.round(model.tl.rowOff / EMU_PER_POINT)}pt;width:96pt;height:18pt;z-index:1;visibility:visible`;
2889
+ }
2890
+ /**
2891
+ * Get the numeric checked value for VML from model (0, 1, or 2)
2892
+ */
2893
+ static getVmlCheckedValue(model) {
2894
+ switch (model.checked) {
2895
+ case "Checked": return 1;
2896
+ case "Mixed": return 2;
2897
+ default: return 0;
2898
+ }
2899
+ }
2900
+ };
2901
+
2624
2902
  //#endregion
2625
2903
  //#region src/utils/env.ts
2626
2904
  /**
@@ -5024,6 +5302,7 @@ var ExcelTS = (function(exports) {
5024
5302
  this.tables = {};
5025
5303
  this.pivotTables = [];
5026
5304
  this.conditionalFormattings = [];
5305
+ this.formControls = [];
5027
5306
  }
5028
5307
  get name() {
5029
5308
  return this._name;
@@ -5496,6 +5775,41 @@ var ExcelTS = (function(exports) {
5496
5775
  return image && image.imageId;
5497
5776
  }
5498
5777
  /**
5778
+ * Add a form control checkbox to the worksheet.
5779
+ *
5780
+ * Form control checkboxes are the legacy style that work in Office 2007+,
5781
+ * WPS Office, LibreOffice, and other spreadsheet applications.
5782
+ *
5783
+ * Unlike modern in-cell checkboxes (which only work in Microsoft 365),
5784
+ * form control checkboxes are floating controls positioned over cells.
5785
+ *
5786
+ * @param range - Cell reference (e.g., "B2") or range (e.g., "B2:D3") for positioning
5787
+ * @param options - Checkbox options
5788
+ * @returns The created FormCheckbox instance
5789
+ *
5790
+ * @example
5791
+ * // Simple checkbox at B2
5792
+ * ws.addFormCheckbox("B2");
5793
+ *
5794
+ * // Checkbox with label and linked cell
5795
+ * ws.addFormCheckbox("B2:D3", {
5796
+ * text: "Accept terms",
5797
+ * link: "A2",
5798
+ * checked: false
5799
+ * });
5800
+ */
5801
+ addFormCheckbox(range$1, options) {
5802
+ const checkbox = new FormCheckbox(this, range$1, options);
5803
+ this.formControls.push(checkbox);
5804
+ return checkbox;
5805
+ }
5806
+ /**
5807
+ * Get all form control checkboxes in the worksheet
5808
+ */
5809
+ getFormCheckboxes() {
5810
+ return this.formControls;
5811
+ }
5812
+ /**
5499
5813
  * Protect the worksheet with optional password and options
5500
5814
  */
5501
5815
  async protect(password, options) {
@@ -5578,7 +5892,8 @@ var ExcelTS = (function(exports) {
5578
5892
  sheetProtection: this.sheetProtection,
5579
5893
  tables: Object.values(this.tables).map((table) => table.model),
5580
5894
  pivotTables: this.pivotTables,
5581
- conditionalFormattings: this.conditionalFormattings
5895
+ conditionalFormattings: this.conditionalFormattings,
5896
+ formControls: this.formControls.map((fc) => fc.model)
5582
5897
  };
5583
5898
  model.cols = Column.toModel(this.columns || []);
5584
5899
  const rows = model.rows = [];
@@ -5632,6 +5947,7 @@ var ExcelTS = (function(exports) {
5632
5947
  }, {});
5633
5948
  this.pivotTables = value.pivotTables;
5634
5949
  this.conditionalFormattings = value.conditionalFormattings;
5950
+ this.formControls = [];
5635
5951
  }
5636
5952
  };
5637
5953
 
@@ -8329,6 +8645,16 @@ var ExcelTS = (function(exports) {
8329
8645
  */
8330
8646
  if (model.alignment) this.map.alignment.render(xmlStream, model.alignment);
8331
8647
  if (model.protection) this.map.protection.render(xmlStream, model.protection);
8648
+ if (model.checkbox && model.xfComplementIndex !== void 0) {
8649
+ xmlStream.openNode("extLst");
8650
+ xmlStream.openNode("ext", {
8651
+ "xmlns:xfpb": "http://schemas.microsoft.com/office/spreadsheetml/2022/featurepropertybag",
8652
+ uri: "{C7286773-470A-42A8-94C5-96B5CB345126}"
8653
+ });
8654
+ xmlStream.leafNode("xfpb:xfComplement", { i: model.xfComplementIndex });
8655
+ xmlStream.closeNode();
8656
+ xmlStream.closeNode();
8657
+ }
8332
8658
  xmlStream.closeNode();
8333
8659
  }
8334
8660
  parseOpen(node) {
@@ -8536,6 +8862,7 @@ var ExcelTS = (function(exports) {
8536
8862
  pattern: "gray125"
8537
8863
  });
8538
8864
  this.weakMap = /* @__PURE__ */ new WeakMap();
8865
+ this._hasCheckboxes = false;
8539
8866
  }
8540
8867
  render(xmlStream, model) {
8541
8868
  const renderModel = model || this.model;
@@ -8665,9 +8992,9 @@ var ExcelTS = (function(exports) {
8665
8992
  family: 2,
8666
8993
  scheme: "minor"
8667
8994
  });
8668
- if (this.weakMap && this.weakMap.has(model)) return this.weakMap.get(model);
8669
- const style = {};
8670
8995
  const type = cellType || Enums.ValueType.Number;
8996
+ if (type !== Enums.ValueType.Checkbox && this.weakMap && this.weakMap.has(model)) return this.weakMap.get(model);
8997
+ const style = {};
8671
8998
  if (model.numFmt) style.numFmtId = this._addNumFmtStr(model.numFmt);
8672
8999
  else switch (type) {
8673
9000
  case Enums.ValueType.Number:
@@ -8683,8 +9010,14 @@ var ExcelTS = (function(exports) {
8683
9010
  if (model.fill) style.fillId = this._addFill(model.fill);
8684
9011
  if (model.alignment) style.alignment = model.alignment;
8685
9012
  if (model.protection) style.protection = model.protection;
9013
+ if (type === Enums.ValueType.Checkbox) {
9014
+ this._hasCheckboxes = true;
9015
+ style.alignment = style.alignment || {};
9016
+ style.checkbox = true;
9017
+ style.xfComplementIndex = 0;
9018
+ }
8686
9019
  const styleId = this._addStyle(style);
8687
- if (this.weakMap) this.weakMap.set(model, styleId);
9020
+ if (type !== Enums.ValueType.Checkbox && this.weakMap) this.weakMap.set(model, styleId);
8688
9021
  return styleId;
8689
9022
  }
8690
9023
  getStyleModel(id) {
@@ -8718,6 +9051,9 @@ var ExcelTS = (function(exports) {
8718
9051
  getDxfStyle(id) {
8719
9052
  return this.model.dxfs[id];
8720
9053
  }
9054
+ get hasCheckboxes() {
9055
+ return !!this._hasCheckboxes;
9056
+ }
8721
9057
  _addStyle(style) {
8722
9058
  const xml = this.map.style.toXml(style);
8723
9059
  let index = this.index.style[xml];
@@ -8864,10 +9200,14 @@ var ExcelTS = (function(exports) {
8864
9200
  }
8865
9201
  addStyleModel(model, cellType) {
8866
9202
  switch (cellType) {
9203
+ case Enums.ValueType.Checkbox: throw new Error("Checkbox cells require styles to be enabled (useStyles: true)");
8867
9204
  case Enums.ValueType.Date: return this.dateStyleId;
8868
9205
  default: return 0;
8869
9206
  }
8870
9207
  }
9208
+ get hasCheckboxes() {
9209
+ return false;
9210
+ }
8871
9211
  get dateStyleId() {
8872
9212
  if (!this._dateStyleId) {
8873
9213
  const dateStyle = { numFmtId: NumFmtXform.getDefaultFmtId("mm-dd-yy") };
@@ -9476,7 +9816,8 @@ var ExcelTS = (function(exports) {
9476
9816
  xlWorkbookRels: "xl/_rels/workbook.xml.rels",
9477
9817
  xlSharedStrings: "xl/sharedStrings.xml",
9478
9818
  xlStyles: "xl/styles.xml",
9479
- xlTheme1: "xl/theme/theme1.xml"
9819
+ xlTheme1: "xl/theme/theme1.xml",
9820
+ xlFeaturePropertyBag: "xl/featurePropertyBag/featurePropertyBag.xml"
9480
9821
  };
9481
9822
  const worksheetXmlRegex = /^xl\/worksheets\/sheet(\d+)[.]xml$/;
9482
9823
  const worksheetRelsXmlRegex = /^xl\/worksheets\/_rels\/sheet(\d+)[.]xml[.]rels$/;
@@ -9622,7 +9963,8 @@ var ExcelTS = (function(exports) {
9622
9963
  const OOXML_REL_TARGETS = {
9623
9964
  workbookStyles: "styles.xml",
9624
9965
  workbookSharedStrings: "sharedStrings.xml",
9625
- workbookTheme1: "theme/theme1.xml"
9966
+ workbookTheme1: "theme/theme1.xml",
9967
+ workbookFeaturePropertyBag: "featurePropertyBag/featurePropertyBag.xml"
9626
9968
  };
9627
9969
  function pivotCacheDefinitionRelTargetFromWorkbook(n) {
9628
9970
  return `pivotCache/pivotCacheDefinition${n}.xml`;
@@ -9657,6 +9999,12 @@ var ExcelTS = (function(exports) {
9657
9999
  function mediaRelTargetFromRels(filename) {
9658
10000
  return `../media/${filename}`;
9659
10001
  }
10002
+ function ctrlPropPath(id) {
10003
+ return `xl/ctrlProps/ctrlProp${id}.xml`;
10004
+ }
10005
+ function ctrlPropRelTargetFromWorksheet(id) {
10006
+ return `../ctrlProps/ctrlProp${id}.xml`;
10007
+ }
9660
10008
 
9661
10009
  //#endregion
9662
10010
  //#region src/modules/excel/xlsx/xform/core/content-types-xform.ts
@@ -9719,6 +10067,10 @@ var ExcelTS = (function(exports) {
9719
10067
  PartName: toContentTypesPartName(OOXML_PATHS.xlStyles),
9720
10068
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"
9721
10069
  });
10070
+ if (model.hasCheckboxes) xmlStream.leafNode("Override", {
10071
+ PartName: toContentTypesPartName(OOXML_PATHS.xlFeaturePropertyBag),
10072
+ ContentType: "application/vnd.ms-excel.featurepropertybag+xml"
10073
+ });
9722
10074
  if (model.sharedStrings && model.sharedStrings.count) xmlStream.leafNode("Override", {
9723
10075
  PartName: toContentTypesPartName(OOXML_PATHS.xlSharedStrings),
9724
10076
  ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"
@@ -9747,6 +10099,16 @@ var ExcelTS = (function(exports) {
9747
10099
  });
9748
10100
  });
9749
10101
  }
10102
+ if (model.formControlRefs) {
10103
+ if (!model.commentRefs) xmlStream.leafNode("Default", {
10104
+ Extension: "vml",
10105
+ ContentType: "application/vnd.openxmlformats-officedocument.vmlDrawing"
10106
+ });
10107
+ for (const ctrlPropId of model.formControlRefs) xmlStream.leafNode("Override", {
10108
+ PartName: toContentTypesPartName(ctrlPropPath(ctrlPropId)),
10109
+ ContentType: "application/vnd.ms-excel.controlproperties+xml"
10110
+ });
10111
+ }
9750
10112
  xmlStream.leafNode("Override", {
9751
10113
  PartName: toContentTypesPartName(OOXML_PATHS.docPropsCore),
9752
10114
  ContentType: "application/vnd.openxmlformats-package.core-properties+xml"
@@ -10327,7 +10689,9 @@ var ExcelTS = (function(exports) {
10327
10689
  Table: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table",
10328
10690
  PivotCacheDefinition: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition",
10329
10691
  PivotCacheRecords: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheRecords",
10330
- PivotTable: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable"
10692
+ PivotTable: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable",
10693
+ FeaturePropertyBag: "http://schemas.microsoft.com/office/2022/11/relationships/FeaturePropertyBag",
10694
+ CtrlProp: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp"
10331
10695
  };
10332
10696
 
10333
10697
  //#endregion
@@ -10506,6 +10870,10 @@ var ExcelTS = (function(exports) {
10506
10870
  xmlStream.addAttribute("t", "b");
10507
10871
  xmlStream.leafNode("v", null, model.value ? "1" : "0");
10508
10872
  break;
10873
+ case Enums.ValueType.Checkbox:
10874
+ xmlStream.addAttribute("t", "b");
10875
+ xmlStream.leafNode("v", null, model.value ? "1" : "0");
10876
+ break;
10509
10877
  case Enums.ValueType.Error:
10510
10878
  xmlStream.addAttribute("t", "e");
10511
10879
  xmlStream.leafNode("v", null, model.value.error);
@@ -13248,6 +13616,23 @@ var ExcelTS = (function(exports) {
13248
13616
  Target: pivotTableRelTargetFromWorksheet(pivotTable.tableNumber)
13249
13617
  });
13250
13618
  });
13619
+ if (model.formControls && model.formControls.length > 0) {
13620
+ if (model.comments.length === 0) rels.push({
13621
+ Id: nextRid(rels),
13622
+ Type: RelType.VmlDrawing,
13623
+ Target: vmlDrawingRelTargetFromWorksheet(model.id)
13624
+ });
13625
+ for (const control of model.formControls) {
13626
+ const globalCtrlPropId = options.formControlRefs.length + 1;
13627
+ control.ctrlPropId = globalCtrlPropId;
13628
+ rels.push({
13629
+ Id: nextRid(rels),
13630
+ Type: RelType.CtrlProp,
13631
+ Target: ctrlPropRelTargetFromWorksheet(globalCtrlPropId)
13632
+ });
13633
+ options.formControlRefs.push(globalCtrlPropId);
13634
+ }
13635
+ }
13251
13636
  this.map.extLst.prepare(model, options);
13252
13637
  }
13253
13638
  render(xmlStream, model) {
@@ -13433,6 +13818,42 @@ var ExcelTS = (function(exports) {
13433
13818
  }
13434
13819
  };
13435
13820
 
13821
+ //#endregion
13822
+ //#region src/modules/excel/xlsx/xform/core/feature-property-bag-xform.ts
13823
+ var FeaturePropertyBagXform = class extends BaseXform {
13824
+ render(xmlStream) {
13825
+ xmlStream.openXml({
13826
+ version: "1.0",
13827
+ encoding: "UTF-8",
13828
+ standalone: "yes"
13829
+ });
13830
+ xmlStream.openNode("FeaturePropertyBags", { xmlns: "http://schemas.microsoft.com/office/spreadsheetml/2022/featurepropertybag" });
13831
+ xmlStream.leafNode("bag", { type: "Checkbox" });
13832
+ xmlStream.openNode("bag", { type: "XFControls" });
13833
+ xmlStream.leafNode("bagId", { k: "CellControl" }, "0");
13834
+ xmlStream.closeNode();
13835
+ xmlStream.openNode("bag", { type: "XFComplement" });
13836
+ xmlStream.leafNode("bagId", { k: "XFControls" }, "1");
13837
+ xmlStream.closeNode();
13838
+ xmlStream.openNode("bag", {
13839
+ type: "XFComplements",
13840
+ extRef: "XFComplementsMapperExtRef"
13841
+ });
13842
+ xmlStream.openNode("a", { k: "MappedFeaturePropertyBags" });
13843
+ xmlStream.leafNode("bagId", {}, "2");
13844
+ xmlStream.closeNode();
13845
+ xmlStream.closeNode();
13846
+ xmlStream.closeNode();
13847
+ }
13848
+ parseOpen() {
13849
+ return false;
13850
+ }
13851
+ parseText() {}
13852
+ parseClose() {
13853
+ return false;
13854
+ }
13855
+ };
13856
+
13436
13857
  //#endregion
13437
13858
  //#region src/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.ts
13438
13859
  var BaseCellAnchorXform = class extends BaseXform {
@@ -15913,41 +16334,125 @@ var ExcelTS = (function(exports) {
15913
16334
  };
15914
16335
 
15915
16336
  //#endregion
15916
- //#region src/modules/excel/xlsx/xform/comment/vml-notes-xform.ts
15917
- var VmlNotesXform = class VmlNotesXform extends BaseXform {
16337
+ //#region src/modules/excel/xlsx/xform/drawing/vml-drawing-xform.ts
16338
+ var VmlDrawingXform = class VmlDrawingXform extends BaseXform {
15918
16339
  constructor() {
15919
16340
  super();
15920
16341
  this.map = { "v:shape": new VmlShapeXform() };
15921
- this.model = { comments: [] };
16342
+ this.model = {
16343
+ comments: [],
16344
+ formControls: []
16345
+ };
15922
16346
  }
15923
16347
  get tag() {
15924
16348
  return "xml";
15925
16349
  }
16350
+ /**
16351
+ * Render VML drawing containing both notes and form controls
16352
+ */
15926
16353
  render(xmlStream, model) {
15927
16354
  const renderModel = model || this.model;
16355
+ const hasComments = renderModel.comments && renderModel.comments.length > 0;
16356
+ const hasFormControls = renderModel.formControls && renderModel.formControls.length > 0;
15928
16357
  xmlStream.openXml(XmlStream.StdDocAttributes);
15929
- xmlStream.openNode(this.tag, VmlNotesXform.DRAWING_ATTRIBUTES);
16358
+ xmlStream.openNode(this.tag, VmlDrawingXform.DRAWING_ATTRIBUTES);
15930
16359
  xmlStream.openNode("o:shapelayout", { "v:ext": "edit" });
15931
16360
  xmlStream.leafNode("o:idmap", {
15932
16361
  "v:ext": "edit",
15933
16362
  data: 1
15934
16363
  });
15935
16364
  xmlStream.closeNode();
15936
- xmlStream.openNode("v:shapetype", {
15937
- id: "_x0000_t202",
15938
- coordsize: "21600,21600",
15939
- "o:spt": 202,
15940
- path: "m,l,21600r21600,l21600,xe"
15941
- });
15942
- xmlStream.leafNode("v:stroke", { joinstyle: "miter" });
15943
- xmlStream.leafNode("v:path", {
15944
- gradientshapeok: "t",
15945
- "o:connecttype": "rect"
15946
- });
16365
+ if (hasComments) {
16366
+ xmlStream.openNode("v:shapetype", {
16367
+ id: "_x0000_t202",
16368
+ coordsize: "21600,21600",
16369
+ "o:spt": 202,
16370
+ path: "m,l,21600r21600,l21600,xe"
16371
+ });
16372
+ xmlStream.leafNode("v:stroke", { joinstyle: "miter" });
16373
+ xmlStream.leafNode("v:path", {
16374
+ gradientshapeok: "t",
16375
+ "o:connecttype": "rect"
16376
+ });
16377
+ xmlStream.closeNode();
16378
+ }
16379
+ if (hasFormControls) {
16380
+ xmlStream.openNode("v:shapetype", {
16381
+ id: "_x0000_t201",
16382
+ coordsize: "21600,21600",
16383
+ "o:spt": "201",
16384
+ path: "m,l,21600r21600,l21600,xe"
16385
+ });
16386
+ xmlStream.leafNode("v:stroke", { joinstyle: "miter" });
16387
+ xmlStream.leafNode("v:path", {
16388
+ shadowok: "f",
16389
+ "o:extrusionok": "f",
16390
+ strokeok: "f",
16391
+ fillok: "f",
16392
+ "o:connecttype": "rect"
16393
+ });
16394
+ xmlStream.leafNode("o:lock", {
16395
+ "v:ext": "edit",
16396
+ shapetype: "t"
16397
+ });
16398
+ xmlStream.closeNode();
16399
+ }
16400
+ if (hasComments) {
16401
+ const comments = renderModel.comments;
16402
+ for (let i = 0; i < comments.length; i++) this.map["v:shape"].render(xmlStream, comments[i], i);
16403
+ }
16404
+ if (hasFormControls) for (const control of renderModel.formControls) this._renderCheckboxShape(xmlStream, control);
15947
16405
  xmlStream.closeNode();
15948
- renderModel.comments.forEach((item, index) => {
15949
- this.map["v:shape"].render(xmlStream, item, index);
16406
+ }
16407
+ /**
16408
+ * Render a checkbox form control shape
16409
+ */
16410
+ _renderCheckboxShape(xmlStream, control) {
16411
+ const shapeAttrs = {
16412
+ id: `_x0000_s${control.shapeId}`,
16413
+ type: "#_x0000_t201",
16414
+ style: FormCheckbox.getVmlStyle(control),
16415
+ "o:insetmode": "auto",
16416
+ fillcolor: "buttonFace [67]",
16417
+ strokecolor: "windowText [64]",
16418
+ "o:preferrelative": "t",
16419
+ filled: "f",
16420
+ stroked: "f"
16421
+ };
16422
+ xmlStream.openNode("v:shape", shapeAttrs);
16423
+ xmlStream.leafNode("v:fill", { "o:detectmouseclick": "t" });
16424
+ xmlStream.leafNode("o:lock", {
16425
+ "v:ext": "edit",
16426
+ text: "t"
15950
16427
  });
16428
+ if (control.text) {
16429
+ xmlStream.openNode("v:textbox", {
16430
+ style: "mso-direction-alt:auto",
16431
+ "o:singleclick": "t"
16432
+ });
16433
+ xmlStream.openNode("div", { style: "text-align:left" });
16434
+ xmlStream.openNode("font", {
16435
+ face: "Tahoma",
16436
+ size: "160",
16437
+ color: "auto"
16438
+ });
16439
+ xmlStream.writeText(control.text);
16440
+ xmlStream.closeNode();
16441
+ xmlStream.closeNode();
16442
+ xmlStream.closeNode();
16443
+ }
16444
+ xmlStream.openNode("x:ClientData", { ObjectType: "Checkbox" });
16445
+ xmlStream.openNode("x:Anchor");
16446
+ xmlStream.writeText(FormCheckbox.getVmlAnchor(control));
16447
+ xmlStream.closeNode();
16448
+ xmlStream.leafNode("x:PrintObject", void 0, control.print ? "True" : "False");
16449
+ xmlStream.leafNode("x:AutoFill", void 0, "False");
16450
+ xmlStream.leafNode("x:AutoLine", void 0, "False");
16451
+ xmlStream.leafNode("x:TextVAlign", void 0, "Center");
16452
+ if (control.link) xmlStream.leafNode("x:FmlaLink", void 0, control.link);
16453
+ if (control.noThreeD) xmlStream.leafNode("x:NoThreeD");
16454
+ xmlStream.leafNode("x:Checked", void 0, String(FormCheckbox.getVmlCheckedValue(control)));
16455
+ xmlStream.closeNode();
15951
16456
  xmlStream.closeNode();
15952
16457
  }
15953
16458
  parseOpen(node) {
@@ -15958,7 +16463,10 @@ var ExcelTS = (function(exports) {
15958
16463
  switch (node.name) {
15959
16464
  case this.tag:
15960
16465
  this.reset();
15961
- this.model = { comments: [] };
16466
+ this.model = {
16467
+ comments: [],
16468
+ formControls: []
16469
+ };
15962
16470
  break;
15963
16471
  default:
15964
16472
  this.parser = this.map[node.name];
@@ -15983,12 +16491,6 @@ var ExcelTS = (function(exports) {
15983
16491
  default: return true;
15984
16492
  }
15985
16493
  }
15986
- reconcile(model, options) {
15987
- model.anchors.forEach((anchor) => {
15988
- if (anchor.br) this.map["xdr:twoCellAnchor"].reconcile(anchor, options);
15989
- else this.map["xdr:oneCellAnchor"].reconcile(anchor, options);
15990
- });
15991
- }
15992
16494
  static {
15993
16495
  this.DRAWING_ATTRIBUTES = {
15994
16496
  "xmlns:v": "urn:schemas-microsoft-com:vml",
@@ -15998,6 +16500,53 @@ var ExcelTS = (function(exports) {
15998
16500
  }
15999
16501
  };
16000
16502
 
16503
+ //#endregion
16504
+ //#region src/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.ts
16505
+ /**
16506
+ * Control Properties Xform - Generates ctrlProp*.xml for form controls
16507
+ *
16508
+ * Each form control (checkbox, button, etc.) has an associated ctrlProp file
16509
+ * that stores its properties like objectType, checked state, and linked cell.
16510
+ */
16511
+ var CtrlPropXform = class extends BaseXform {
16512
+ get tag() {
16513
+ return "formControlPr";
16514
+ }
16515
+ render(xmlStream, model) {
16516
+ const renderModel = model || this.model;
16517
+ const attrs = {
16518
+ xmlns: "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main",
16519
+ objectType: "CheckBox",
16520
+ checked: renderModel.checked,
16521
+ lockText: "1"
16522
+ };
16523
+ if (renderModel.link) attrs.fmlaLink = renderModel.link;
16524
+ if (renderModel.noThreeD) attrs.noThreeD = "1";
16525
+ xmlStream.openXml({
16526
+ version: "1.0",
16527
+ encoding: "UTF-8",
16528
+ standalone: "yes"
16529
+ });
16530
+ xmlStream.leafNode(this.tag, attrs);
16531
+ }
16532
+ /**
16533
+ * Generate XML string directly (convenience method)
16534
+ * Uses render() internally to ensure consistency
16535
+ */
16536
+ toXml(model) {
16537
+ const xmlStream = new XmlStream();
16538
+ this.render(xmlStream, model);
16539
+ return xmlStream.xml;
16540
+ }
16541
+ parseOpen() {
16542
+ return true;
16543
+ }
16544
+ parseText() {}
16545
+ parseClose() {
16546
+ return false;
16547
+ }
16548
+ };
16549
+
16001
16550
  //#endregion
16002
16551
  //#region src/modules/excel/xlsx/xml/theme1.ts
16003
16552
  const theme1Xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" name=\"Office Theme\"> <a:themeElements> <a:clrScheme name=\"Office\"> <a:dk1> <a:sysClr val=\"windowText\" lastClr=\"000000\"/> </a:dk1> <a:lt1> <a:sysClr val=\"window\" lastClr=\"FFFFFF\"/> </a:lt1> <a:dk2> <a:srgbClr val=\"1F497D\"/> </a:dk2> <a:lt2> <a:srgbClr val=\"EEECE1\"/> </a:lt2> <a:accent1> <a:srgbClr val=\"4F81BD\"/> </a:accent1> <a:accent2> <a:srgbClr val=\"C0504D\"/> </a:accent2> <a:accent3> <a:srgbClr val=\"9BBB59\"/> </a:accent3> <a:accent4> <a:srgbClr val=\"8064A2\"/> </a:accent4> <a:accent5> <a:srgbClr val=\"4BACC6\"/> </a:accent5> <a:accent6> <a:srgbClr val=\"F79646\"/> </a:accent6> <a:hlink> <a:srgbClr val=\"0000FF\"/> </a:hlink> <a:folHlink> <a:srgbClr val=\"800080\"/> </a:folHlink> </a:clrScheme> <a:fontScheme name=\"Office\"> <a:majorFont> <a:latin typeface=\"Cambria\"/> <a:ea typeface=\"\"/> <a:cs typeface=\"\"/> <a:font script=\"Jpan\" typeface=\"MS Pゴシック\"/> <a:font script=\"Hang\" typeface=\"맑은 고딕\"/> <a:font script=\"Hans\" typeface=\"宋体\"/> <a:font script=\"Hant\" typeface=\"新細明體\"/> <a:font script=\"Arab\" typeface=\"Times New Roman\"/> <a:font script=\"Hebr\" typeface=\"Times New Roman\"/> <a:font script=\"Thai\" typeface=\"Tahoma\"/> <a:font script=\"Ethi\" typeface=\"Nyala\"/> <a:font script=\"Beng\" typeface=\"Vrinda\"/> <a:font script=\"Gujr\" typeface=\"Shruti\"/> <a:font script=\"Khmr\" typeface=\"MoolBoran\"/> <a:font script=\"Knda\" typeface=\"Tunga\"/> <a:font script=\"Guru\" typeface=\"Raavi\"/> <a:font script=\"Cans\" typeface=\"Euphemia\"/> <a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/> <a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/> <a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/> <a:font script=\"Thaa\" typeface=\"MV Boli\"/> <a:font script=\"Deva\" typeface=\"Mangal\"/> <a:font script=\"Telu\" typeface=\"Gautami\"/> <a:font script=\"Taml\" typeface=\"Latha\"/> <a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/> <a:font script=\"Orya\" typeface=\"Kalinga\"/> <a:font script=\"Mlym\" typeface=\"Kartika\"/> <a:font script=\"Laoo\" typeface=\"DokChampa\"/> <a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/> <a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/> <a:font script=\"Viet\" typeface=\"Times New Roman\"/> <a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/> <a:font script=\"Geor\" typeface=\"Sylfaen\"/> </a:majorFont> <a:minorFont> <a:latin typeface=\"Calibri\"/> <a:ea typeface=\"\"/> <a:cs typeface=\"\"/> <a:font script=\"Jpan\" typeface=\"MS Pゴシック\"/> <a:font script=\"Hang\" typeface=\"맑은 고딕\"/> <a:font script=\"Hans\" typeface=\"宋体\"/> <a:font script=\"Hant\" typeface=\"新細明體\"/> <a:font script=\"Arab\" typeface=\"Arial\"/> <a:font script=\"Hebr\" typeface=\"Arial\"/> <a:font script=\"Thai\" typeface=\"Tahoma\"/> <a:font script=\"Ethi\" typeface=\"Nyala\"/> <a:font script=\"Beng\" typeface=\"Vrinda\"/> <a:font script=\"Gujr\" typeface=\"Shruti\"/> <a:font script=\"Khmr\" typeface=\"DaunPenh\"/> <a:font script=\"Knda\" typeface=\"Tunga\"/> <a:font script=\"Guru\" typeface=\"Raavi\"/> <a:font script=\"Cans\" typeface=\"Euphemia\"/> <a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/> <a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/> <a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/> <a:font script=\"Thaa\" typeface=\"MV Boli\"/> <a:font script=\"Deva\" typeface=\"Mangal\"/> <a:font script=\"Telu\" typeface=\"Gautami\"/> <a:font script=\"Taml\" typeface=\"Latha\"/> <a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/> <a:font script=\"Orya\" typeface=\"Kalinga\"/> <a:font script=\"Mlym\" typeface=\"Kartika\"/> <a:font script=\"Laoo\" typeface=\"DokChampa\"/> <a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/> <a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/> <a:font script=\"Viet\" typeface=\"Arial\"/> <a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/> <a:font script=\"Geor\" typeface=\"Sylfaen\"/> </a:minorFont> </a:fontScheme> <a:fmtScheme name=\"Office\"> <a:fillStyleLst> <a:solidFill> <a:schemeClr val=\"phClr\"/> </a:solidFill> <a:gradFill rotWithShape=\"1\"> <a:gsLst> <a:gs pos=\"0\"> <a:schemeClr val=\"phClr\"> <a:tint val=\"50000\"/> <a:satMod val=\"300000\"/> </a:schemeClr> </a:gs> <a:gs pos=\"35000\"> <a:schemeClr val=\"phClr\"> <a:tint val=\"37000\"/> <a:satMod val=\"300000\"/> </a:schemeClr> </a:gs> <a:gs pos=\"100000\"> <a:schemeClr val=\"phClr\"> <a:tint val=\"15000\"/> <a:satMod val=\"350000\"/> </a:schemeClr> </a:gs> </a:gsLst> <a:lin ang=\"16200000\" scaled=\"1\"/> </a:gradFill> <a:gradFill rotWithShape=\"1\"> <a:gsLst> <a:gs pos=\"0\"> <a:schemeClr val=\"phClr\"> <a:tint val=\"100000\"/> <a:shade val=\"100000\"/> <a:satMod val=\"130000\"/> </a:schemeClr> </a:gs> <a:gs pos=\"100000\"> <a:schemeClr val=\"phClr\"> <a:tint val=\"50000\"/> <a:shade val=\"100000\"/> <a:satMod val=\"350000\"/> </a:schemeClr> </a:gs> </a:gsLst> <a:lin ang=\"16200000\" scaled=\"0\"/> </a:gradFill> </a:fillStyleLst> <a:lnStyleLst> <a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"> <a:solidFill> <a:schemeClr val=\"phClr\"> <a:shade val=\"95000\"/> <a:satMod val=\"105000\"/> </a:schemeClr> </a:solidFill> <a:prstDash val=\"solid\"/> </a:ln> <a:ln w=\"25400\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"> <a:solidFill> <a:schemeClr val=\"phClr\"/> </a:solidFill> <a:prstDash val=\"solid\"/> </a:ln> <a:ln w=\"38100\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"> <a:solidFill> <a:schemeClr val=\"phClr\"/> </a:solidFill> <a:prstDash val=\"solid\"/> </a:ln> </a:lnStyleLst> <a:effectStyleLst> <a:effectStyle> <a:effectLst> <a:outerShdw blurRad=\"40000\" dist=\"20000\" dir=\"5400000\" rotWithShape=\"0\"> <a:srgbClr val=\"000000\"> <a:alpha val=\"38000\"/> </a:srgbClr> </a:outerShdw> </a:effectLst> </a:effectStyle> <a:effectStyle> <a:effectLst> <a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"> <a:srgbClr val=\"000000\"> <a:alpha val=\"35000\"/> </a:srgbClr> </a:outerShdw> </a:effectLst> </a:effectStyle> <a:effectStyle> <a:effectLst> <a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"> <a:srgbClr val=\"000000\"> <a:alpha val=\"35000\"/> </a:srgbClr> </a:outerShdw> </a:effectLst> <a:scene3d> <a:camera prst=\"orthographicFront\"> <a:rot lat=\"0\" lon=\"0\" rev=\"0\"/> </a:camera> <a:lightRig rig=\"threePt\" dir=\"t\"> <a:rot lat=\"0\" lon=\"0\" rev=\"1200000\"/> </a:lightRig> </a:scene3d> <a:sp3d> <a:bevelT w=\"63500\" h=\"25400\"/> </a:sp3d> </a:effectStyle> </a:effectStyleLst> <a:bgFillStyleLst> <a:solidFill> <a:schemeClr val=\"phClr\"/> </a:solidFill> <a:gradFill rotWithShape=\"1\"> <a:gsLst> <a:gs pos=\"0\"> <a:schemeClr val=\"phClr\"> <a:tint val=\"40000\"/> <a:satMod val=\"350000\"/> </a:schemeClr> </a:gs> <a:gs pos=\"40000\"> <a:schemeClr val=\"phClr\"> <a:tint val=\"45000\"/> <a:shade val=\"99000\"/> <a:satMod val=\"350000\"/> </a:schemeClr> </a:gs> <a:gs pos=\"100000\"> <a:schemeClr val=\"phClr\"> <a:shade val=\"20000\"/> <a:satMod val=\"255000\"/> </a:schemeClr> </a:gs> </a:gsLst> <a:path path=\"circle\"> <a:fillToRect l=\"50000\" t=\"-80000\" r=\"50000\" b=\"180000\"/> </a:path> </a:gradFill> <a:gradFill rotWithShape=\"1\"> <a:gsLst> <a:gs pos=\"0\"> <a:schemeClr val=\"phClr\"> <a:tint val=\"80000\"/> <a:satMod val=\"300000\"/> </a:schemeClr> </a:gs> <a:gs pos=\"100000\"> <a:schemeClr val=\"phClr\"> <a:shade val=\"30000\"/> <a:satMod val=\"200000\"/> </a:schemeClr> </a:gs> </a:gsLst> <a:path path=\"circle\"> <a:fillToRect l=\"50000\" t=\"50000\" r=\"50000\" b=\"50000\"/> </a:path> </a:gradFill> </a:bgFillStyleLst> </a:fmtScheme> </a:themeElements> <a:objectDefaults> <a:spDef> <a:spPr/> <a:bodyPr/> <a:lstStyle/> <a:style> <a:lnRef idx=\"1\"> <a:schemeClr val=\"accent1\"/> </a:lnRef> <a:fillRef idx=\"3\"> <a:schemeClr val=\"accent1\"/> </a:fillRef> <a:effectRef idx=\"2\"> <a:schemeClr val=\"accent1\"/> </a:effectRef> <a:fontRef idx=\"minor\"> <a:schemeClr val=\"lt1\"/> </a:fontRef> </a:style> </a:spDef> <a:lnDef> <a:spPr/> <a:bodyPr/> <a:lstStyle/> <a:style> <a:lnRef idx=\"2\"> <a:schemeClr val=\"accent1\"/> </a:lnRef> <a:fillRef idx=\"0\"> <a:schemeClr val=\"accent1\"/> </a:fillRef> <a:effectRef idx=\"1\"> <a:schemeClr val=\"accent1\"/> </a:effectRef> <a:fontRef idx=\"minor\"> <a:schemeClr val=\"tx1\"/> </a:fontRef> </a:style> </a:lnDef> </a:objectDefaults> <a:extraClrSchemeLst/> </a:theme>";
@@ -19606,6 +20155,7 @@ var ExcelTS = (function(exports) {
19606
20155
  this.addTables(zip, model);
19607
20156
  this.addPivotTables(zip, model);
19608
20157
  await Promise.all([this.addThemes(zip, model), this.addStyles(zip, model)]);
20158
+ await this.addFeaturePropertyBag(zip, model);
19609
20159
  await this.addMedia(zip, model);
19610
20160
  await Promise.all([this.addApp(zip, model), this.addCore(zip, model)]);
19611
20161
  await this.addWorkbook(zip, model);
@@ -20018,7 +20568,7 @@ var ExcelTS = (function(exports) {
20018
20568
  model.drawingRels[name] = relationships;
20019
20569
  }
20020
20570
  async _processVmlDrawingEntry(entry, model, name) {
20021
- const vmlDrawing = await new VmlNotesXform().parseStream(entry);
20571
+ const vmlDrawing = await new VmlDrawingXform().parseStream(entry);
20022
20572
  model.vmlDrawings[vmlDrawingRelTargetFromWorksheetName(name)] = vmlDrawing;
20023
20573
  }
20024
20574
  async _processThemeEntry(stream, model, name) {
@@ -20264,6 +20814,11 @@ var ExcelTS = (function(exports) {
20264
20814
  Type: XLSX.RelType.SharedStrings,
20265
20815
  Target: OOXML_REL_TARGETS.workbookSharedStrings
20266
20816
  });
20817
+ if (model.hasCheckboxes) relationships.push({
20818
+ Id: `rId${count++}`,
20819
+ Type: XLSX.RelType.FeaturePropertyBag,
20820
+ Target: OOXML_REL_TARGETS.workbookFeaturePropertyBag
20821
+ });
20267
20822
  (model.pivotTables || []).forEach((pivotTable) => {
20268
20823
  pivotTable.rId = `rId${count++}`;
20269
20824
  relationships.push({
@@ -20284,6 +20839,11 @@ var ExcelTS = (function(exports) {
20284
20839
  const xml = new RelationshipsXform().toXml(relationships);
20285
20840
  zip.append(xml, { name: OOXML_PATHS.xlWorkbookRels });
20286
20841
  }
20842
+ async addFeaturePropertyBag(zip, model) {
20843
+ if (!model.hasCheckboxes) return;
20844
+ const xform$1 = new FeaturePropertyBagXform();
20845
+ zip.append(xform$1.toXml({}), { name: OOXML_PATHS.xlFeaturePropertyBag });
20846
+ }
20287
20847
  async addSharedStrings(zip, model) {
20288
20848
  if (model.sharedStrings && model.sharedStrings.count) zip.append(model.sharedStrings.xml, { name: OOXML_PATHS.xlSharedStrings });
20289
20849
  }
@@ -20299,7 +20859,8 @@ var ExcelTS = (function(exports) {
20299
20859
  const worksheetXform = new WorkSheetXform();
20300
20860
  const relationshipsXform = new RelationshipsXform();
20301
20861
  const commentsXform = new CommentsXform();
20302
- const vmlNotesXform = new VmlNotesXform();
20862
+ const vmlDrawingXform = new VmlDrawingXform();
20863
+ const ctrlPropXform = new CtrlPropXform();
20303
20864
  model.worksheets.forEach((worksheet, index) => {
20304
20865
  const fileIndex = worksheet.fileIndex || index + 1;
20305
20866
  let xmlStream = new XmlStream();
@@ -20314,10 +20875,21 @@ var ExcelTS = (function(exports) {
20314
20875
  xmlStream = new XmlStream();
20315
20876
  commentsXform.render(xmlStream, worksheet);
20316
20877
  zip.append(xmlStream.xml, { name: commentsPath(fileIndex) });
20878
+ }
20879
+ const hasComments = worksheet.comments.length > 0;
20880
+ const hasFormControls = worksheet.formControls && worksheet.formControls.length > 0;
20881
+ if (hasComments || hasFormControls) {
20317
20882
  xmlStream = new XmlStream();
20318
- vmlNotesXform.render(xmlStream, worksheet);
20883
+ vmlDrawingXform.render(xmlStream, {
20884
+ comments: hasComments ? worksheet.comments : [],
20885
+ formControls: hasFormControls ? worksheet.formControls : []
20886
+ });
20319
20887
  zip.append(xmlStream.xml, { name: vmlDrawingPath(fileIndex) });
20320
20888
  }
20889
+ if (hasFormControls) worksheet.formControls.forEach((control) => {
20890
+ const xml = ctrlPropXform.toXml(control);
20891
+ zip.append(xml, { name: ctrlPropPath(control.ctrlPropId) });
20892
+ });
20321
20893
  });
20322
20894
  }
20323
20895
  addDrawings(zip, model) {
@@ -20414,6 +20986,7 @@ var ExcelTS = (function(exports) {
20414
20986
  };
20415
20987
  worksheetOptions.drawings = model.drawings = [];
20416
20988
  worksheetOptions.commentRefs = model.commentRefs = [];
20989
+ worksheetOptions.formControlRefs = model.formControlRefs = [];
20417
20990
  let tableCount = 0;
20418
20991
  model.tables = [];
20419
20992
  model.worksheets.forEach((worksheet) => {
@@ -20425,6 +20998,7 @@ var ExcelTS = (function(exports) {
20425
20998
  });
20426
20999
  worksheetXform.prepare(worksheet, worksheetOptions);
20427
21000
  });
21001
+ model.hasCheckboxes = model.styles.hasCheckboxes;
20428
21002
  }
20429
21003
  };
20430
21004
 
@@ -22448,6 +23022,7 @@ var ExcelTS = (function(exports) {
22448
23022
  this.addCore(),
22449
23023
  this.addSharedStrings(),
22450
23024
  this.addStyles(),
23025
+ this.addFeaturePropertyBag(),
22451
23026
  this.addWorkbookRels()
22452
23027
  ]);
22453
23028
  await this.addWorkbook();
@@ -22543,7 +23118,8 @@ var ExcelTS = (function(exports) {
22543
23118
  worksheets: this._worksheets.filter(Boolean),
22544
23119
  sharedStrings: this.sharedStrings,
22545
23120
  commentRefs: this.commentRefs,
22546
- media: this.media
23121
+ media: this.media,
23122
+ hasCheckboxes: this.styles.hasCheckboxes
22547
23123
  };
22548
23124
  const xform$1 = new ContentTypesXform();
22549
23125
  this._addFile(xform$1.toXml(model), OOXML_PATHS.contentTypes);
@@ -22593,6 +23169,13 @@ var ExcelTS = (function(exports) {
22593
23169
  });
22594
23170
  return Promise.resolve();
22595
23171
  }
23172
+ addFeaturePropertyBag() {
23173
+ if (this.styles.hasCheckboxes) {
23174
+ const xform$1 = new FeaturePropertyBagXform();
23175
+ this._addFile(xform$1.toXml({}), OOXML_PATHS.xlFeaturePropertyBag);
23176
+ }
23177
+ return Promise.resolve();
23178
+ }
22596
23179
  addWorkbookRels() {
22597
23180
  let count = 1;
22598
23181
  const relationships = [{
@@ -22609,6 +23192,11 @@ var ExcelTS = (function(exports) {
22609
23192
  Type: RelType.SharedStrings,
22610
23193
  Target: OOXML_REL_TARGETS.workbookSharedStrings
22611
23194
  });
23195
+ if (this.styles.hasCheckboxes) relationships.push({
23196
+ Id: `rId${count++}`,
23197
+ Type: RelType.FeaturePropertyBag,
23198
+ Target: OOXML_REL_TARGETS.workbookFeaturePropertyBag
23199
+ });
22612
23200
  this._worksheets.forEach((ws) => {
22613
23201
  if (ws) {
22614
23202
  ws.rId = `rId${count++}`;
@@ -24636,6 +25224,7 @@ exports.DataValidations = DataValidations;
24636
25224
  exports.DocumentType = DocumentType;
24637
25225
  exports.Enums = Enums;
24638
25226
  exports.ErrorValue = ErrorValue;
25227
+ exports.FormCheckbox = FormCheckbox;
24639
25228
  exports.FormulaType = FormulaType;
24640
25229
  exports.Image = Image;
24641
25230
  exports.PaperSize = PaperSize;