@rowsncolumns/toolkit 24.5.4 → 24.5.6

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 (77) hide show
  1. package/dist/cjs/autofilter-condition.js +6 -2
  2. package/dist/cjs/excel-parser/helpers.d.ts +9 -1
  3. package/dist/cjs/excel-parser/helpers.d.ts.map +1 -1
  4. package/dist/cjs/excel-parser/helpers.js +70 -16
  5. package/dist/cjs/excel-parser/interface.d.ts +9 -1
  6. package/dist/cjs/excel-parser/interface.d.ts.map +1 -1
  7. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -1
  8. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.js +61 -6
  9. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -1
  10. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.js +13 -2
  11. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts +8 -1
  12. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
  13. package/dist/cjs/excel-parser/plugins/xlsx/index.js +159 -26
  14. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts +17 -2
  15. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
  16. package/dist/cjs/excel-parser/plugins/xlsx/styles.js +25 -14
  17. package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -1
  18. package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.js +19 -15
  19. package/dist/cjs/excel-parser/types.d.ts +5 -1
  20. package/dist/cjs/excel-parser/types.d.ts.map +1 -1
  21. package/dist/cjs/excel-parser/workbook.d.ts +1 -0
  22. package/dist/cjs/excel-parser/workbook.d.ts.map +1 -1
  23. package/dist/cjs/excel-parser/workbook.js +4 -0
  24. package/dist/cjs/excel-parser/worker.js +3 -0
  25. package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -1
  26. package/dist/cjs/exporter/xlsx/chart-builder.js +167 -53
  27. package/dist/cjs/exporter/xlsx/future-functions.d.ts +6 -7
  28. package/dist/cjs/exporter/xlsx/future-functions.d.ts.map +1 -1
  29. package/dist/cjs/exporter/xlsx/future-functions.js +5 -261
  30. package/dist/cjs/exporter/xlsx/style-builder.d.ts.map +1 -1
  31. package/dist/cjs/exporter/xlsx/style-builder.js +62 -19
  32. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts +10 -2
  33. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -1
  34. package/dist/cjs/exporter/xlsx/xlsx-export.js +404 -158
  35. package/dist/cjs/helpers/excel-formula-prefixes.d.ts +51 -0
  36. package/dist/cjs/helpers/excel-formula-prefixes.d.ts.map +1 -0
  37. package/dist/cjs/helpers/excel-formula-prefixes.js +548 -0
  38. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  39. package/dist/esm/autofilter-condition.js +6 -2
  40. package/dist/esm/excel-parser/helpers.d.ts +9 -1
  41. package/dist/esm/excel-parser/helpers.d.ts.map +1 -1
  42. package/dist/esm/excel-parser/helpers.js +65 -3
  43. package/dist/esm/excel-parser/interface.d.ts +9 -1
  44. package/dist/esm/excel-parser/interface.d.ts.map +1 -1
  45. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -1
  46. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.js +42 -1
  47. package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -1
  48. package/dist/esm/excel-parser/plugins/xlsx/data-validations.js +11 -2
  49. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts +8 -1
  50. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
  51. package/dist/esm/excel-parser/plugins/xlsx/index.js +109 -4
  52. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts +17 -2
  53. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
  54. package/dist/esm/excel-parser/plugins/xlsx/styles.js +20 -8
  55. package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -1
  56. package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.js +13 -9
  57. package/dist/esm/excel-parser/types.d.ts +5 -1
  58. package/dist/esm/excel-parser/types.d.ts.map +1 -1
  59. package/dist/esm/excel-parser/workbook.d.ts +1 -0
  60. package/dist/esm/excel-parser/workbook.d.ts.map +1 -1
  61. package/dist/esm/excel-parser/workbook.js +3 -0
  62. package/dist/esm/excel-parser/worker.js +3 -0
  63. package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -1
  64. package/dist/esm/exporter/xlsx/chart-builder.js +80 -0
  65. package/dist/esm/exporter/xlsx/future-functions.d.ts +6 -7
  66. package/dist/esm/exporter/xlsx/future-functions.d.ts.map +1 -1
  67. package/dist/esm/exporter/xlsx/future-functions.js +5 -261
  68. package/dist/esm/exporter/xlsx/style-builder.d.ts.map +1 -1
  69. package/dist/esm/exporter/xlsx/style-builder.js +56 -18
  70. package/dist/esm/exporter/xlsx/xlsx-export.d.ts +10 -2
  71. package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -1
  72. package/dist/esm/exporter/xlsx/xlsx-export.js +338 -106
  73. package/dist/esm/helpers/excel-formula-prefixes.d.ts +51 -0
  74. package/dist/esm/helpers/excel-formula-prefixes.d.ts.map +1 -0
  75. package/dist/esm/helpers/excel-formula-prefixes.js +531 -0
  76. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  77. package/package.json +4 -4
@@ -1,264 +1,8 @@
1
- import { __read, __spreadArray } from "tslib";
2
1
  /**
3
2
  * Excel "future functions" — functions added after the Excel 2007 (.xlsx)
4
- * file format was frozen. [MS-XLSX] requires them to be written into sheet
5
- * XML behind a `_xlfn.` namespace prefix (`_xlfn._xlws.` for the
6
- * worksheet-scoped dynamic-array functions); the UI never shows the prefix.
7
- * Written bare, Excel does not resolve the name: it renders the call behind
8
- * the implicit-intersection operator (`=@DAYS(...)`) and evaluates `#NAME?`.
9
- *
10
- * The list follows Microsoft's documentation of `_xlfn.`-prefixed functions
11
- * ("Issue: An _xlfn. prefix is displayed in front of a function in a
12
- * formula", support.microsoft.com) plus the dynamic-array / LAMBDA-era and
13
- * 2024 additions that ship with the same prefix convention.
3
+ * file format was frozen — must be written into sheet XML behind a `_xlfn.`
4
+ * namespace prefix. The list and both directions of the transform live in
5
+ * `helpers/excel-formula-prefixes` (the importer strips what the exporter
6
+ * adds); this module keeps the exporter-side entry point.
14
7
  */
15
- var FUTURE_FUNCTION_NAMES = [
16
- "ACOT",
17
- "ACOTH",
18
- "AGGREGATE",
19
- "ANCHORARRAY",
20
- "ARABIC",
21
- "ARRAYTOTEXT",
22
- "BASE",
23
- "BETA.DIST",
24
- "BETA.INV",
25
- "BINOM.DIST",
26
- "BINOM.DIST.RANGE",
27
- "BINOM.INV",
28
- "BITAND",
29
- "BITLSHIFT",
30
- "BITOR",
31
- "BITRSHIFT",
32
- "BITXOR",
33
- "BYCOL",
34
- "BYROW",
35
- "CEILING.MATH",
36
- "CEILING.PRECISE",
37
- "CHISQ.DIST",
38
- "CHISQ.DIST.RT",
39
- "CHISQ.INV",
40
- "CHISQ.INV.RT",
41
- "CHISQ.TEST",
42
- "CHOOSECOLS",
43
- "CHOOSEROWS",
44
- "COMBINA",
45
- "CONCAT",
46
- "CONFIDENCE.NORM",
47
- "CONFIDENCE.T",
48
- "COT",
49
- "COTH",
50
- "COVARIANCE.P",
51
- "COVARIANCE.S",
52
- "CSC",
53
- "CSCH",
54
- "DAYS",
55
- "DECIMAL",
56
- "DETECTLANGUAGE",
57
- "DROP",
58
- "ENCODEURL",
59
- "ERF.PRECISE",
60
- "ERFC.PRECISE",
61
- "EXPAND",
62
- "EXPON.DIST",
63
- "F.DIST",
64
- "F.DIST.RT",
65
- "F.INV",
66
- "F.INV.RT",
67
- "F.TEST",
68
- "FIELDVALUE",
69
- "FILTER",
70
- "FILTERXML",
71
- "FLOOR.MATH",
72
- "FLOOR.PRECISE",
73
- "FORECAST.ETS",
74
- "FORECAST.ETS.CONFINT",
75
- "FORECAST.ETS.SEASONALITY",
76
- "FORECAST.ETS.STAT",
77
- "FORECAST.LINEAR",
78
- "FORMULATEXT",
79
- "GAMMA",
80
- "GAMMA.DIST",
81
- "GAMMA.INV",
82
- "GAMMALN.PRECISE",
83
- "GAUSS",
84
- "GROUPBY",
85
- "HSTACK",
86
- "HYPGEOM.DIST",
87
- "IFNA",
88
- "IFS",
89
- "IMAGE",
90
- "IMCOSH",
91
- "IMCOT",
92
- "IMCSC",
93
- "IMCSCH",
94
- "IMSEC",
95
- "IMSECH",
96
- "IMSINH",
97
- "IMTAN",
98
- "ISFORMULA",
99
- "ISOMITTED",
100
- "ISOWEEKNUM",
101
- "LAMBDA",
102
- "LET",
103
- "LOGNORM.DIST",
104
- "LOGNORM.INV",
105
- "MAKEARRAY",
106
- "MAP",
107
- "MAXIFS",
108
- "MINIFS",
109
- "MODE.MULT",
110
- "MODE.SNGL",
111
- "MUNIT",
112
- "NEGBINOM.DIST",
113
- "NETWORKDAYS.INTL",
114
- "NORM.DIST",
115
- "NORM.INV",
116
- "NORM.S.DIST",
117
- "NORM.S.INV",
118
- "NUMBERVALUE",
119
- "PDURATION",
120
- "PERCENTILE.EXC",
121
- "PERCENTILE.INC",
122
- "PERCENTOF",
123
- "PERCENTRANK.EXC",
124
- "PERCENTRANK.INC",
125
- "PERMUTATIONA",
126
- "PHI",
127
- "PIVOTBY",
128
- "POISSON.DIST",
129
- "QUARTILE.EXC",
130
- "QUARTILE.INC",
131
- "QUERYSTRING",
132
- "RANDARRAY",
133
- "RANK.AVG",
134
- "RANK.EQ",
135
- "REDUCE",
136
- "REGEXEXTRACT",
137
- "REGEXREPLACE",
138
- "REGEXTEST",
139
- "RRI",
140
- "SCAN",
141
- "SEC",
142
- "SECH",
143
- "SEQUENCE",
144
- "SHEET",
145
- "SHEETS",
146
- "SINGLE",
147
- "SKEW.P",
148
- "SORT",
149
- "SORTBY",
150
- "STDEV.P",
151
- "STDEV.S",
152
- "STOCKHISTORY",
153
- "SWITCH",
154
- "T.DIST",
155
- "T.DIST.2T",
156
- "T.DIST.RT",
157
- "T.INV",
158
- "T.INV.2T",
159
- "T.TEST",
160
- "TAKE",
161
- "TEXTAFTER",
162
- "TEXTBEFORE",
163
- "TEXTJOIN",
164
- "TEXTSPLIT",
165
- "TOCOL",
166
- "TOROW",
167
- "TRANSLATE",
168
- "TRIMRANGE",
169
- "UNICHAR",
170
- "UNICODE",
171
- "UNIQUE",
172
- "VALUETOTEXT",
173
- "VAR.P",
174
- "VAR.S",
175
- "VSTACK",
176
- "WEBSERVICE",
177
- "WEIBULL.DIST",
178
- "WORKDAY.INTL",
179
- "WRAPCOLS",
180
- "WRAPROWS",
181
- "XLOOKUP",
182
- "XMATCH",
183
- "XOR",
184
- "Z.TEST",
185
- ];
186
- /**
187
- * Future functions that Excel writes behind the worksheet-scope prefix
188
- * (`_xlfn._xlws.`) rather than plain `_xlfn.` — the dynamic-array functions
189
- * that also exist as worksheet-only names.
190
- */
191
- var WORKSHEET_SCOPED_FUTURE_FUNCTIONS = new Set([
192
- "FILTER",
193
- "SORT",
194
- ]);
195
- var QUALIFIED_BY_NAME = new Map(FUTURE_FUNCTION_NAMES.map(function (name) { return [
196
- name,
197
- WORKSHEET_SCOPED_FUTURE_FUNCTIONS.has(name)
198
- ? "_xlfn._xlws.".concat(name)
199
- : "_xlfn.".concat(name),
200
- ]; }));
201
- // Longest names first so `T.DIST.2T` wins over `T.DIST`. The match must be
202
- // followed by `(` — a bare name (e.g. the defined name `DAYS`) is not a call.
203
- var FUTURE_FUNCTION_REGEX = new RegExp("(" +
204
- __spreadArray([], __read(FUTURE_FUNCTION_NAMES), false).sort(function (a, b) { return b.length - a.length; })
205
- .map(function (name) { return name.replace(/\./g, "\\."); })
206
- .join("|") +
207
- ")(\\s*\\()", "gi");
208
- // `\b` is not enough of a left boundary: it would match the `DAYS` in
209
- // `_xlfn.DAYS` and in `MYDAYS`. The preceding character is checked by offset
210
- // instead of being consumed by the pattern, so nested calls
211
- // (`SORT(FILTER(...))`) still match after the enclosing one.
212
- var FUTURE_FUNCTION_LEFT_BOUNDARY = /[A-Za-z0-9_.$]/;
213
- function qualifySegment(segment) {
214
- var stripped = segment
215
- .replace(/_xlfn\./gi, "")
216
- .replace(/_xlws\./gi, "")
217
- .replace(/_xludf\./gi, "");
218
- return stripped.replace(FUTURE_FUNCTION_REGEX, function (match, name, open, offset) {
219
- if (offset > 0 &&
220
- FUTURE_FUNCTION_LEFT_BOUNDARY.test(stripped[offset - 1])) {
221
- return match;
222
- }
223
- var qualified = QUALIFIED_BY_NAME.get(name.toUpperCase());
224
- return qualified ? qualified + open : match;
225
- });
226
- }
227
- /**
228
- * Strip the `_xlfn.` / `_xlws.` / `_xludf.` prefixes and re-add the correct
229
- * one to every future-function call in `formula`. Quoted spans are copied
230
- * verbatim so string literals (`"…"`) and quoted sheet names (`'…'`) keep
231
- * their original text; a doubled quote inside a span is an escaped quote.
232
- * Because the strip pass runs first, already-qualified input comes out
233
- * qualified exactly once.
234
- */
235
- export function qualifyFutureFunctions(formula) {
236
- var result = "";
237
- var segmentStart = 0;
238
- var index = 0;
239
- while (index < formula.length) {
240
- var char = formula[index];
241
- if (char !== '"' && char !== "'") {
242
- index++;
243
- continue;
244
- }
245
- result += qualifySegment(formula.slice(segmentStart, index));
246
- var end = index + 1;
247
- while (end < formula.length) {
248
- if (formula[end] === char) {
249
- if (formula[end + 1] === char) {
250
- end += 2;
251
- continue;
252
- }
253
- break;
254
- }
255
- end++;
256
- }
257
- // An unterminated literal consumes the rest of the formula.
258
- var literalEnd = end < formula.length ? end + 1 : formula.length;
259
- result += formula.slice(index, literalEnd);
260
- index = literalEnd;
261
- segmentStart = literalEnd;
262
- }
263
- return result + qualifySegment(formula.slice(segmentStart));
264
- }
8
+ export { FUTURE_FUNCTION_NAMES, WORKSHEET_SCOPED_FUTURE_FUNCTIONS, qualifyFutureFunctions, } from "../../helpers/excel-formula-prefixes";
@@ -1 +1 @@
1
- {"version":3,"file":"style-builder.d.ts","sourceRoot":"","sources":["../../../../exporter/xlsx/style-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,QAAQ,EACR,UAAU,EACV,KAAK,EAEL,UAAU,EACV,gBAAgB,EAEjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAwF/D,KAAK,oBAAoB,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAKF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,eAAe,CAAC,EAAE,KAAK,CAAC;QACxB,SAAS,CAAC,EAAE,KAAK,CAAC;QAClB,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,GACxC,aAAa,gBAAgB,KAC5B,sBAAsB,CAAC,UAAU,CAqBnC,CAAC;AAEF,qBAAa,YAAY;IACvB,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,KAAK,CAKX;IACF,OAAO,CAAC,KAAK,CAA+D;IAC5E,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,eAAe,CAErB;IACF,OAAO,CAAC,iBAAiB,CAAgC;IAEzD;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,EAAE;IAUlD;;;;;;;OAOG;IACH,oBAAoB,CAAC,OAAO,EAAE,sBAAsB,EAAE;IAOtD,OAAO,CAAC,OAAO,CAOb;IAEF,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,MAAM,CAA6B;;IAU3C;;;;;;;OAOG;IACH,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI;IASzC,YAAY,CAAC,CAAC,SAAS,QAAQ,EAC7B,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EAC1B,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS;IACnC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,UAAU,CAAC,cAAc,CAAC,GAC/C,MAAM;IAsET,0BAA0B,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI;IA0BrD,OAAO,CAAC,iBAAiB;IAoCzB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,SAAS;IA2DjB,OAAO,CAAC,WAAW;IA2BnB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,eAAe;IA8BvB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,YAAY;IAqCpB,OAAO,CAAC,oBAAoB;IAyB5B,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,YAAY;IAMpB,KAAK;CAuJN"}
1
+ {"version":3,"file":"style-builder.d.ts","sourceRoot":"","sources":["../../../../exporter/xlsx/style-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,QAAQ,EACR,UAAU,EACV,KAAK,EAEL,UAAU,EACV,gBAAgB,EAEjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,iCAAiC,CAAC;AA4F/D,KAAK,oBAAoB,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAKF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,eAAe,CAAC,EAAE,KAAK,CAAC;QACxB,SAAS,CAAC,EAAE,KAAK,CAAC;QAClB,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,GACxC,aAAa,gBAAgB,KAC5B,sBAAsB,CAAC,UAAU,CAqBnC,CAAC;AAEF,qBAAa,YAAY;IACvB,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,KAAK,CAKX;IACF,OAAO,CAAC,KAAK,CAA+D;IAC5E,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,eAAe,CAErB;IACF,OAAO,CAAC,iBAAiB,CAAgC;IAEzD;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,EAAE;IAUlD;;;;;;;OAOG;IACH,oBAAoB,CAAC,OAAO,EAAE,sBAAsB,EAAE;IAOtD,OAAO,CAAC,OAAO,CAOb;IAEF,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,MAAM,CAA6B;;IAU3C;;;;;;;OAOG;IACH,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI;IASzC,YAAY,CAAC,CAAC,SAAS,QAAQ,EAC7B,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EAC1B,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS;IACnC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,UAAU,CAAC,cAAc,CAAC,GAC/C,MAAM;IAsET,0BAA0B,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI;IAsCrD,OAAO,CAAC,iBAAiB;IAoCzB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,SAAS;IA2DjB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,eAAe;IA8BvB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,YAAY;IAqCpB,OAAO,CAAC,oBAAoB;IAyB5B,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,YAAY;IAQpB,KAAK;CA6JN"}
@@ -180,6 +180,7 @@ var StyleBuilder = /** @class */ (function () {
180
180
  return nextId;
181
181
  };
182
182
  StyleBuilder.prototype.registerDifferentialFormat = function (format) {
183
+ var _a;
183
184
  if (!format)
184
185
  return undefined;
185
186
  var record = {};
@@ -192,7 +193,19 @@ var StyleBuilder = /** @class */ (function () {
192
193
  if (font) {
193
194
  record.font = font;
194
195
  }
195
- if (!record.fill && !record.font) {
196
+ // A rule may set ONLY a border and/or a number format (Excel's Format
197
+ // Cells → Border / Number tabs) — that is a normal rule with a normal
198
+ // dxf, not an empty record to drop.
199
+ var border = buildBorderRecord(format.borders);
200
+ if (hasBorderEdge(border)) {
201
+ record.border = border;
202
+ }
203
+ var numFmtId = this.getNumberFormatId(format);
204
+ var numFmtPattern = (_a = format.numberFormat) === null || _a === void 0 ? void 0 : _a.pattern;
205
+ if (numFmtId !== 0 && numFmtPattern) {
206
+ record.numFmt = { id: numFmtId, format: numFmtPattern };
207
+ }
208
+ if (!record.fill && !record.font && !record.border && !record.numFmt) {
196
209
  return undefined;
197
210
  }
198
211
  var key = this.serializeDxf(record);
@@ -310,22 +323,7 @@ var StyleBuilder = /** @class */ (function () {
310
323
  return nextId;
311
324
  };
312
325
  StyleBuilder.prototype.getBorderId = function (borders) {
313
- var _a;
314
- // OOXML uses a single <diagonal> child plus diagonalUp/diagonalDown
315
- // attributes. If both diagonals are present and identically styled the
316
- // first non-null one defines the edge; otherwise each flag is set
317
- // independently and both share the same painted style. This matches
318
- // how Excel collapses diagonal pairs.
319
- var diagonalEdge = convertBorderEdge((_a = borders === null || borders === void 0 ? void 0 : borders.diagonalUp) !== null && _a !== void 0 ? _a : borders === null || borders === void 0 ? void 0 : borders.diagonalDown);
320
- var record = {
321
- top: convertBorderEdge(borders === null || borders === void 0 ? void 0 : borders.top),
322
- bottom: convertBorderEdge(borders === null || borders === void 0 ? void 0 : borders.bottom),
323
- left: convertBorderEdge(borders === null || borders === void 0 ? void 0 : borders.left),
324
- right: convertBorderEdge(borders === null || borders === void 0 ? void 0 : borders.right),
325
- diagonal: diagonalEdge,
326
- diagonalUp: !!(borders === null || borders === void 0 ? void 0 : borders.diagonalUp),
327
- diagonalDown: !!(borders === null || borders === void 0 ? void 0 : borders.diagonalDown),
328
- };
326
+ var record = buildBorderRecord(borders);
329
327
  var key = this.serializeBorder(record);
330
328
  var existing = this.borderMap.get(key);
331
329
  if (typeof existing === "number") {
@@ -464,7 +462,7 @@ var StyleBuilder = /** @class */ (function () {
464
462
  ].join("|");
465
463
  };
466
464
  StyleBuilder.prototype.serializeDxf = function (dxf) {
467
- return "".concat(dxf.fill ? this.serializeFill(dxf.fill) : "", "|").concat(dxf.font ? this.serializeFont(dxf.font) : "");
465
+ return "".concat(dxf.fill ? this.serializeFill(dxf.fill) : "", "|").concat(dxf.font ? this.serializeFont(dxf.font) : "", "|").concat(dxf.border ? this.serializeBorder(dxf.border) : "", "|").concat(dxf.numFmt ? dxf.numFmt.id : "");
468
466
  };
469
467
  StyleBuilder.prototype.toXml = function () {
470
468
  var _this = this;
@@ -553,8 +551,12 @@ var StyleBuilder = /** @class */ (function () {
553
551
  ? "<dxfs count=\"".concat(this.dxfs.length, "\">").concat(this.dxfs
554
552
  .map(function (dxf) {
555
553
  var font = dxf.font ? _this.buildFontXml(dxf.font) : "";
554
+ var numFmt = dxf.numFmt
555
+ ? "<numFmt numFmtId=\"".concat(dxf.numFmt.id, "\" formatCode=\"").concat(escapeXml(dxf.numFmt.format), "\"/>")
556
+ : "";
556
557
  var fill = dxf.fill ? _this.buildFillXml(dxf.fill, true) : "";
557
- return "<dxf>".concat(font).concat(fill, "</dxf>");
558
+ var border = dxf.border ? buildDxfBorderXml(dxf.border) : "";
559
+ return "<dxf>".concat(font).concat(numFmt).concat(fill).concat(border, "</dxf>");
558
560
  })
559
561
  .join(""), "</dxfs>")
560
562
  : "<dxfs count=\"0\"/>";
@@ -598,6 +600,47 @@ var StyleBuilder = /** @class */ (function () {
598
600
  return StyleBuilder;
599
601
  }());
600
602
  export { StyleBuilder };
603
+ // OOXML uses a single <diagonal> child plus diagonalUp/diagonalDown
604
+ // attributes. If both diagonals are present and identically styled the
605
+ // first non-null one defines the edge; otherwise each flag is set
606
+ // independently and both share the same painted style. This matches
607
+ // how Excel collapses diagonal pairs.
608
+ var buildBorderRecord = function (borders) {
609
+ var _a;
610
+ var diagonalEdge = convertBorderEdge((_a = borders === null || borders === void 0 ? void 0 : borders.diagonalUp) !== null && _a !== void 0 ? _a : borders === null || borders === void 0 ? void 0 : borders.diagonalDown);
611
+ return {
612
+ top: convertBorderEdge(borders === null || borders === void 0 ? void 0 : borders.top),
613
+ bottom: convertBorderEdge(borders === null || borders === void 0 ? void 0 : borders.bottom),
614
+ left: convertBorderEdge(borders === null || borders === void 0 ? void 0 : borders.left),
615
+ right: convertBorderEdge(borders === null || borders === void 0 ? void 0 : borders.right),
616
+ diagonal: diagonalEdge,
617
+ diagonalUp: !!(borders === null || borders === void 0 ? void 0 : borders.diagonalUp),
618
+ diagonalDown: !!(borders === null || borders === void 0 ? void 0 : borders.diagonalDown),
619
+ };
620
+ };
621
+ var hasBorderEdge = function (border) {
622
+ var _a, _b, _c, _d, _e;
623
+ return Boolean(((_a = border.top) === null || _a === void 0 ? void 0 : _a.style) ||
624
+ ((_b = border.bottom) === null || _b === void 0 ? void 0 : _b.style) ||
625
+ ((_c = border.left) === null || _c === void 0 ? void 0 : _c.style) ||
626
+ ((_d = border.right) === null || _d === void 0 ? void 0 : _d.style) ||
627
+ ((_e = border.diagonal) === null || _e === void 0 ? void 0 : _e.style));
628
+ };
629
+ // A dxf `<border>` lists only the edges the rule sets: unlike a cell
630
+ // border, an empty `<left/>` in a differential format would mean "remove
631
+ // the left border", not "leave it alone".
632
+ var buildDxfBorderXml = function (border) {
633
+ var _a;
634
+ var edges = ["left", "right", "top", "bottom"]
635
+ .filter(function (side) { var _a; return (_a = border[side]) === null || _a === void 0 ? void 0 : _a.style; })
636
+ .map(function (side) { return serializeBorderEdgeXml(border[side], side); })
637
+ .join("");
638
+ var diagonal = ((_a = border.diagonal) === null || _a === void 0 ? void 0 : _a.style)
639
+ ? serializeBorderEdgeXml(border.diagonal, "diagonal")
640
+ : "";
641
+ var diagonalAttrs = "".concat(border.diagonalUp ? " diagonalUp=\"1\"" : "").concat(border.diagonalDown ? " diagonalDown=\"1\"" : "");
642
+ return "<border".concat(diagonalAttrs, ">").concat(edges).concat(diagonal, "</border>");
643
+ };
601
644
  var convertBorderEdge = function (border) {
602
645
  var _a;
603
646
  if (!border || !border.style)
@@ -1,5 +1,5 @@
1
1
  import type { CellData, Citation, CommentThread, DataValidationRuleRecord, IterativeCalculationOptions, SheetData, TextFormat } from "@rowsncolumns/common-types";
2
- import type { Color, ConditionalFormatRule, EmbeddedChart, EmbeddedObject, NamedRange, PivotTable, ProtectedRange, Sheet, Slicer, SpreadsheetTheme, TableView, CustomTableStyle } from "@rowsncolumns/spreadsheet";
2
+ import type { Color, ConditionalFormatRule, EmbeddedChart, EmbeddedObject, NamedRange, PivotTable, ProtectedRange, Sheet, WorkbookProtection, Slicer, SpreadsheetTheme, TableView, CustomTableStyle } from "@rowsncolumns/spreadsheet";
3
3
  import type { CellXfs, SharedStrings as SharedStringsType } from "@rowsncolumns/spreadsheet-state";
4
4
  import type { PowerQueryParts } from "../../power-query";
5
5
  import type { ExternalLink, WorkbookProperties } from "../../excel-parser/types";
@@ -83,6 +83,14 @@ export type ExportExcelProps<S extends Sheet, T extends CellData, C extends Cita
83
83
  }>;
84
84
  }>;
85
85
  iterativeCalculationOptions?: IterativeCalculationOptions;
86
+ /**
87
+ * Excel "Protect Workbook" — written as `<workbookProtection …/>` right after
88
+ * `<workbookPr>` in `xl/workbook.xml` (structure / windows / revision locks
89
+ * plus the source's password hash, verbatim). Omitted ⇒ no element, Excel's
90
+ * unprotected workbook. The parser's `getWorkbookProtection()` is the source
91
+ * on a round trip.
92
+ */
93
+ workbookProtection?: WorkbookProtection;
86
94
  ignoreFormulaPatterns?: RegExp | RegExp[];
87
95
  citations?: Citation[];
88
96
  /**
@@ -118,7 +126,7 @@ export type ExportExcelProps<S extends Sheet, T extends CellData, C extends Cita
118
126
  */
119
127
  properties?: WorkbookProperties;
120
128
  };
121
- export declare const createExcelFile: <S extends Sheet, T extends CellData, C extends Citation>({ conditionalFormats: _conditionalFormats, dataValidations: _dataValidations, sheets, sheetData, sharedStrings: sourceSharedStrings, tables: _tables, cellXfs, theme, defaultFont, embeds, charts, slicers, pivotTables, externalLinks, namedRanges, protectedRanges, namedCellStyles, customTableStyles, iterativeCalculationOptions, ignoreFormulaPatterns, citations, comments, password, locale, use1904, properties, powerQuery, }: ExportExcelProps<S, T, C>) => Promise<Uint8Array<ArrayBufferLike>>;
129
+ export declare const createExcelFile: <S extends Sheet, T extends CellData, C extends Citation>({ conditionalFormats: _conditionalFormats, dataValidations: _dataValidations, sheets, sheetData, sharedStrings: sourceSharedStrings, tables: _tables, cellXfs, theme, defaultFont, embeds, charts, slicers, pivotTables, externalLinks, namedRanges, protectedRanges, namedCellStyles, customTableStyles, iterativeCalculationOptions, workbookProtection, ignoreFormulaPatterns, citations, comments, password, locale, use1904, properties, powerQuery, }: ExportExcelProps<S, T, C>) => Promise<Uint8Array<ArrayBufferLike>>;
122
130
  /**
123
131
  * Normalize a dataValidation sqref list: collapse degenerate ranges
124
132
  * (`C7:C7` → `C7`), drop exact duplicates, and drop members fully contained
@@ -1 +1 @@
1
- {"version":3,"file":"xlsx-export.d.ts","sourceRoot":"","sources":["../../../../exporter/xlsx/xlsx-export.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"xlsx-export.d.ts","sourceRoot":"","sources":["../../../../exporter/xlsx/xlsx-export.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,QAAQ,EACR,aAAa,EAEb,wBAAwB,EAGxB,2BAA2B,EAI3B,SAAS,EACT,UAAU,EAEX,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAGV,KAAK,EAEL,qBAAqB,EAErB,aAAa,EACb,cAAc,EAMd,UAAU,EACV,UAAU,EAEV,cAAc,EAMd,KAAK,EAEL,kBAAkB,EAClB,MAAM,EACN,gBAAgB,EAEhB,SAAS,EAGT,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EACV,OAAO,EACP,aAAa,IAAI,iBAAiB,EACnC,MAAM,iCAAiC,CAAC;AA6CzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAUzD,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAwClC,MAAM,MAAM,gBAAgB,CAC1B,CAAC,SAAS,KAAK,EACf,CAAC,SAAS,QAAQ,EAClB,CAAC,SAAS,QAAQ,IAChB;IACF,MAAM,EAAE,CAAC,EAAE,CAAC;IACZ,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACxB,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,kBAAkB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAC7C,eAAe,CAAC,EAAE,wBAAwB,EAAE,CAAC;IAC7C,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,KAAK,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB,CAAC,CAAC;IACH;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC,gBAAgB,GAAG;QAC3C,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,KAAK,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,eAAe,CAAC,EAAE,KAAK,CAAC;YACxB,SAAS,CAAC,EAAE,KAAK,CAAC;YAClB,IAAI,CAAC,EAAE,OAAO,CAAC;YACf,MAAM,CAAC,EAAE,OAAO,CAAC;SAClB,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,kBAAkB,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,CAAC,SAAS,KAAK,EACf,CAAC,SAAS,QAAQ,EAClB,CAAC,SAAS,QAAQ,EAClB,6bA6BC,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,yCAylB3B,CAAC;AA8OF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,EAAE,KAAG,MAAM,EA2C5D,CAAC"}