@office-open/xlsx 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { AppProperties, BaseXmlComponent, ChartCollection, ChartSpace, Formatter, IgnoreIfEmptyXmlComponent, OoxmlMimeType, Relationships, buildCorePropertiesXmlString, compileMapping, createPacker, parseArchive, parseCorePropsElement, strFromU8, toJson, unzipSync, zipAndConvert } from "@office-open/core";
1
+ import { AppProperties, BaseXmlComponent, ChartCollection, ChartSpace, Formatter, IgnoreIfEmptyXmlComponent, OoxmlMimeType, Relationships, TargetModeType, buildCorePropertiesXmlString, compileMapping, createPacker, derivePasswordHash, parseArchive, parseCorePropsElement, strFromU8, toJson, toUint8Array, unzipSync, zipAndConvert } from "@office-open/core";
2
2
  import { attr, attrNum, attrs, escapeXml, findChild, js2xml, selfCloseElement, textOf } from "@office-open/xml";
3
- import { toUint8Array } from "undio";
3
+ import { DefaultTheme } from "@office-open/core/theme";
4
4
  //#region src/file/content-types.ts
5
5
  /**
6
6
  * Content Types module for XLSX packages.
@@ -9,6 +9,7 @@ import { toUint8Array } from "undio";
9
9
  */
10
10
  const XLSX_MAIN = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
11
11
  const XLSX_WORKSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml";
12
+ const XLSX_CHARTSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml";
12
13
  const XLSX_STYLES = "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml";
13
14
  const XLSX_SHARED_STRINGS = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml";
14
15
  const XLSX_THEME = "application/vnd.openxmlformats-officedocument.theme+xml";
@@ -52,6 +53,13 @@ var ContentTypes = class extends BaseXmlComponent {
52
53
  key: `/xl/worksheets/sheet${index}.xml`
53
54
  });
54
55
  }
56
+ addChartsheet(index) {
57
+ this.dynamicEntries.push({
58
+ type: "Override",
59
+ contentType: XLSX_CHARTSHEET,
60
+ key: `/xl/chartsheets/sheet${index}.xml`
61
+ });
62
+ }
55
63
  addStyles() {
56
64
  this.dynamicEntries.push({
57
65
  type: "Override",
@@ -132,6 +140,62 @@ var ContentTypes = class extends BaseXmlComponent {
132
140
  key: `/xl/pivotCache/pivotCacheRecords${index}.xml`
133
141
  });
134
142
  }
143
+ addTable(index) {
144
+ this.dynamicEntries.push({
145
+ type: "Override",
146
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml",
147
+ key: `/xl/tables/table${index}.xml`
148
+ });
149
+ }
150
+ addExternalLink(index) {
151
+ this.dynamicEntries.push({
152
+ type: "Override",
153
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml",
154
+ key: `/xl/externalLinks/externalLink${index}.xml`
155
+ });
156
+ }
157
+ addCalcChain() {
158
+ this.dynamicEntries.push({
159
+ type: "Override",
160
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml",
161
+ key: "/xl/calcChain.xml"
162
+ });
163
+ }
164
+ addDialogsheet(index) {
165
+ this.dynamicEntries.push({
166
+ type: "Override",
167
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml",
168
+ key: `/xl/dialogsheets/sheet${index}.xml`
169
+ });
170
+ }
171
+ addRevisionHeaders() {
172
+ this.dynamicEntries.push({
173
+ type: "Override",
174
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml",
175
+ key: "/xl/revisionHeaders.xml"
176
+ });
177
+ }
178
+ addRevisionLog(index) {
179
+ this.dynamicEntries.push({
180
+ type: "Override",
181
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml",
182
+ key: `/xl/revisions/revision${index}.xml`
183
+ });
184
+ }
185
+ addQueryTable(index) {
186
+ this.dynamicEntries.push({
187
+ type: "Override",
188
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml",
189
+ key: `/xl/queryTables/queryTable${index}.xml`
190
+ });
191
+ }
192
+ addMetadata() {
193
+ this.dynamicEntries.push({
194
+ type: "Override",
195
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
196
+ key: "/xl/metadata.xml"
197
+ });
198
+ }
135
199
  toXml(_context) {
136
200
  const p = ["<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">", STATIC_XML];
137
201
  for (const e of this.dynamicEntries) if (e.type === "Default") p.push(`<Default ContentType="${e.contentType}" Extension="${e.key}"/>`);
@@ -178,34 +242,81 @@ var Media = class {
178
242
  *
179
243
  * @module
180
244
  */
245
+ /**
246
+ * Build rich text run properties XML (CT_RPrElt).
247
+ * Exported for reuse by Comments and other components.
248
+ */
249
+ function buildRPrXml(pr) {
250
+ if (!pr) return "";
251
+ const parts = [];
252
+ if (pr.font) parts.push(`<rFont val="${escapeXml(pr.font)}"/>`);
253
+ if (pr.charset !== void 0) parts.push(`<charset val="${pr.charset}"/>`);
254
+ if (pr.family !== void 0) parts.push(`<family val="${pr.family}"/>`);
255
+ if (pr.bold) parts.push("<b/>");
256
+ if (pr.italic) parts.push("<i/>");
257
+ if (pr.strike) parts.push("<strike/>");
258
+ if (pr.outline) parts.push("<outline/>");
259
+ if (pr.shadow) parts.push("<shadow/>");
260
+ if (pr.condense) parts.push("<condense/>");
261
+ if (pr.extend) parts.push("<extend/>");
262
+ if (pr.color) parts.push(`<color rgb="${escapeXml(pr.color)}"/>`);
263
+ if (pr.size !== void 0) parts.push(`<sz val="${pr.size}"/>`);
264
+ if (pr.underline) if (pr.underline === "none") parts.push("<u/>");
265
+ else parts.push(`<u val="${pr.underline}"/>`);
266
+ if (pr.vertAlign) parts.push(`<vertAlign val="${pr.vertAlign}"/>`);
267
+ if (pr.scheme) parts.push(`<scheme val="${pr.scheme}"/>`);
268
+ return parts.length > 0 ? `<rPr>${parts.join("")}</rPr>` : "";
269
+ }
270
+ /** Build a CT_Rst XML string from RichTextOptions. */
271
+ function buildRstXml(rst) {
272
+ const parts = [];
273
+ if (rst.runs && rst.runs.length > 0) for (const run of rst.runs) {
274
+ const rPr = buildRPrXml(run.properties);
275
+ parts.push(`<r>${rPr}<t>${escapeXml(run.text)}</t></r>`);
276
+ }
277
+ else if (rst.text !== void 0) parts.push(`<t>${escapeXml(rst.text)}</t>`);
278
+ if (rst.phonetics) for (const ph of rst.phonetics) parts.push(`<rPh sb="${ph.sb}" eb="${ph.eb}"><t>${escapeXml(ph.text)}</t></rPh>`);
279
+ return parts.join("");
280
+ }
181
281
  var SharedStrings = class extends BaseXmlComponent {
182
- strings = [];
282
+ entries = [];
283
+ /** Dedup map for plain strings only. Rich text is not deduped. */
183
284
  indexMap = /* @__PURE__ */ new Map();
184
285
  constructor() {
185
286
  super("sst");
186
287
  }
187
288
  /**
188
- * Register a string and return its index.
289
+ * Register a plain string and return its index.
189
290
  * Returns existing index if the string is already registered.
190
291
  */
191
292
  register(s) {
192
293
  const existing = this.indexMap.get(s);
193
294
  if (existing !== void 0) return existing;
194
- const idx = this.strings.length;
195
- this.strings.push(s);
295
+ const idx = this.entries.length;
296
+ this.entries.push(s);
196
297
  this.indexMap.set(s, idx);
197
298
  return idx;
198
299
  }
300
+ /**
301
+ * Register a rich text entry and return its index.
302
+ * Rich text is not deduped (each call creates a new entry).
303
+ */
304
+ registerRich(rst) {
305
+ const idx = this.entries.length;
306
+ this.entries.push(rst);
307
+ return idx;
308
+ }
199
309
  get count() {
200
- return this.strings.length;
310
+ return this.entries.length;
201
311
  }
202
312
  /**
203
313
  * Zero-allocation fast path: directly concatenate XML string.
204
314
  * Bypasses the IXmlableObject intermediate tree entirely.
205
315
  */
206
316
  toXml(_context) {
207
- const p = ["<sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"", ` count="${this.strings.length}" uniqueCount="${this.indexMap.size}">`];
208
- for (const s of this.strings) p.push(`<si><t>${escapeXml(s)}</t></si>`);
317
+ const p = ["<sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"", ` count="${this.entries.length}" uniqueCount="${this.indexMap.size}">`];
318
+ for (const entry of this.entries) if (typeof entry === "string") p.push(`<si><t>${escapeXml(entry)}</t></si>`);
319
+ else p.push(`<si>${buildRstXml(entry)}</si>`);
209
320
  p.push("</sst>");
210
321
  return p.join("");
211
322
  }
@@ -221,14 +332,14 @@ var SharedStrings = class extends BaseXmlComponent {
221
332
  * @module
222
333
  */
223
334
  function fontKey(f) {
224
- return `b${f.bold ? 1 : 0}i${f.italic ? 1 : 0}u${f.underline ? 1 : 0}s${f.strike ? 1 : 0}z${f.size ?? 0}c${f.color ?? ""}n${f.fontName ?? ""}`;
335
+ return `b${f.bold ? 1 : 0}i${f.italic ? 1 : 0}u${f.underline ? 1 : 0}s${f.strike ? 1 : 0}z${f.size ?? 0}c${f.color ?? ""}n${f.fontName ?? ""}cs${f.charset ?? ""}fm${f.family ?? ""}co${f.condense ? 1 : 0}ex${f.extend ? 1 : 0}va${f.vertAlign ?? ""}sc${f.scheme ?? ""}sh${f.shadow ? 1 : 0}ol${f.outline ? 1 : 0}`;
225
336
  }
226
337
  function fillKey(f) {
227
- return `t${f.type ?? ""}c${f.color ?? ""}p${f.patternType ?? ""}`;
338
+ return `t${f.type ?? ""}c${f.color ?? ""}p${f.patternType ?? ""}bg${f.bgColor ?? ""}g${f.stops?.map((s) => `${s.position}_${s.color}`).join("|") ?? ""}`;
228
339
  }
229
340
  function borderKey(b) {
230
341
  const sk = (o) => `${o?.style ?? ""}_${o?.color ?? ""}`;
231
- return `t${sk(b.top)}b${sk(b.bottom)}l${sk(b.left)}r${sk(b.right)}d${sk(b.diagonal)}`;
342
+ return `t${sk(b.top)}b${sk(b.bottom)}l${sk(b.left)}r${sk(b.right)}d${sk(b.diagonal)}st${sk(b.start)}en${sk(b.end)}v${sk(b.vertical)}h${sk(b.horizontal)}`;
232
343
  }
233
344
  const BUILTIN_NUMFMTS = {
234
345
  General: 0,
@@ -278,6 +389,10 @@ var Styles = class extends BaseXmlComponent {
278
389
  }];
279
390
  cellXfKeys = /* @__PURE__ */ new Map();
280
391
  dxfs = [];
392
+ colors;
393
+ tableStyles;
394
+ /** Style sheet extensions (CT_ExtensionList) */
395
+ styleExtensions;
281
396
  constructor() {
282
397
  super("styleSheet");
283
398
  this.fontKeys.set(fontKey(this.fonts[0]), 0);
@@ -296,7 +411,10 @@ var Styles = class extends BaseXmlComponent {
296
411
  fillId: this.registerFill(opts.fill),
297
412
  borderId: this.registerBorder(opts.border),
298
413
  numFmtId: this.registerNumFmt(opts.numFmt),
299
- alignment: opts.alignment
414
+ alignment: opts.alignment,
415
+ quotePrefix: opts.quotePrefix,
416
+ pivotButton: opts.pivotButton,
417
+ protection: opts.protection
300
418
  };
301
419
  const key = this.cellXfKey(xf);
302
420
  const existing = this.cellXfKeys.get(key);
@@ -315,6 +433,18 @@ var Styles = class extends BaseXmlComponent {
315
433
  this.dxfs.push(opts);
316
434
  return idx;
317
435
  }
436
+ /**
437
+ * Set color palette (indexed colors and MRU colors).
438
+ */
439
+ setColors(opts) {
440
+ this.colors = opts;
441
+ }
442
+ setTableStyles(styles) {
443
+ this.tableStyles = styles;
444
+ }
445
+ setExtensions(extensions) {
446
+ this.styleExtensions = extensions;
447
+ }
318
448
  registerFont(opts) {
319
449
  if (!opts) return 0;
320
450
  const key = fontKey(opts);
@@ -357,8 +487,10 @@ var Styles = class extends BaseXmlComponent {
357
487
  }
358
488
  cellXfKey(xf) {
359
489
  const a = xf.alignment;
360
- const ak = a ? `h${a.horizontal ?? ""}v${a.vertical ?? ""}w${a.wrapText ? 1 : 0}r${a.textRotation ?? ""}i${a.indent ?? ""}` : "";
361
- return `${xf.fontId}|${xf.fillId}|${xf.borderId}|${xf.numFmtId}|${ak}`;
490
+ const ak = a ? `h${a.horizontal ?? ""}v${a.vertical ?? ""}w${a.wrapText ? 1 : 0}r${a.textRotation ?? ""}i${a.indent ?? ""}ri${a.relativeIndent ?? ""}jl${a.justifyLastLine ? 1 : 0}st${a.shrinkToFit ? 1 : 0}ro${a.readingOrder ?? ""}` : "";
491
+ const pr = xf.protection;
492
+ const pk = pr ? `l${pr.locked ?? ""}h${pr.hidden ?? ""}` : "";
493
+ return `${xf.fontId}|${xf.fillId}|${xf.borderId}|${xf.numFmtId}|${ak}|qp${xf.quotePrefix ? 1 : 0}|pb${xf.pivotButton ? 1 : 0}|${pk}`;
362
494
  }
363
495
  /**
364
496
  * Zero-allocation fast path: directly concatenate XML string.
@@ -375,10 +507,20 @@ var Styles = class extends BaseXmlComponent {
375
507
  for (const f of this.fonts) p.push(`<font>${this.fontXmlStr(f)}</font>`);
376
508
  p.push("</fonts>");
377
509
  p.push(`<fills count="${this.fills.length}">`);
378
- for (const f of this.fills) {
510
+ for (const f of this.fills) if (f.type === "gradient" && f.stops && f.stops.length > 0) {
511
+ const gfAttrs = {};
512
+ if (f.gradientType && f.gradientType !== "linear") gfAttrs.type = f.gradientType;
513
+ if (f.gradientDegree !== void 0) gfAttrs.degree = f.gradientDegree;
514
+ if (f.gradientLeft !== void 0) gfAttrs.left = f.gradientLeft;
515
+ if (f.gradientRight !== void 0) gfAttrs.right = f.gradientRight;
516
+ if (f.gradientTop !== void 0) gfAttrs.top = f.gradientTop;
517
+ if (f.gradientBottom !== void 0) gfAttrs.bottom = f.gradientBottom;
518
+ const stopParts = f.stops.map((s) => `<stop position="${s.position}"><color rgb="FF${s.color}"/></stop>`).join("");
519
+ p.push(`<fill><gradientFill${attrs(gfAttrs)}>${stopParts}</gradientFill></fill>`);
520
+ } else {
379
521
  const patternAttrs = attrs({ patternType: f.patternType ?? "solid" });
380
- const fgColor = f.color ? `<fgColor rgb="FF${f.color}"/>` : "";
381
- p.push(fgColor ? `<fill><patternFill${patternAttrs}>${fgColor}</patternFill></fill>` : `<fill><patternFill${patternAttrs}/></fill>`);
522
+ const colorContent = (f.color ? `<fgColor rgb="FF${f.color}"/>` : "") + (f.bgColor ? `<bgColor rgb="FF${f.bgColor}"/>` : "");
523
+ p.push(colorContent ? `<fill><patternFill${patternAttrs}>${colorContent}</patternFill></fill>` : `<fill><patternFill${patternAttrs}/></fill>`);
382
524
  }
383
525
  p.push("</fills>");
384
526
  p.push(`<borders count="${this.borders.length}">`);
@@ -398,8 +540,11 @@ var Styles = class extends BaseXmlComponent {
398
540
  if (xf.fontId > 0) xAttrs.applyFont = 1;
399
541
  if (xf.fillId > 0) xAttrs.applyFill = 1;
400
542
  if (xf.borderId > 0) xAttrs.applyBorder = 1;
401
- const alignStr = xf.alignment ? this.alignmentXmlStr(xf.alignment) : "";
402
- p.push(alignStr ? `<xf${attrs(xAttrs)}>${alignStr}</xf>` : `<xf${attrs(xAttrs)}/>`);
543
+ if (xf.numFmtId > 0) xAttrs.applyNumberFormat = 1;
544
+ if (xf.quotePrefix) xAttrs.quotePrefix = 1;
545
+ if (xf.pivotButton) xAttrs.pivotButton = 1;
546
+ const inner = (xf.alignment ? this.alignmentXmlStr(xf.alignment) : "") + (xf.protection ? this.protectionXmlStr(xf.protection) : "");
547
+ p.push(inner ? `<xf${attrs(xAttrs)}>${inner}</xf>` : `<xf${attrs(xAttrs)}/>`);
403
548
  }
404
549
  p.push("</cellXfs>");
405
550
  p.push("<cellStyles count=\"1\"><cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/></cellStyles>");
@@ -419,8 +564,48 @@ var Styles = class extends BaseXmlComponent {
419
564
  }
420
565
  p.push("</dxfs>");
421
566
  } else p.push("<dxfs count=\"0\"/>");
422
- p.push("<tableStyles count=\"0\" defaultTableStyle=\"TableStyleMedium2\" defaultPivotStyle=\"PivotStyleLight16\"/>");
423
- p.push("<extLst/>");
567
+ if (this.tableStyles && this.tableStyles.length > 0) {
568
+ const tsParts = [`<tableStyles count="${this.tableStyles.length}" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16">`];
569
+ for (const ts of this.tableStyles) {
570
+ const tsAttrs = [`name="${escapeXml(ts.name)}"`];
571
+ if (ts.pivot) tsAttrs.push("pivot=\"1\"");
572
+ if (ts.elements && ts.elements.length > 0) {
573
+ tsParts.push(`<tableStyle ${tsAttrs.join(" ")}>`);
574
+ for (const el of ts.elements) {
575
+ const elAttrs = [`type="${el.type}"`];
576
+ if (el.dxfId !== void 0) elAttrs.push(`dxfId="${el.dxfId}"`);
577
+ if (el.button) elAttrs.push("button=\"1\"");
578
+ tsParts.push(`<tableStyleElement ${elAttrs.join(" ")}/>`);
579
+ }
580
+ tsParts.push("</tableStyle>");
581
+ } else tsParts.push(`<tableStyle ${tsAttrs.join(" ")}/>`);
582
+ }
583
+ tsParts.push("</tableStyles>");
584
+ p.push(tsParts.join(""));
585
+ } else p.push("<tableStyles count=\"0\" defaultTableStyle=\"TableStyleMedium2\" defaultPivotStyle=\"PivotStyleLight16\"/>");
586
+ if (this.colors) {
587
+ const c = this.colors;
588
+ const colorParts = ["<colors>"];
589
+ if (c.indexedColors && c.indexedColors.length > 0) {
590
+ colorParts.push("<indexedColors>");
591
+ for (const ic of c.indexedColors) colorParts.push(`<rgbColor rgb="${ic.rgb}"/>`);
592
+ colorParts.push("</indexedColors>");
593
+ }
594
+ if (c.mruColors && c.mruColors.length > 0) {
595
+ colorParts.push("<mruColors>");
596
+ for (const mc of c.mruColors) colorParts.push(`<color rgb="FF${mc}"/>`);
597
+ colorParts.push("</mruColors>");
598
+ }
599
+ colorParts.push("</colors>");
600
+ p.push(colorParts.join(""));
601
+ }
602
+ if (this.styleExtensions && this.styleExtensions.length > 0) {
603
+ const extParts = ["<extLst>"];
604
+ for (const ext of this.styleExtensions) if (ext.content) extParts.push(`<ext uri="${ext.uri}">${ext.content}</ext>`);
605
+ else extParts.push(`<ext uri="${ext.uri}"/>`);
606
+ extParts.push("</extLst>");
607
+ p.push(extParts.join(""));
608
+ } else p.push("<extLst/>");
424
609
  p.push("</styleSheet>");
425
610
  return p.join("");
426
611
  }
@@ -430,26 +615,38 @@ var Styles = class extends BaseXmlComponent {
430
615
  if (f.italic) parts.push("<i/>");
431
616
  if (f.underline) parts.push("<u/>");
432
617
  if (f.strike) parts.push("<strike/>");
618
+ if (f.outline) parts.push("<outline/>");
619
+ if (f.shadow) parts.push("<shadow/>");
620
+ if (f.condense) parts.push("<condense/>");
621
+ if (f.extend) parts.push("<extend/>");
433
622
  if (f.size) parts.push(`<sz val="${f.size}"/>`);
434
623
  if (f.color) parts.push(`<color rgb="FF${f.color}"/>`);
435
624
  if (f.fontName) parts.push(`<name val="${escapeXml(f.fontName)}"/>`);
625
+ if (f.charset !== void 0) parts.push(`<charset val="${f.charset}"/>`);
626
+ if (f.family !== void 0) parts.push(`<family val="${f.family}"/>`);
627
+ if (f.vertAlign) parts.push(`<vertAlign val="${f.vertAlign}"/>`);
628
+ if (f.scheme) parts.push(`<scheme val="${f.scheme}"/>`);
436
629
  return parts.join("");
437
630
  }
438
631
  borderXmlStr(b) {
439
632
  const parts = [];
633
+ const renderSide = (name, opts, required = true) => {
634
+ if (opts && opts.style && opts.style !== "none") {
635
+ const colorStr = opts.color ? `<color rgb="FF${opts.color}"/>` : "";
636
+ parts.push(`<${name} style="${opts.style}">${colorStr}</${name}>`);
637
+ } else if (required) parts.push(`<${name}/>`);
638
+ };
440
639
  for (const side of [
441
640
  "left",
442
641
  "right",
443
642
  "top",
444
643
  "bottom",
445
- "diagonal"
446
- ]) {
447
- const opts = b[side];
448
- if (opts && opts.style && opts.style !== "none") {
449
- const colorStr = opts.color ? `<color rgb="FF${opts.color}"/>` : "";
450
- parts.push(`<${side} style="${opts.style}">${colorStr}</${side}>`);
451
- } else parts.push(`<${side}/>`);
452
- }
644
+ "diagonal",
645
+ "vertical",
646
+ "horizontal"
647
+ ]) renderSide(side, b[side]);
648
+ renderSide("start", b.start, false);
649
+ renderSide("end", b.end, false);
453
650
  return parts.join("");
454
651
  }
455
652
  alignmentXmlStr(a) {
@@ -459,29 +656,17 @@ var Styles = class extends BaseXmlComponent {
459
656
  if (a.wrapText) aAttrs.wrapText = 1;
460
657
  if (a.textRotation !== void 0) aAttrs.textRotation = a.textRotation;
461
658
  if (a.indent !== void 0) aAttrs.indent = a.indent;
659
+ if (a.relativeIndent !== void 0) aAttrs.relativeIndent = a.relativeIndent;
660
+ if (a.justifyLastLine) aAttrs.justifyLastLine = 1;
661
+ if (a.shrinkToFit) aAttrs.shrinkToFit = 1;
662
+ if (a.readingOrder !== void 0) aAttrs.readingOrder = a.readingOrder;
462
663
  return `<alignment${attrs(aAttrs)}/>`;
463
664
  }
464
- };
465
- //#endregion
466
- //#region src/file/theme.ts
467
- /**
468
- * Default theme for XLSX files — matches Microsoft Office's output structure.
469
- * Produces xl/theme/theme1.xml that Excel accepts without repair warnings.
470
- *
471
- * The theme XML is completely static — identical for every XLSX file.
472
- * Pre-serialized as a string constant to avoid building the IXmlableObject
473
- * tree and re-serializing on every compile.
474
- *
475
- * @module
476
- */
477
- const THEME_XML = "<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=\"44546A\"/></a:dk2><a:lt2><a:srgbClr val=\"E7E6E6\"/></a:lt2><a:accent1><a:srgbClr val=\"5B9BD5\"/></a:accent1><a:accent2><a:srgbClr val=\"ED7D31\"/></a:accent2><a:accent3><a:srgbClr val=\"A5A5A5\"/></a:accent3><a:accent4><a:srgbClr val=\"FFC000\"/></a:accent4><a:accent5><a:srgbClr val=\"4472C4\"/></a:accent5><a:accent6><a:srgbClr val=\"70AD47\"/></a:accent6><a:hlink><a:srgbClr val=\"0563C1\"/></a:hlink><a:folHlink><a:srgbClr val=\"954F72\"/></a:folHlink></a:clrScheme><a:fontScheme name=\"Office\"><a:majorFont><a:latin typeface=\"Calibri Light\" panose=\"020F0302020204030204\"/><a:ea typeface=\"\"/><a:cs typeface=\"\"/></a:majorFont><a:minorFont><a:latin typeface=\"Calibri\" panose=\"020F0502020204030204\"/><a:ea typeface=\"\"/><a:cs typeface=\"\"/></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:lumMod val=\"110000\"/><a:satMod val=\"105000\"/><a:tint val=\"67000\"/></a:schemeClr></a:gs><a:gs pos=\"50000\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"105000\"/><a:satMod val=\"103000\"/><a:tint val=\"73000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"105000\"/><a:satMod val=\"109000\"/><a:tint val=\"81000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"5400000\" scaled=\"0\"/></a:gradFill><a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"102000\"/><a:satMod val=\"103000\"/><a:tint val=\"94000\"/></a:schemeClr></a:gs><a:gs pos=\"50000\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"100000\"/><a:satMod val=\"110000\"/><a:shade val=\"100000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"99000\"/><a:satMod val=\"120000\"/><a:shade val=\"78000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"5400000\" scaled=\"0\"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w=\"6350\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/><a:miter lim=\"800000\"/></a:ln><a:ln w=\"12700\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/><a:miter lim=\"800000\"/></a:ln><a:ln w=\"19050\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/><a:miter lim=\"800000\"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"57150\" dist=\"19050\" dir=\"5400000\" algn=\"ctr\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"63000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:solidFill><a:schemeClr val=\"phClr\"><a:tint val=\"95000\"/><a:satMod val=\"170000\"/></a:schemeClr></a:solidFill><a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"102000\"/><a:satMod val=\"150000\"/><a:tint val=\"93000\"/><a:shade val=\"98000\"/></a:schemeClr></a:gs><a:gs pos=\"50000\"><a:schemeClr val=\"phClr\"><a:lumMod val=\"103000\"/><a:satMod val=\"130000\"/><a:tint val=\"98000\"/><a:shade val=\"90000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:satMod val=\"120000\"/><a:shade val=\"63000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"5400000\" scaled=\"0\"/></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>";
478
- var DefaultTheme = class extends BaseXmlComponent {
479
- constructor() {
480
- super("a:theme");
481
- }
482
- /** Return pre-cached static theme XML — zero allocation. */
483
- toXml(_context) {
484
- return THEME_XML;
665
+ protectionXmlStr(pr) {
666
+ const prAttrs = {};
667
+ if (pr.locked !== void 0) prAttrs.locked = pr.locked ? 1 : 0;
668
+ if (pr.hidden !== void 0) prAttrs.hidden = pr.hidden ? 1 : 0;
669
+ return `<protection${attrs(prAttrs)}/>`;
485
670
  }
486
671
  };
487
672
  //#endregion
@@ -494,32 +679,301 @@ var DefaultTheme = class extends BaseXmlComponent {
494
679
  var WorkbookXml = class extends BaseXmlComponent {
495
680
  sheets;
496
681
  pivotCaches;
497
- constructor(sheets, pivotCaches) {
682
+ protection;
683
+ customViews;
684
+ fileRecoveryPr;
685
+ functionGroupNames;
686
+ webPublishing;
687
+ fileSharing;
688
+ workbookPr;
689
+ calcPr;
690
+ bookView;
691
+ volTypes;
692
+ webPublishObjects;
693
+ constructor(sheets, pivotCaches, protection, customViews, fileRecoveryPr, functionGroups, webPublishing, fileSharing, workbookPr, calcPr, bookView, volTypes, webPublishObjects) {
498
694
  super("workbook");
499
695
  this.sheets = sheets;
500
696
  this.pivotCaches = pivotCaches ?? [];
697
+ this.protection = protection;
698
+ this.customViews = customViews;
699
+ this.fileRecoveryPr = fileRecoveryPr;
700
+ this.functionGroupNames = functionGroups ?? [];
701
+ this.webPublishing = webPublishing;
702
+ this.fileSharing = fileSharing;
703
+ this.workbookPr = workbookPr;
704
+ this.calcPr = calcPr;
705
+ this.bookView = bookView;
706
+ this.volTypes = volTypes;
707
+ this.webPublishObjects = webPublishObjects;
501
708
  }
502
709
  toXml(_context) {
503
- const p = [
504
- "<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"x15 xr xr6 xr10 xr2\" xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\" xmlns:xr=\"http://schemas.microsoft.com/office/spreadsheetml/2014/revision\" xmlns:xr6=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision6\" xmlns:xr10=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision10\" xmlns:xr2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/revision2\">",
505
- "<fileVersion appName=\"xl\" lastEdited=\"7\" lowestEdited=\"6\" rupBuild=\"29929\"/>",
506
- "<workbookPr/>",
507
- "<bookViews><workbookView xWindow=\"0\" yWindow=\"0\" windowWidth=\"28800\" windowHeight=\"12300\"/></bookViews>",
508
- "<sheets>"
509
- ];
710
+ const parts = ["<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"x15 xr xr6 xr10 xr2\" xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\" xmlns:xr=\"http://schemas.microsoft.com/office/spreadsheetml/2014/revision\" xmlns:xr6=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision6\" xmlns:xr10=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision10\" xmlns:xr2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/revision2\">", "<fileVersion appName=\"xl\" lastEdited=\"7\" lowestEdited=\"6\" rupBuild=\"29929\"/>"];
711
+ if (this.fileSharing) {
712
+ const fileSharing = this.fileSharing;
713
+ const fsAttrs = [];
714
+ if (fileSharing.readOnlyRecommended) fsAttrs.push("readOnlyRecommended=\"1\"");
715
+ if (fileSharing.userName) fsAttrs.push(`userName="${escapeXml(fileSharing.userName)}"`);
716
+ if (fileSharing.reservationPassword) {
717
+ fsAttrs.push(`reservationPassword="${escapeXml(fileSharing.reservationPassword)}"`);
718
+ if (fileSharing.hashValue === void 0) {
719
+ const derived = derivePasswordHash(fileSharing.reservationPassword);
720
+ fsAttrs.push(`algorithmName="${escapeXml(derived.algorithmName)}"`);
721
+ fsAttrs.push(`hashValue="${escapeXml(derived.hashValue)}"`);
722
+ fsAttrs.push(`saltValue="${escapeXml(derived.saltValue)}"`);
723
+ fsAttrs.push(`spinCount="${derived.spinCount}"`);
724
+ }
725
+ }
726
+ if (fileSharing.algorithmName) fsAttrs.push(`algorithmName="${escapeXml(fileSharing.algorithmName)}"`);
727
+ if (fileSharing.hashValue) fsAttrs.push(`hashValue="${escapeXml(fileSharing.hashValue)}"`);
728
+ if (fileSharing.saltValue) fsAttrs.push(`saltValue="${escapeXml(fileSharing.saltValue)}"`);
729
+ if (fileSharing.spinCount !== void 0) fsAttrs.push(`spinCount="${fileSharing.spinCount}"`);
730
+ if (fsAttrs.length > 0) parts.push(`<fileSharing ${fsAttrs.join(" ")}/>`);
731
+ }
732
+ if (this.workbookPr) {
733
+ const wbPr = this.workbookPr;
734
+ const wbPrAttrs = [];
735
+ if (wbPr.date1904) wbPrAttrs.push("date1904=\"1\"");
736
+ if (wbPr.defaultThemeVersion !== void 0) wbPrAttrs.push(`defaultThemeVersion="${wbPr.defaultThemeVersion}"`);
737
+ if (wbPr.showObjects) wbPrAttrs.push(`showObjects="${escapeXml(wbPr.showObjects)}"`);
738
+ if (wbPr.hidePivotFieldList) wbPrAttrs.push("hidePivotFieldList=\"1\"");
739
+ if (wbPr.allowRefreshQuery) wbPrAttrs.push("allowRefreshQuery=\"1\"");
740
+ if (wbPr.filterPrivacy) wbPrAttrs.push("filterPrivacy=\"1\"");
741
+ if (wbPr.backupFile) wbPrAttrs.push("backupFile=\"1\"");
742
+ if (wbPr.codeName) wbPrAttrs.push(`codeName="${escapeXml(wbPr.codeName)}"`);
743
+ if (wbPr.showBorderUnselectedTables) wbPrAttrs.push("showBorderUnselectedTables=\"1\"");
744
+ if (wbPr.promptedSolutions) wbPrAttrs.push("promptedSolutions=\"1\"");
745
+ if (wbPr.showInkAnnotation === false) wbPrAttrs.push("showInkAnnotation=\"0\"");
746
+ if (wbPr.saveExternalLinkValues === false) wbPrAttrs.push("saveExternalLinkValues=\"0\"");
747
+ if (wbPr.updateLinks) wbPrAttrs.push(`updateLinks="${escapeXml(wbPr.updateLinks)}"`);
748
+ if (wbPr.showPivotChartFilter) wbPrAttrs.push("showPivotChartFilter=\"1\"");
749
+ if (wbPr.publishItems) wbPrAttrs.push("publishItems=\"1\"");
750
+ if (wbPr.checkCompatibility) wbPrAttrs.push("checkCompatibility=\"1\"");
751
+ if (wbPr.autoCompressPictures === false) wbPrAttrs.push("autoCompressPictures=\"0\"");
752
+ if (wbPr.refreshAllConnections) wbPrAttrs.push("refreshAllConnections=\"1\"");
753
+ parts.push(`<workbookPr${wbPrAttrs.length > 0 ? ` ${wbPrAttrs.join(" ")}` : ""}/>`);
754
+ } else parts.push("<workbookPr/>");
755
+ if (this.protection) {
756
+ const prot = this.protection;
757
+ const protAttrs = [];
758
+ if (prot.lockStructure) protAttrs.push("lockStructure=\"1\"");
759
+ if (prot.lockWindows) protAttrs.push("lockWindows=\"1\"");
760
+ if (prot.lockRevision) protAttrs.push("lockRevision=\"1\"");
761
+ if (prot.workbookPassword) {
762
+ protAttrs.push(`workbookPassword="${this.hashPassword(prot.workbookPassword)}"`);
763
+ if (prot.workbookHashValue === void 0) {
764
+ const wbDerived = derivePasswordHash(prot.workbookPassword);
765
+ protAttrs.push(`workbookAlgorithmName="${escapeXml(wbDerived.algorithmName)}"`);
766
+ protAttrs.push(`workbookHashValue="${escapeXml(wbDerived.hashValue)}"`);
767
+ protAttrs.push(`workbookSaltValue="${escapeXml(wbDerived.saltValue)}"`);
768
+ protAttrs.push(`workbookSpinCount="${wbDerived.spinCount}"`);
769
+ }
770
+ }
771
+ if (prot.workbookAlgorithmName) protAttrs.push(`workbookAlgorithmName="${escapeXml(prot.workbookAlgorithmName)}"`);
772
+ if (prot.workbookHashValue) protAttrs.push(`workbookHashValue="${escapeXml(prot.workbookHashValue)}"`);
773
+ if (prot.workbookSaltValue) protAttrs.push(`workbookSaltValue="${escapeXml(prot.workbookSaltValue)}"`);
774
+ if (prot.workbookSpinCount !== void 0) protAttrs.push(`workbookSpinCount="${prot.workbookSpinCount}"`);
775
+ if (prot.revisionsPassword) {
776
+ protAttrs.push(`revisionsPassword="${this.hashPassword(prot.revisionsPassword)}"`);
777
+ if (prot.revisionsHashValue === void 0) {
778
+ const revDerived = derivePasswordHash(prot.revisionsPassword);
779
+ protAttrs.push(`revisionsAlgorithmName="${escapeXml(revDerived.algorithmName)}"`);
780
+ protAttrs.push(`revisionsHashValue="${escapeXml(revDerived.hashValue)}"`);
781
+ protAttrs.push(`revisionsSaltValue="${escapeXml(revDerived.saltValue)}"`);
782
+ protAttrs.push(`revisionsSpinCount="${revDerived.spinCount}"`);
783
+ }
784
+ }
785
+ if (prot.revisionsAlgorithmName) protAttrs.push(`revisionsAlgorithmName="${escapeXml(prot.revisionsAlgorithmName)}"`);
786
+ if (prot.revisionsHashValue) protAttrs.push(`revisionsHashValue="${escapeXml(prot.revisionsHashValue)}"`);
787
+ if (prot.revisionsSaltValue) protAttrs.push(`revisionsSaltValue="${escapeXml(prot.revisionsSaltValue)}"`);
788
+ if (prot.revisionsSpinCount !== void 0) protAttrs.push(`revisionsSpinCount="${prot.revisionsSpinCount}"`);
789
+ if (protAttrs.length > 0) parts.push(`<workbookProtection ${protAttrs.join(" ")}/>`);
790
+ }
791
+ if (this.bookView) {
792
+ const bv = this.bookView;
793
+ const bvAttrs = [];
794
+ if (bv.xWindow !== void 0) bvAttrs.push(`xWindow="${bv.xWindow}"`);
795
+ else bvAttrs.push("xWindow=\"0\"");
796
+ if (bv.yWindow !== void 0) bvAttrs.push(`yWindow="${bv.yWindow}"`);
797
+ else bvAttrs.push("yWindow=\"0\"");
798
+ if (bv.windowWidth !== void 0) bvAttrs.push(`windowWidth="${bv.windowWidth}"`);
799
+ else bvAttrs.push("windowWidth=\"28800\"");
800
+ if (bv.windowHeight !== void 0) bvAttrs.push(`windowHeight="${bv.windowHeight}"`);
801
+ else bvAttrs.push("windowHeight=\"12300\"");
802
+ if (bv.activeTab !== void 0) bvAttrs.push(`activeTab="${bv.activeTab}"`);
803
+ if (bv.autoFilterDateGrouping === false) bvAttrs.push("autoFilterDateGrouping=\"0\"");
804
+ if (bv.firstSheet !== void 0) bvAttrs.push(`firstSheet="${bv.firstSheet}"`);
805
+ if (bv.showHorizontalScroll === false) bvAttrs.push("showHorizontalScroll=\"0\"");
806
+ if (bv.showSheetTabs === false) bvAttrs.push("showSheetTabs=\"0\"");
807
+ if (bv.showVerticalScroll === false) bvAttrs.push("showVerticalScroll=\"0\"");
808
+ if (bv.tabRatio !== void 0) bvAttrs.push(`tabRatio="${bv.tabRatio}"`);
809
+ parts.push(`<bookViews><workbookView ${bvAttrs.join(" ")}/></bookViews>`);
810
+ } else parts.push("<bookViews><workbookView xWindow=\"0\" yWindow=\"0\" windowWidth=\"28800\" windowHeight=\"12300\"/></bookViews>");
811
+ parts.push("<sheets>");
510
812
  for (const s of this.sheets) {
511
813
  const stateAttr = s.state && s.state !== "visible" ? ` state="${s.state}"` : "";
512
- p.push(`<sheet name="${escapeXml(s.name)}" sheetId="${s.sheetId}" r:id="${s.rId}"${stateAttr}/>`);
814
+ parts.push(`<sheet name="${escapeXml(s.name)}" sheetId="${s.sheetId}" r:id="${s.rId}"${stateAttr}/>`);
815
+ }
816
+ parts.push("</sheets>");
817
+ if (this.functionGroupNames.length > 0) {
818
+ const functionGroupParts = [`<functionGroups builtInGroupCount="16">`];
819
+ for (const name of this.functionGroupNames) functionGroupParts.push(`<functionGroup name="${escapeXml(name)}"/>`);
820
+ functionGroupParts.push("</functionGroups>");
821
+ parts.push(functionGroupParts.join(""));
822
+ }
823
+ parts.push("<!--EXTERNAL_REFS-->");
824
+ if (this.calcPr) {
825
+ const cp = this.calcPr;
826
+ const cpAttrs = [];
827
+ cpAttrs.push(`calcId="${cp.calcId ?? 162913}"`);
828
+ if (cp.calcMode) cpAttrs.push(`calcMode="${escapeXml(cp.calcMode)}"`);
829
+ if (cp.fullCalcOnLoad) cpAttrs.push("fullCalcOnLoad=\"1\"");
830
+ if (cp.calcOnSave === false) cpAttrs.push("calcOnSave=\"0\"");
831
+ if (cp.forceFullCalc) cpAttrs.push("forceFullCalc=\"1\"");
832
+ if (cp.concurrentCalc === false) cpAttrs.push("concurrentCalc=\"0\"");
833
+ if (cp.concurrentManualCount !== void 0) cpAttrs.push(`concurrentManualCount="${cp.concurrentManualCount}"`);
834
+ if (cp.iterate) cpAttrs.push("iterate=\"1\"");
835
+ if (cp.iterateCount !== void 0) cpAttrs.push(`iterateCount="${cp.iterateCount}"`);
836
+ if (cp.iterateDelta !== void 0) cpAttrs.push(`iterateDelta="${cp.iterateDelta}"`);
837
+ if (cp.refMode) cpAttrs.push(`refMode="${escapeXml(cp.refMode)}"`);
838
+ if (cp.fullPrecision === false) cpAttrs.push("fullPrecision=\"0\"");
839
+ if (cp.calcCompleted) cpAttrs.push("calcCompleted=\"1\"");
840
+ parts.push(`<calcPr ${cpAttrs.join(" ")}/>`);
841
+ } else parts.push("<calcPr calcId=\"162913\"/>");
842
+ if (this.customViews && this.customViews.length > 0) {
843
+ parts.push("<customWorkbookViews>");
844
+ for (const v of this.customViews) {
845
+ const vAttrs = [
846
+ `name="${escapeXml(v.name)}"`,
847
+ `guid="${escapeXml(v.guid)}"`,
848
+ `windowWidth="${v.windowWidth}"`,
849
+ `windowHeight="${v.windowHeight}"`,
850
+ `activeSheetId="${v.activeSheetId}"`
851
+ ];
852
+ if (v.xWindow !== void 0) vAttrs.push(`xWindow="${v.xWindow}"`);
853
+ if (v.yWindow !== void 0) vAttrs.push(`yWindow="${v.yWindow}"`);
854
+ if (v.showFormulaBar === false) vAttrs.push("showFormulaBar=\"0\"");
855
+ if (v.showStatusbar === false) vAttrs.push("showStatusbar=\"0\"");
856
+ if (v.showHorizontalScroll === false) vAttrs.push("showHorizontalScroll=\"0\"");
857
+ if (v.showVerticalScroll === false) vAttrs.push("showVerticalScroll=\"0\"");
858
+ if (v.showSheetTabs === false) vAttrs.push("showSheetTabs=\"0\"");
859
+ if (v.tabRatio !== void 0) vAttrs.push(`tabRatio="${v.tabRatio}"`);
860
+ if (v.includeHiddenRowCol === false) vAttrs.push("includeHiddenRowCol=\"0\"");
861
+ if (v.includePrintSettings === false) vAttrs.push("includePrintSettings=\"0\"");
862
+ if (v.personalView) vAttrs.push("personalView=\"1\"");
863
+ if (v.maximized) vAttrs.push("maximized=\"1\"");
864
+ if (v.minimized) vAttrs.push("minimized=\"1\"");
865
+ if (v.autoUpdate) vAttrs.push("autoUpdate=\"1\"");
866
+ if (v.mergeInterval !== void 0) vAttrs.push(`mergeInterval="${v.mergeInterval}"`);
867
+ if (v.changesSavedWin) vAttrs.push("changesSavedWin=\"1\"");
868
+ if (v.onlySync) vAttrs.push("onlySync=\"1\"");
869
+ if (v.showComments) vAttrs.push(`showComments="${escapeXml(v.showComments)}"`);
870
+ parts.push(`<customWorkbookView ${vAttrs.join(" ")}/>`);
871
+ }
872
+ parts.push("</customWorkbookViews>");
513
873
  }
514
- p.push("</sheets>");
515
- p.push("<calcPr calcId=\"162913\"/>");
516
874
  if (this.pivotCaches.length > 0) {
517
- p.push("<pivotCaches>");
518
- for (const pc of this.pivotCaches) p.push(`<pivotCache cacheId="${pc.cacheId}" r:id="${pc.rId}"/>`);
519
- p.push("</pivotCaches>");
875
+ parts.push("<pivotCaches>");
876
+ for (const pc of this.pivotCaches) parts.push(`<pivotCache cacheId="${pc.cacheId}" r:id="${pc.rId}"/>`);
877
+ parts.push("</pivotCaches>");
520
878
  }
521
- p.push("</workbook>");
522
- return p.join("");
879
+ if (this.webPublishing) {
880
+ const webPublishing = this.webPublishing;
881
+ const wpAttrs = [];
882
+ if (webPublishing.css === false) wpAttrs.push("css=\"0\"");
883
+ if (webPublishing.thicket === false) wpAttrs.push("thicket=\"0\"");
884
+ if (webPublishing.longFileNames === false) wpAttrs.push("longFileNames=\"0\"");
885
+ if (webPublishing.vml) wpAttrs.push("vml=\"1\"");
886
+ if (webPublishing.allowPng) wpAttrs.push("allowPng=\"1\"");
887
+ if (webPublishing.targetScreenSize && webPublishing.targetScreenSize !== "800x600") wpAttrs.push(`targetScreenSize="${webPublishing.targetScreenSize}"`);
888
+ if (webPublishing.dpi !== void 0 && webPublishing.dpi !== 96) wpAttrs.push(`dpi="${webPublishing.dpi}"`);
889
+ if (webPublishing.codePage !== void 0) wpAttrs.push(`codePage="${webPublishing.codePage}"`);
890
+ if (webPublishing.characterSet) wpAttrs.push(`characterSet="${escapeXml(webPublishing.characterSet)}"`);
891
+ parts.push(`<webPublishing ${wpAttrs.join(" ")}/>`);
892
+ }
893
+ if (this.fileRecoveryPr) {
894
+ const fileRecovery = this.fileRecoveryPr;
895
+ const frpAttrs = [];
896
+ if (fileRecovery.autoRecover === false) frpAttrs.push("autoRecover=\"0\"");
897
+ if (fileRecovery.crashSave) frpAttrs.push("crashSave=\"1\"");
898
+ if (fileRecovery.dataExtractLoad) frpAttrs.push("dataExtractLoad=\"1\"");
899
+ if (fileRecovery.repairLoad) frpAttrs.push("repairLoad=\"1\"");
900
+ if (frpAttrs.length > 0) parts.push(`<fileRecoveryPr ${frpAttrs.join(" ")}/>`);
901
+ }
902
+ if (this.webPublishObjects && this.webPublishObjects.length > 0) {
903
+ const wpoParts = [`<webPublishObjects count="${this.webPublishObjects.length}">`];
904
+ for (const wpo of this.webPublishObjects) {
905
+ const wpoAttrs = [`r:id="${escapeXml(wpo.rId)}"`];
906
+ if (wpo.destinationFile) wpoAttrs.push(`destinationFile="${escapeXml(wpo.destinationFile)}"`);
907
+ if (wpo.autoRepublish) wpoAttrs.push("autoRepublish=\"1\"");
908
+ if (wpo.title) wpoAttrs.push(`title="${escapeXml(wpo.title)}"`);
909
+ if (wpo.sourceObject) wpoAttrs.push(`sourceObject="${escapeXml(wpo.sourceObject)}"`);
910
+ wpoParts.push(`<webPublishObject ${wpoAttrs.join(" ")}/>`);
911
+ }
912
+ wpoParts.push("</webPublishObjects>");
913
+ parts.push(wpoParts.join(""));
914
+ }
915
+ if (this.volTypes && this.volTypes.length > 0) {
916
+ const vtParts = [`<volTypes count="${this.volTypes.length}">`];
917
+ for (const vt of this.volTypes) {
918
+ const vtType = vt.type ?? "realTimeData";
919
+ const mains = vt.mains ?? [];
920
+ if (mains.length > 0) {
921
+ const mainParts = [];
922
+ for (const m of mains) {
923
+ const tpParts = [];
924
+ for (const topic of m.topics ?? []) {
925
+ let tpInner = `<v>${escapeXml(topic.value)}</v>`;
926
+ for (const stp of topic.stringTopics ?? []) tpInner += `<stp>${escapeXml(stp)}</stp>`;
927
+ for (const tr of topic.refs ?? []) tpInner += `<tr r="${escapeXml(tr.reference)}" s="${tr.sheetIndex}"/>`;
928
+ const tpAttr = topic.valueType && topic.valueType !== "n" ? ` t="${escapeXml(topic.valueType)}"` : "";
929
+ tpParts.push(`<tp${tpAttr}>${tpInner}</tp>`);
930
+ }
931
+ mainParts.push(`<main first="${escapeXml(m.first)}">${tpParts.join("")}</main>`);
932
+ }
933
+ vtParts.push(`<volType type="${vtType}">${mainParts.join("")}</volType>`);
934
+ } else vtParts.push(`<volType type="${vtType}"/>`);
935
+ }
936
+ vtParts.push("</volTypes>");
937
+ parts.push(vtParts.join(""));
938
+ }
939
+ parts.push("</workbook>");
940
+ return parts.join("");
941
+ }
942
+ /**
943
+ * Generate tableParts XML fragment for embedding in a worksheet.
944
+ * This is called by the compiler to insert table references into the worksheet XML.
945
+ */
946
+ static buildTablePartsXml(tableParts) {
947
+ if (tableParts.length === 0) return "";
948
+ const parts = [`<tableParts count="${tableParts.length}">`];
949
+ for (const tp of tableParts) parts.push(`<tablePart r:id="${tp.rId}"/>`);
950
+ parts.push("</tableParts>");
951
+ return parts.join("");
952
+ }
953
+ /**
954
+ * Generate externalReferences XML fragment for embedding in the workbook.
955
+ * This is called by the compiler to insert external reference entries.
956
+ */
957
+ static buildExternalReferencesXml(refs) {
958
+ if (refs.length === 0) return "";
959
+ const parts = ["<externalReferences>"];
960
+ for (const ref of refs) parts.push(`<externalReference r:id="${ref.rId}"/>`);
961
+ parts.push("</externalReferences>");
962
+ return parts.join("");
963
+ }
964
+ /** Legacy Excel password hash (XOR-based) */
965
+ hashPassword(password) {
966
+ let hash = 0;
967
+ for (let i = 0; i < password.length; i++) {
968
+ const c = password.charCodeAt(i);
969
+ hash = (hash >> 14 & 1) + (hash << 1 & 32767);
970
+ hash ^= c;
971
+ hash = hash & 16384 ? hash ^ 1 : hash;
972
+ }
973
+ hash = (hash >> 14 & 1) + (hash << 1 & 32767);
974
+ hash = (hash >> 14 & 1) + (hash << 1 & 32767);
975
+ hash ^= password.length;
976
+ return hash.toString(16).toUpperCase().padStart(4, "0");
523
977
  }
524
978
  };
525
979
  //#endregion
@@ -541,6 +995,8 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
541
995
  mergeCells;
542
996
  freezePanes;
543
997
  protection;
998
+ protectedRanges;
999
+ scenarioOpts;
544
1000
  autoFilter;
545
1001
  images;
546
1002
  chartOptions;
@@ -553,6 +1009,28 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
553
1009
  tabColor;
554
1010
  sheetView;
555
1011
  pivotTableOptions;
1012
+ tableOptions;
1013
+ ignoredErrors;
1014
+ phoneticPr;
1015
+ backgroundImage;
1016
+ printOptions;
1017
+ sheetFormatPr;
1018
+ sheetPr;
1019
+ rowBreaks;
1020
+ colBreaks;
1021
+ customSheetViews;
1022
+ cellWatches;
1023
+ dataConsolidate;
1024
+ oleSize;
1025
+ drawingHF;
1026
+ legacyDrawingHF;
1027
+ selection;
1028
+ sheetCalcPr;
1029
+ ext;
1030
+ controls;
1031
+ customProperties;
1032
+ oleObjects;
1033
+ webPublishItems;
556
1034
  constructor(options) {
557
1035
  super("worksheet");
558
1036
  this.rows = options.rows ?? [];
@@ -560,6 +1038,8 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
560
1038
  this.mergeCells = options.mergeCells ?? [];
561
1039
  this.freezePanes = options.freezePanes;
562
1040
  this.protection = options.protection;
1041
+ this.protectedRanges = options.protectedRanges ?? [];
1042
+ this.scenarioOpts = options.scenarios;
563
1043
  this.autoFilter = options.autoFilter;
564
1044
  this.images = options.images ?? [];
565
1045
  this.chartOptions = options.charts ?? [];
@@ -572,6 +1052,28 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
572
1052
  this.tabColor = options.tabColor;
573
1053
  this.sheetView = options.sheetView;
574
1054
  this.pivotTableOptions = options.pivotTables ?? [];
1055
+ this.tableOptions = options.tables ?? [];
1056
+ this.ignoredErrors = options.ignoredErrors ?? [];
1057
+ this.phoneticPr = options.phoneticPr;
1058
+ this.backgroundImage = options.backgroundImage;
1059
+ this.printOptions = options.printOptions;
1060
+ this.sheetFormatPr = options.sheetFormatPr;
1061
+ this.sheetPr = options.sheetPr;
1062
+ this.rowBreaks = options.rowBreaks ?? [];
1063
+ this.colBreaks = options.colBreaks ?? [];
1064
+ this.customSheetViews = options.customSheetViews ?? [];
1065
+ this.cellWatches = options.cellWatches ?? [];
1066
+ this.dataConsolidate = options.dataConsolidate;
1067
+ this.oleSize = options.oleSize;
1068
+ this.drawingHF = options.drawingHF;
1069
+ this.legacyDrawingHF = options.legacyDrawingHF;
1070
+ this.selection = options.selection;
1071
+ this.sheetCalcPr = options.sheetCalcPr;
1072
+ this.ext = options.ext;
1073
+ this.controls = options.controls ?? [];
1074
+ this.customProperties = options.customProperties ?? [];
1075
+ this.oleObjects = options.oleObjects ?? [];
1076
+ this.webPublishItems = options.webPublishItems ?? [];
575
1077
  }
576
1078
  get imageOptions() {
577
1079
  return this.images;
@@ -591,6 +1093,12 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
591
1093
  get pivotTables() {
592
1094
  return this.pivotTableOptions;
593
1095
  }
1096
+ get tables() {
1097
+ return this.tableOptions;
1098
+ }
1099
+ get background() {
1100
+ return this.backgroundImage;
1101
+ }
594
1102
  /**
595
1103
  * Zero-allocation fast path: directly concatenate XML string.
596
1104
  * Bypasses the IXmlableObject intermediate tree entirely.
@@ -602,8 +1110,19 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
602
1110
  const p = ["<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"x14ac xr xr2 xr3\" xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" xmlns:xr=\"http://schemas.microsoft.com/office/spreadsheetml/2014/revision\" xmlns:xr2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/revision2\" xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\">"];
603
1111
  const hasTabColor = !!this.tabColor;
604
1112
  const hasOutline = this.columns.some((c) => c.outlineLevel !== void 0);
605
- if (hasTabColor || hasOutline) {
1113
+ const sp = this.sheetPr;
1114
+ const hasSheetPrAttrs = sp && (sp.syncHorizontal || sp.syncVertical || sp.syncRef || sp.transitionEvaluation || sp.transitionEntry || sp.published || sp.filterMode || sp.enableFormatConditionsCalculation);
1115
+ if (hasTabColor || hasOutline || hasSheetPrAttrs) {
606
1116
  const prParts = [];
1117
+ const prAttrs = {};
1118
+ if (sp?.syncHorizontal) prAttrs.syncHorizontal = 1;
1119
+ if (sp?.syncVertical) prAttrs.syncVertical = 1;
1120
+ if (sp?.syncRef) prAttrs.syncRef = sp.syncRef;
1121
+ if (sp?.transitionEvaluation) prAttrs.transitionEvaluation = 1;
1122
+ if (sp?.transitionEntry) prAttrs.transitionEntry = 1;
1123
+ if (sp?.published) prAttrs.published = 1;
1124
+ if (sp?.filterMode) prAttrs.filterMode = 1;
1125
+ if (sp?.enableFormatConditionsCalculation) prAttrs.enableFormatConditionsCalculation = 1;
607
1126
  if (this.tabColor) {
608
1127
  const tc = this.tabColor;
609
1128
  const tcAttrs = {};
@@ -612,8 +1131,18 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
612
1131
  if (tc.tint !== void 0) tcAttrs.tint = tc.tint;
613
1132
  prParts.push(`<tabColor${attrs(tcAttrs)}/>`);
614
1133
  }
615
- if (hasOutline) prParts.push("<outlinePr summaryBelow=\"1\" summaryRight=\"1\"/>");
616
- p.push(`<sheetPr>${prParts.join("")}</sheetPr>`);
1134
+ if (hasOutline) {
1135
+ const outAttrs = {
1136
+ summaryBelow: 1,
1137
+ summaryRight: 1
1138
+ };
1139
+ if (sp?.outlineApplyStyles) outAttrs.applyStyles = 1;
1140
+ if (sp?.outlineShowSymbols === false) outAttrs.showOutlineSymbols = 0;
1141
+ prParts.push(`<outlinePr${attrs(outAttrs)}/>`);
1142
+ }
1143
+ if (this.pageSetup?.fitToWidth || this.pageSetup?.fitToHeight) prParts.push("<pageSetUpPr fitToPage=\"1\"/>");
1144
+ const prAttrStr = Object.keys(prAttrs).length > 0 ? attrs(prAttrs) : "";
1145
+ p.push(`<sheetPr${prAttrStr}>${prParts.join("")}</sheetPr>`);
617
1146
  }
618
1147
  const maxRow = this.rows.length;
619
1148
  let maxCol = 0;
@@ -622,6 +1151,7 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
622
1151
  const dimRef = `A1:${this.defaultCellRef(maxRow, maxCol)}`;
623
1152
  p.push(`<dimension ref="${dimRef}"/>`);
624
1153
  }
1154
+ const pivotSelXml = this.sheetView?.pivotSelections ? this.sheetView.pivotSelections.map((ps) => this.buildPivotSelectionXml(ps)).join("") : "";
625
1155
  if (this.freezePanes) {
626
1156
  const fp = this.freezePanes;
627
1157
  const ySplit = fp.row ? fp.row : 0;
@@ -631,12 +1161,26 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
631
1161
  const topLeftCell = this.defaultCellRef(topRow, leftCol);
632
1162
  const activePane = ySplit > 0 && xSplit > 0 ? "bottomRight" : ySplit > 0 ? "bottomLeft" : "topRight";
633
1163
  const svAttrs = this.buildSheetViewAttrs();
634
- p.push(`<sheetViews><sheetView${svAttrs}>`, `<pane ySplit="${ySplit}" xSplit="${xSplit}" topLeftCell="${topLeftCell}" activePane="${activePane}" state="frozen"/>`, "</sheetView></sheetViews>");
1164
+ p.push(`<sheetViews><sheetView${svAttrs}>`, `<pane ySplit="${ySplit}" xSplit="${xSplit}" topLeftCell="${topLeftCell}" activePane="${activePane}" state="frozen"/>`, this.selection ? this.buildSelectionXml(this.selection) : "", pivotSelXml, "</sheetView></sheetViews>");
635
1165
  } else {
636
1166
  const svAttrs = this.buildSheetViewAttrs();
637
- p.push(`<sheetViews><sheetView${svAttrs}/></sheetViews>`);
1167
+ const innerXml = (this.selection ? this.buildSelectionXml(this.selection) : "") + pivotSelXml;
1168
+ if (innerXml) p.push(`<sheetViews><sheetView${svAttrs}>${innerXml}</sheetView></sheetViews>`);
1169
+ else p.push(`<sheetViews><sheetView${svAttrs}/></sheetViews>`);
638
1170
  }
639
- p.push("<sheetFormatPr defaultRowHeight=\"15\"/>");
1171
+ if (this.sheetFormatPr) {
1172
+ const sfp = this.sheetFormatPr;
1173
+ const sfpAttrs = {};
1174
+ if (sfp.baseColWidth !== void 0) sfpAttrs.baseColWidth = sfp.baseColWidth;
1175
+ if (sfp.defaultColWidth !== void 0) sfpAttrs.defaultColWidth = sfp.defaultColWidth;
1176
+ sfpAttrs.defaultRowHeight = sfp.defaultRowHeight ?? 15;
1177
+ if (sfp.zeroHeight) sfpAttrs.zeroHeight = 1;
1178
+ if (sfp.thickTop) sfpAttrs.thickTop = 1;
1179
+ if (sfp.thickBottom) sfpAttrs.thickBottom = 1;
1180
+ if (sfp.outlineLevelRow !== void 0) sfpAttrs.outlineLevelRow = sfp.outlineLevelRow;
1181
+ if (sfp.outlineLevelCol !== void 0) sfpAttrs.outlineLevelCol = sfp.outlineLevelCol;
1182
+ p.push(`<sheetFormatPr${attrs(sfpAttrs)}/>`);
1183
+ } else p.push("<sheetFormatPr defaultRowHeight=\"15\"/>");
640
1184
  if (this.columns.length > 0) {
641
1185
  p.push("<cols>");
642
1186
  for (const col of this.columns) {
@@ -651,6 +1195,8 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
651
1195
  if (col.hidden) colAttrs.hidden = 1;
652
1196
  if (col.outlineLevel !== void 0) colAttrs.outlineLevel = col.outlineLevel;
653
1197
  if (col.collapsed) colAttrs.collapsed = 1;
1198
+ if (col.bestFit) colAttrs.bestFit = 1;
1199
+ if (col.phonetic) colAttrs.phonetic = 1;
654
1200
  p.push(selfCloseElement("col", attrs(colAttrs)));
655
1201
  }
656
1202
  p.push("</cols>");
@@ -665,6 +1211,11 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
665
1211
  rowAttrs.customHeight = 1;
666
1212
  }
667
1213
  if (rowOpts.hidden) rowAttrs.hidden = 1;
1214
+ if (rowOpts.spans) rowAttrs.spans = rowOpts.spans;
1215
+ if (rowOpts.customFormat) rowAttrs.customFormat = 1;
1216
+ if (rowOpts.thickTop) rowAttrs.thickTop = 1;
1217
+ if (rowOpts.thickBot) rowAttrs.thickBot = 1;
1218
+ if (rowOpts.ph) rowAttrs.ph = 1;
668
1219
  if (rowOpts.cells) {
669
1220
  const rowParts = [];
670
1221
  for (let j = 0; j < rowOpts.cells.length; j++) {
@@ -677,10 +1228,92 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
677
1228
  } else p.push(`<row${attrs(rowAttrs)}/>`);
678
1229
  }
679
1230
  p.push("</sheetData>");
1231
+ if (this.sheetCalcPr) {
1232
+ const scAttrs = [];
1233
+ if (this.sheetCalcPr.fullCalcOnLoad) scAttrs.push("fullCalcOnLoad=\"1\"");
1234
+ p.push(`<sheetCalcPr${scAttrs.length ? " " + scAttrs.join(" ") : ""}/>`);
1235
+ }
1236
+ if (this.rowBreaks.length > 0) {
1237
+ const brkParts = this.rowBreaks.map((b) => {
1238
+ const bAttrs = { id: b.id };
1239
+ if (b.min !== void 0) bAttrs.min = b.min;
1240
+ if (b.max !== void 0) bAttrs.max = b.max;
1241
+ if (b.manual) bAttrs.man = 1;
1242
+ if (b.pivot) bAttrs.pt = 1;
1243
+ return `<brk${attrs(bAttrs)}/>`;
1244
+ });
1245
+ p.push(`<rowBreaks count="${this.rowBreaks.length}" manualBreakCount="${this.rowBreaks.filter((b) => b.manual).length}">${brkParts.join("")}</rowBreaks>`);
1246
+ }
1247
+ if (this.colBreaks.length > 0) {
1248
+ const brkParts = this.colBreaks.map((b) => {
1249
+ const bAttrs = { id: b.id };
1250
+ if (b.min !== void 0) bAttrs.min = b.min;
1251
+ if (b.max !== void 0) bAttrs.max = b.max;
1252
+ if (b.manual) bAttrs.man = 1;
1253
+ if (b.pivot) bAttrs.pt = 1;
1254
+ return `<brk${attrs(bAttrs)}/>`;
1255
+ });
1256
+ p.push(`<colBreaks count="${this.colBreaks.length}" manualBreakCount="${this.colBreaks.filter((b) => b.manual).length}">${brkParts.join("")}</colBreaks>`);
1257
+ }
1258
+ if (this.customProperties.length > 0) {
1259
+ const cpParts = ["<customProperties>"];
1260
+ for (const cp of this.customProperties) cpParts.push(`<customPr name="${escapeXml(cp.name)}" r:id="${escapeXml(cp.rId)}"/>`);
1261
+ cpParts.push("</customProperties>");
1262
+ p.push(cpParts.join(""));
1263
+ }
1264
+ if (this.oleSize) p.push(`<oleSize ref="${escapeXml(this.oleSize)}"/>`);
1265
+ if (this.customSheetViews.length > 0) {
1266
+ p.push("<customSheetViews>");
1267
+ for (const csv of this.customSheetViews) {
1268
+ const csvAttrs = { guid: csv.guid };
1269
+ if (csv.scale !== void 0) csvAttrs.scale = csv.scale;
1270
+ if (csv.showPageBreaks) csvAttrs.showPageBreaks = 1;
1271
+ if (csv.showFormulas) csvAttrs.showFormulas = 1;
1272
+ if (csv.showGridLines === false) csvAttrs.showGridLines = 0;
1273
+ if (csv.showRowColHeaders === false) csvAttrs.showRowCol = 0;
1274
+ if (csv.outlineSymbols === false) csvAttrs.outlineSymbols = 0;
1275
+ if (csv.zeroValues === false) csvAttrs.zeroValues = 0;
1276
+ if (csv.fitToPage) csvAttrs.fitToPage = 1;
1277
+ if (csv.printArea) csvAttrs.printArea = 1;
1278
+ if (csv.filter) csvAttrs.filter = 1;
1279
+ if (csv.showAutoFilter) csvAttrs.showAutoFilter = 1;
1280
+ if (csv.hiddenRows) csvAttrs.hiddenRows = 1;
1281
+ if (csv.hiddenColumns) csvAttrs.hiddenColumns = 1;
1282
+ if (csv.state && csv.state !== "visible") csvAttrs.state = csv.state;
1283
+ if (csv.filterUnique) csvAttrs.filterUnique = 1;
1284
+ if (csv.view && csv.view !== "normal") csvAttrs.view = csv.view;
1285
+ p.push(`<customSheetView${attrs(csvAttrs)}/>`);
1286
+ }
1287
+ p.push("</customSheetViews>");
1288
+ }
1289
+ if (this.cellWatches.length > 0) {
1290
+ p.push("<cellWatches>");
1291
+ for (const cw of this.cellWatches) p.push(`<cellWatch r="${escapeXml(cw.r)}"/>`);
1292
+ p.push("</cellWatches>");
1293
+ }
1294
+ if (this.dataConsolidate) {
1295
+ const dc = this.dataConsolidate;
1296
+ const dcAttrs = {};
1297
+ if (dc.function && dc.function !== "sum") dcAttrs.function = dc.function;
1298
+ if (dc.topLabels) dcAttrs.topLabels = 1;
1299
+ if (dc.leftLabels) dcAttrs.leftLabels = 1;
1300
+ if (dc.startLabels) dcAttrs.startLabels = 1;
1301
+ if (dc.link) dcAttrs.link = 1;
1302
+ const refsInner = dc.refs?.map((r) => `<dataRef ref="${escapeXml(r)}"/>`).join("") ?? "";
1303
+ const refsXml = refsInner ? `<dataRefs>${refsInner}</dataRefs>` : "";
1304
+ if (refsXml || Object.keys(dcAttrs).length > 0) p.push(`<dataConsolidate${attrs(dcAttrs)}>${refsXml}</dataConsolidate>`);
1305
+ }
680
1306
  if (this.protection) {
681
1307
  const prot = this.protection;
682
1308
  const protAttrs = {};
683
1309
  if (prot.password) protAttrs.password = this.hashPassword(prot.password);
1310
+ let derived;
1311
+ if (prot.password !== void 0 && prot.hashValue === void 0) derived = derivePasswordHash(prot.password);
1312
+ protAttrs.algorithmName = prot.algorithmName ?? derived?.algorithmName;
1313
+ protAttrs.hashValue = prot.hashValue ?? derived?.hashValue;
1314
+ protAttrs.saltValue = prot.saltValue ?? derived?.saltValue;
1315
+ if (prot.spinCount !== void 0) protAttrs.spinCount = prot.spinCount;
1316
+ else if (derived) protAttrs.spinCount = derived.spinCount;
684
1317
  if (prot.sheet) protAttrs.sheet = 1;
685
1318
  if (prot.objects) protAttrs.objects = 1;
686
1319
  if (prot.scenarios) protAttrs.scenarios = 1;
@@ -699,6 +1332,55 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
699
1332
  if (prot.selectUnlockedCells) protAttrs.selectUnlockedCells = 1;
700
1333
  p.push(selfCloseElement("sheetProtection", attrs(protAttrs)));
701
1334
  }
1335
+ if (this.protectedRanges.length > 0) {
1336
+ const prParts = ["<protectedRanges>"];
1337
+ for (const pr of this.protectedRanges) {
1338
+ const prAttrs = {
1339
+ name: pr.name,
1340
+ sqref: pr.sqref
1341
+ };
1342
+ if (pr.password) prAttrs.password = this.hashPassword(pr.password);
1343
+ let prDerived;
1344
+ if (pr.password !== void 0 && pr.hashValue === void 0) prDerived = derivePasswordHash(pr.password);
1345
+ prAttrs.algorithmName = pr.algorithmName ?? prDerived?.algorithmName;
1346
+ prAttrs.hashValue = pr.hashValue ?? prDerived?.hashValue;
1347
+ prAttrs.saltValue = pr.saltValue ?? prDerived?.saltValue;
1348
+ if (pr.spinCount !== void 0) prAttrs.spinCount = pr.spinCount;
1349
+ else if (prDerived) prAttrs.spinCount = prDerived.spinCount;
1350
+ if (!!pr.securityDescriptor) prParts.push(`<protectedRange${attrs(prAttrs)}><securityDescriptor>${escapeXml(pr.securityDescriptor)}</securityDescriptor></protectedRange>`);
1351
+ else prParts.push(selfCloseElement("protectedRange", attrs(prAttrs)));
1352
+ }
1353
+ prParts.push("</protectedRanges>");
1354
+ p.push(prParts.join(""));
1355
+ }
1356
+ if (this.scenarioOpts) {
1357
+ const scParts = ["<scenarios"];
1358
+ const scAttrs = {};
1359
+ if (this.scenarioOpts.current !== void 0) scAttrs.current = this.scenarioOpts.current;
1360
+ if (this.scenarioOpts.show !== void 0) scAttrs.show = this.scenarioOpts.show;
1361
+ scParts[0] = `<scenarios${attrs(scAttrs)}>`;
1362
+ for (const scenario of this.scenarioOpts.scenarios) {
1363
+ const sAttrs = { name: scenario.name };
1364
+ if (scenario.count !== void 0) sAttrs.count = scenario.count;
1365
+ if (scenario.user) sAttrs.user = scenario.user;
1366
+ if (scenario.comment) sAttrs.comment = scenario.comment;
1367
+ if (scenario.hidden) sAttrs.hidden = true;
1368
+ if (scenario.locked) sAttrs.locked = true;
1369
+ const sParts = [`<scenario${attrs(sAttrs)}>`];
1370
+ for (const cell of scenario.inputCells) {
1371
+ const icAttrs = {
1372
+ r: cell.r,
1373
+ val: String(cell.val)
1374
+ };
1375
+ if (cell.deleted) icAttrs.deleted = true;
1376
+ sParts.push(`<inputCells${attrs(icAttrs)}/>`);
1377
+ }
1378
+ sParts.push("</scenario>");
1379
+ scParts.push(sParts.join(""));
1380
+ }
1381
+ scParts.push("</scenarios>");
1382
+ p.push(scParts.join(""));
1383
+ }
702
1384
  if (this.autoFilter) if (typeof this.autoFilter === "string") p.push(selfCloseElement("autoFilter", attrs({ ref: this.autoFilter })));
703
1385
  else {
704
1386
  const af = this.autoFilter;
@@ -726,9 +1408,43 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
726
1408
  for (const sc of af.sort) {
727
1409
  const scAttrs = { ref: sc.ref };
728
1410
  if (sc.descending) scAttrs.descending = 1;
1411
+ if (sc.sortBy) scAttrs.sortBy = sc.sortBy;
1412
+ if (sc.customList) scAttrs.customList = sc.customList;
1413
+ if (sc.iconId !== void 0) scAttrs.iconId = sc.iconId;
729
1414
  sortParts.push(selfCloseElement("sortCondition", attrs(scAttrs)));
730
1415
  }
731
- inner.push(`<sortState ref="${af.ref}">${sortParts.join("")}</sortState>`);
1416
+ const ssAttrs = { ref: af.ref };
1417
+ if (af.sortState?.columnSort) ssAttrs.columnSort = 1;
1418
+ if (af.sortState?.caseSensitive) ssAttrs.caseSensitive = 1;
1419
+ if (af.sortState?.sortMethod) ssAttrs.sortMethod = af.sortState.sortMethod;
1420
+ inner.push(`<sortState${attrs(ssAttrs)}>${sortParts.join("")}</sortState>`);
1421
+ }
1422
+ for (const cf of af.colorFilters ?? []) {
1423
+ const cfAttrs = {};
1424
+ if (cf.dxfId !== void 0) cfAttrs.dxfId = cf.dxfId;
1425
+ if (cf.cellColor === false) cfAttrs.cellColor = 0;
1426
+ inner.push(`<filterColumn colId="${cf.colId}"><colorFilter${attrs(cfAttrs)}/></filterColumn>`);
1427
+ }
1428
+ for (const if_ of af.iconFilters ?? []) {
1429
+ const ifAttrs = { iconSet: if_.iconSet };
1430
+ if (if_.iconId !== void 0) ifAttrs.iconId = if_.iconId;
1431
+ inner.push(`<filterColumn colId="${if_.colId}"><iconFilter${attrs(ifAttrs)}/></filterColumn>`);
1432
+ }
1433
+ for (const df of af.dynamicFilters ?? []) {
1434
+ const dfAttrs = { type: df.type };
1435
+ if (df.val !== void 0) dfAttrs.val = df.val;
1436
+ if (df.maxVal !== void 0) dfAttrs.maxVal = df.maxVal;
1437
+ inner.push(`<filterColumn colId="${df.colId}"><dynamicFilter${attrs(dfAttrs)}/></filterColumn>`);
1438
+ }
1439
+ for (const dg of af.dateGroupItems ?? []) {
1440
+ const dgAttrs = { dateTimeGrouping: dg.dateTimeGrouping };
1441
+ if (dg.year !== void 0) dgAttrs.year = dg.year;
1442
+ if (dg.month !== void 0) dgAttrs.month = dg.month;
1443
+ if (dg.day !== void 0) dgAttrs.day = dg.day;
1444
+ if (dg.hour !== void 0) dgAttrs.hour = dg.hour;
1445
+ if (dg.minute !== void 0) dgAttrs.minute = dg.minute;
1446
+ if (dg.second !== void 0) dgAttrs.second = dg.second;
1447
+ inner.push(`<filterColumn colId="${dg.colId}"><dateGroupItem${attrs(dgAttrs)}/></filterColumn>`);
732
1448
  }
733
1449
  if (inner.length > 0) p.push(`<autoFilter ref="${af.ref}">`, ...inner, "</autoFilter>");
734
1450
  else p.push(selfCloseElement("autoFilter", attrs({ ref: af.ref })));
@@ -742,6 +1458,13 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
742
1458
  }
743
1459
  p.push("</mergeCells>");
744
1460
  }
1461
+ if (this.phoneticPr) {
1462
+ const pp = this.phoneticPr;
1463
+ const ppAttrs = { fontId: pp.fontId };
1464
+ if (pp.type && pp.type !== "fullwidthKatakana") ppAttrs.type = pp.type;
1465
+ if (pp.alignment && pp.alignment !== "left") ppAttrs.alignment = pp.alignment;
1466
+ p.push(selfCloseElement("phoneticPr", attrs(ppAttrs)));
1467
+ }
745
1468
  if (this.conditionalFormats.length > 0) for (const cf of this.conditionalFormats) {
746
1469
  p.push(`<conditionalFormatting sqref="${cf.sqref}">`);
747
1470
  for (let ri = 0; ri < cf.rules.length; ri++) {
@@ -752,7 +1475,39 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
752
1475
  };
753
1476
  if (rule.operator) ruleAttrs.operator = rule.operator;
754
1477
  if (rule.dxfId !== void 0) ruleAttrs.dxfId = rule.dxfId;
755
- if (rule.formulas && rule.formulas.length > 0) {
1478
+ if (rule.stopIfTrue) ruleAttrs.stopIfTrue = 1;
1479
+ if (rule.timePeriod) ruleAttrs.timePeriod = rule.timePeriod;
1480
+ if (rule.rank !== void 0) ruleAttrs.rank = rule.rank;
1481
+ if (rule.equalAverage) ruleAttrs.equalAverage = 1;
1482
+ if (rule.type === "colorScale" && rule.colorScale) {
1483
+ const cs = rule.colorScale;
1484
+ const inner = [];
1485
+ for (const v of cs.cfvo) inner.push(this.buildCfvoXml(v));
1486
+ for (const c of cs.colors) inner.push(`<color rgb="FF${c}"/>`);
1487
+ p.push(`<cfRule${attrs(ruleAttrs)}><colorScale>${inner.join("")}</colorScale></cfRule>`);
1488
+ } else if (rule.type === "dataBar" && rule.dataBar) {
1489
+ const db = rule.dataBar;
1490
+ const inner = [];
1491
+ for (const v of db.cfvo) inner.push(this.buildCfvoXml(v));
1492
+ inner.push(`<color rgb="FF${db.color}"/>`);
1493
+ const dbAttrs = {};
1494
+ if (db.minLength !== void 0 && db.minLength !== 10) dbAttrs.minLength = db.minLength;
1495
+ if (db.maxLength !== void 0 && db.maxLength !== 90) dbAttrs.maxLength = db.maxLength;
1496
+ if (db.showValue === false) dbAttrs.showValue = 0;
1497
+ const attrStr = Object.keys(dbAttrs).length > 0 ? attrs(dbAttrs) : "";
1498
+ p.push(`<cfRule${attrs(ruleAttrs)}><dataBar${attrStr}>${inner.join("")}</dataBar></cfRule>`);
1499
+ } else if (rule.type === "iconSet" && rule.iconSet) {
1500
+ const is = rule.iconSet;
1501
+ const inner = [];
1502
+ for (const v of is.cfvo) inner.push(this.buildCfvoXml(v));
1503
+ const isAttrs = {};
1504
+ if (is.iconSet !== void 0 && is.iconSet !== "3TrafficLights1") isAttrs.iconSet = is.iconSet;
1505
+ if (is.showValue === false) isAttrs.showValue = 0;
1506
+ if (is.percent === false) isAttrs.percent = 0;
1507
+ if (is.reverse) isAttrs.reverse = 1;
1508
+ const attrStr = Object.keys(isAttrs).length > 0 ? attrs(isAttrs) : "";
1509
+ p.push(`<cfRule${attrs(ruleAttrs)}><iconSet${attrStr}>${inner.join("")}</iconSet></cfRule>`);
1510
+ } else if (rule.formulas && rule.formulas.length > 0) {
756
1511
  const formulaParts = rule.formulas.map((f) => `<formula>${escapeXml(f)}</formula>`);
757
1512
  p.push(`<cfRule${attrs(ruleAttrs)}>`, ...formulaParts, "</cfRule>");
758
1513
  } else p.push(selfCloseElement("cfRule", attrs(ruleAttrs)));
@@ -772,6 +1527,9 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
772
1527
  if (dv.error) dvAttrs.error = dv.error;
773
1528
  if (dv.promptTitle) dvAttrs.promptTitle = dv.promptTitle;
774
1529
  if (dv.prompt) dvAttrs.prompt = dv.prompt;
1530
+ if (dv.errorStyle) dvAttrs.errorStyle = dv.errorStyle;
1531
+ if (dv.imeMode) dvAttrs.imeMode = dv.imeMode;
1532
+ if (dv.showDropDown) dvAttrs.showDropDown = 1;
775
1533
  const inner = [];
776
1534
  if (dv.formula1 !== void 0) inner.push(`<formula1>${escapeXml(dv.formula1)}</formula1>`);
777
1535
  if (dv.formula2 !== void 0) inner.push(`<formula2>${escapeXml(dv.formula2)}</formula2>`);
@@ -795,6 +1553,16 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
795
1553
  }
796
1554
  p.push("</hyperlinks>");
797
1555
  }
1556
+ if (this.printOptions) {
1557
+ const po = this.printOptions;
1558
+ const poAttrs = {};
1559
+ if (po.horizontalCentered) poAttrs.horizontalCentered = 1;
1560
+ if (po.verticalCentered) poAttrs.verticalCentered = 1;
1561
+ if (po.headings) poAttrs.headings = 1;
1562
+ if (po.gridLines) poAttrs.gridLines = 1;
1563
+ if (po.gridLinesSet === false) poAttrs.gridLinesSet = 0;
1564
+ p.push(selfCloseElement("printOptions", attrs(poAttrs)));
1565
+ }
798
1566
  p.push("<pageMargins left=\"0.75\" right=\"0.75\" top=\"1\" bottom=\"1\" header=\"0.5\" footer=\"0.5\"/>");
799
1567
  if (this.pageSetup) {
800
1568
  const ps = this.pageSetup;
@@ -807,6 +1575,13 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
807
1575
  if (ps.pageOrder && ps.pageOrder !== "downThenOver") psAttrs.pageOrder = ps.pageOrder;
808
1576
  if (ps.useFirstPageNumber) psAttrs.useFirstPageNumber = 1;
809
1577
  if (ps.firstPageNumber !== void 0) psAttrs.firstPageNumber = ps.firstPageNumber;
1578
+ if (ps.paperHeight !== void 0) psAttrs.paperHeight = ps.paperHeight;
1579
+ if (ps.paperWidth !== void 0) psAttrs.paperWidth = ps.paperWidth;
1580
+ if (ps.usePrinterDefaults) psAttrs.usePrinterDefaults = 1;
1581
+ if (ps.blackAndWhite) psAttrs.blackAndWhite = 1;
1582
+ if (ps.draft) psAttrs.draft = 1;
1583
+ if (ps.cellComments && ps.cellComments !== "none") psAttrs.cellComments = ps.cellComments;
1584
+ if (ps.errors && ps.errors !== "displayed") psAttrs.errors = ps.errors;
810
1585
  p.push(selfCloseElement("pageSetup", attrs(psAttrs)));
811
1586
  }
812
1587
  if (this.headerFooter) {
@@ -814,6 +1589,8 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
814
1589
  const hfAttrs = {};
815
1590
  if (hf.differentOddEven) hfAttrs.differentOddEven = 1;
816
1591
  if (hf.differentFirst) hfAttrs.differentFirst = 1;
1592
+ if (hf.scaleWithDoc === false) hfAttrs.scaleWithDoc = 0;
1593
+ if (hf.alignWithMargins === false) hfAttrs.alignWithMargins = 0;
817
1594
  const inner = [];
818
1595
  if (hf.oddHeader) inner.push(`<oddHeader>${escapeXml(hf.oddHeader)}</oddHeader>`);
819
1596
  if (hf.oddFooter) inner.push(`<oddFooter>${escapeXml(hf.oddFooter)}</oddFooter>`);
@@ -824,9 +1601,125 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
824
1601
  if (inner.length > 0) p.push(`<headerFooter${attrs(hfAttrs)}>`, ...inner, "</headerFooter>");
825
1602
  else if (hfAttrs.differentOddEven || hfAttrs.differentFirst) p.push(selfCloseElement("headerFooter", attrs(hfAttrs)));
826
1603
  }
1604
+ if (this.drawingHF) {
1605
+ const dhf = this.drawingHF;
1606
+ const dhfAttrs = { "r:id": dhf.rId };
1607
+ if (dhf.lho !== void 0) dhfAttrs.lho = dhf.lho;
1608
+ if (dhf.lhe !== void 0) dhfAttrs.lhe = dhf.lhe;
1609
+ if (dhf.lhf !== void 0) dhfAttrs.lhf = dhf.lhf;
1610
+ if (dhf.cho !== void 0) dhfAttrs.cho = dhf.cho;
1611
+ if (dhf.che !== void 0) dhfAttrs.che = dhf.che;
1612
+ if (dhf.chf !== void 0) dhfAttrs.chf = dhf.chf;
1613
+ if (dhf.rho !== void 0) dhfAttrs.rho = dhf.rho;
1614
+ if (dhf.rhe !== void 0) dhfAttrs.rhe = dhf.rhe;
1615
+ if (dhf.rhf !== void 0) dhfAttrs.rhf = dhf.rhf;
1616
+ if (dhf.lfo !== void 0) dhfAttrs.lfo = dhf.lfo;
1617
+ if (dhf.lfe !== void 0) dhfAttrs.lfe = dhf.lfe;
1618
+ if (dhf.lff !== void 0) dhfAttrs.lff = dhf.lff;
1619
+ if (dhf.cfo !== void 0) dhfAttrs.cfo = dhf.cfo;
1620
+ if (dhf.cfe !== void 0) dhfAttrs.cfe = dhf.cfe;
1621
+ if (dhf.cff !== void 0) dhfAttrs.cff = dhf.cff;
1622
+ if (dhf.rfo !== void 0) dhfAttrs.rfo = dhf.rfo;
1623
+ if (dhf.rfe !== void 0) dhfAttrs.rfe = dhf.rfe;
1624
+ if (dhf.rff !== void 0) dhfAttrs.rff = dhf.rff;
1625
+ p.push(selfCloseElement("drawingHF", attrs(dhfAttrs)));
1626
+ }
1627
+ if (this.legacyDrawingHF) p.push(`<legacyDrawingHF r:id="${escapeXml(this.legacyDrawingHF)}"/>`);
1628
+ if (this.ignoredErrors.length > 0) {
1629
+ const ieParts = ["<ignoredErrors>"];
1630
+ for (const ie of this.ignoredErrors) {
1631
+ const ieAttrs = { sqref: ie.sqref };
1632
+ if (ie.evalError) ieAttrs.evalError = 1;
1633
+ if (ie.twoDigitTextYear) ieAttrs.twoDigitTextYear = 1;
1634
+ if (ie.numberStoredAsText) ieAttrs.numberStoredAsText = 1;
1635
+ if (ie.formula) ieAttrs.formula = 1;
1636
+ if (ie.formulaRange) ieAttrs.formulaRange = 1;
1637
+ if (ie.unlockedFormula) ieAttrs.unlockedFormula = 1;
1638
+ if (ie.emptyCellReference) ieAttrs.emptyCellReference = 1;
1639
+ if (ie.listDataValidation) ieAttrs.listDataValidation = 1;
1640
+ if (ie.calculatedColumn) ieAttrs.calculatedColumn = 1;
1641
+ ieParts.push(selfCloseElement("ignoredError", attrs(ieAttrs)));
1642
+ }
1643
+ ieParts.push("</ignoredErrors>");
1644
+ p.push(ieParts.join(""));
1645
+ }
1646
+ if (this.backgroundImage) p.push("<!--BACKGROUND_PICTURE-->");
1647
+ if (this.oleObjects.length > 0) {
1648
+ const oleParts = ["<oleObjects>"];
1649
+ for (const ole of this.oleObjects) {
1650
+ const oleAttrs = [`shapeId="${ole.shapeId}"`];
1651
+ if (ole.progId) oleAttrs.push(`progId="${escapeXml(ole.progId)}"`);
1652
+ if (ole.dvAspect && ole.dvAspect !== "DVASPECT_CONTENT") oleAttrs.push(`dvAspect="${ole.dvAspect}"`);
1653
+ if (ole.link) oleAttrs.push(`link="${escapeXml(ole.link)}"`);
1654
+ if (ole.oleUpdate) oleAttrs.push(`oleUpdate="${ole.oleUpdate}"`);
1655
+ if (ole.autoLoad) oleAttrs.push("autoLoad=\"1\"");
1656
+ if (ole.rId) oleAttrs.push(`r:id="${escapeXml(ole.rId)}"`);
1657
+ if (ole.objectPr) {
1658
+ const opr = ole.objectPr;
1659
+ const oprAttrs = [];
1660
+ if (opr.locked === false) oprAttrs.push("locked=\"0\"");
1661
+ if (opr.defaultSize === false) oprAttrs.push("defaultSize=\"0\"");
1662
+ if (opr.print === false) oprAttrs.push("print=\"0\"");
1663
+ if (opr.disabled) oprAttrs.push("disabled=\"1\"");
1664
+ if (opr.uiObject) oprAttrs.push("uiObject=\"1\"");
1665
+ if (opr.autoFill === false) oprAttrs.push("autoFill=\"0\"");
1666
+ if (opr.autoLine === false) oprAttrs.push("autoLine=\"0\"");
1667
+ if (opr.autoPict === false) oprAttrs.push("autoPict=\"0\"");
1668
+ if (opr.macro) oprAttrs.push(`macro="${escapeXml(opr.macro)}"`);
1669
+ if (opr.altText) oprAttrs.push(`altText="${escapeXml(opr.altText)}"`);
1670
+ if (opr.dde) oprAttrs.push("dde=\"1\"");
1671
+ if (opr.rId) oprAttrs.push(`r:id="${escapeXml(opr.rId)}"`);
1672
+ oleParts.push(`<oleObject ${oleAttrs.join(" ")}><objectPr${oprAttrs.length ? " " + oprAttrs.join(" ") : ""}/></oleObject>`);
1673
+ } else oleParts.push(`<oleObject ${oleAttrs.join(" ")}/>`);
1674
+ }
1675
+ oleParts.push("</oleObjects>");
1676
+ p.push(oleParts.join(""));
1677
+ }
1678
+ if (this.controls.length > 0) {
1679
+ const ctrlParts = ["<controls>"];
1680
+ for (const c of this.controls) {
1681
+ const cAttrs = [`shapeId="${c.shapeId}"`, `r:id="${escapeXml(c.rId)}"`];
1682
+ if (c.name) cAttrs.push(`name="${escapeXml(c.name)}"`);
1683
+ const prAttrs = [];
1684
+ if (c.locked === false) prAttrs.push("locked=\"0\"");
1685
+ if (c.uiObject) prAttrs.push("uiObject=\"1\"");
1686
+ if (prAttrs.length > 0) ctrlParts.push(`<control ${cAttrs.join(" ")}><controlPr${prAttrs.length ? " " + prAttrs.join(" ") : ""}/></control>`);
1687
+ else ctrlParts.push(`<control ${cAttrs.join(" ")}/>`);
1688
+ }
1689
+ ctrlParts.push("</controls>");
1690
+ p.push(ctrlParts.join(""));
1691
+ }
1692
+ if (this.webPublishItems.length > 0) {
1693
+ const wpParts = [`<webPublishItems count="${this.webPublishItems.length}">`];
1694
+ for (const wpi of this.webPublishItems) {
1695
+ const wpiAttrs = [
1696
+ `id="${wpi.id}"`,
1697
+ `divId="${escapeXml(wpi.divId)}"`,
1698
+ `sourceType="${wpi.sourceType}"`,
1699
+ `destinationFile="${escapeXml(wpi.destinationFile)}"`
1700
+ ];
1701
+ if (wpi.sourceRef) wpiAttrs.push(`sourceRef="${escapeXml(wpi.sourceRef)}"`);
1702
+ if (wpi.sourceObject) wpiAttrs.push(`sourceObject="${escapeXml(wpi.sourceObject)}"`);
1703
+ if (wpi.title) wpiAttrs.push(`title="${escapeXml(wpi.title)}"`);
1704
+ if (wpi.autoRepublish) wpiAttrs.push("autoRepublish=\"1\"");
1705
+ wpParts.push(`<webPublishItem ${wpiAttrs.join(" ")}/>`);
1706
+ }
1707
+ wpParts.push("</webPublishItems>");
1708
+ p.push(wpParts.join(""));
1709
+ }
1710
+ if (this.ext) p.push(`<extLst>${this.ext}</extLst>`);
827
1711
  p.push("</worksheet>");
828
1712
  return p.join("");
829
1713
  }
1714
+ /**
1715
+ * Build a <cfvo> element string for conditional formatting.
1716
+ */
1717
+ buildCfvoXml(cfvo) {
1718
+ const a = { type: cfvo.type };
1719
+ if (cfvo.val !== void 0) a.val = cfvo.val;
1720
+ if (cfvo.gte === false) a.gte = 0;
1721
+ return `<cfvo${attrs(a)}/>`;
1722
+ }
830
1723
  buildSheetViewAttrs() {
831
1724
  const sv = this.sheetView;
832
1725
  const svMap = { workbookViewId: 0 };
@@ -837,8 +1730,48 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
837
1730
  if (sv?.showZeros === false) svMap.showZeros = 0;
838
1731
  if (sv?.zoomScale !== void 0) svMap.zoomScale = sv.zoomScale;
839
1732
  if (sv?.rightToLeft) svMap.rightToLeft = 1;
1733
+ if (sv?.windowProtection) svMap.windowProtection = 1;
1734
+ if (sv?.showFormulas) svMap.showFormulas = 1;
1735
+ if (sv?.showRuler === false) svMap.showRuler = 0;
1736
+ if (sv?.showOutlineSymbols === false) svMap.showOutlineSymbols = 0;
1737
+ if (sv?.defaultGridColor === false) svMap.defaultGridColor = 0;
1738
+ if (sv?.showWhiteSpace === false) svMap.showWhiteSpace = 0;
1739
+ if (sv?.view) svMap.view = sv.view;
1740
+ if (sv?.colorId !== void 0) svMap.colorId = sv.colorId;
1741
+ if (sv?.zoomScaleNormal !== void 0) svMap.zoomScaleNormal = sv.zoomScaleNormal;
1742
+ if (sv?.zoomScaleSheetLayoutView !== void 0) svMap.zoomScaleSheetLayoutView = sv.zoomScaleSheetLayoutView;
1743
+ if (sv?.zoomScalePageLayoutView !== void 0) svMap.zoomScalePageLayoutView = sv.zoomScalePageLayoutView;
840
1744
  return attrs(svMap);
841
1745
  }
1746
+ buildSelectionXml(sel) {
1747
+ const selAttrs = {};
1748
+ if (sel.pane) selAttrs.pane = sel.pane;
1749
+ if (sel.activeCell) selAttrs.activeCell = sel.activeCell;
1750
+ if (sel.activeCellId !== void 0) selAttrs.activeCellId = sel.activeCellId;
1751
+ if (sel.sqref) selAttrs.sqref = sel.sqref;
1752
+ return `<selection${attrs(selAttrs)}/>`;
1753
+ }
1754
+ buildPivotSelectionXml(ps) {
1755
+ const psAttrs = {};
1756
+ if (ps.pane) psAttrs.pane = ps.pane;
1757
+ if (ps.showHeader) psAttrs.showHeader = 1;
1758
+ if (ps.label) psAttrs.label = 1;
1759
+ if (ps.data) psAttrs.data = 1;
1760
+ if (ps.extendable) psAttrs.extendable = 1;
1761
+ if (ps.count !== void 0) psAttrs.count = ps.count;
1762
+ if (ps.axis) psAttrs.axis = ps.axis;
1763
+ if (ps.dimension !== void 0) psAttrs.dimension = ps.dimension;
1764
+ if (ps.start !== void 0) psAttrs.start = ps.start;
1765
+ if (ps.min !== void 0) psAttrs.min = ps.min;
1766
+ if (ps.max !== void 0) psAttrs.max = ps.max;
1767
+ if (ps.activeRow !== void 0) psAttrs.activeRow = ps.activeRow;
1768
+ if (ps.activeCol !== void 0) psAttrs.activeCol = ps.activeCol;
1769
+ if (ps.previousRow !== void 0) psAttrs.previousRow = ps.previousRow;
1770
+ if (ps.previousCol !== void 0) psAttrs.previousCol = ps.previousCol;
1771
+ if (ps.click !== void 0) psAttrs.click = ps.click;
1772
+ if (ps.rId) psAttrs["r:id"] = ps.rId;
1773
+ return `<pivotSelection${attrs(psAttrs)}><pivotArea/></pivotSelection>`;
1774
+ }
842
1775
  /**
843
1776
  * Excel legacy password hash (16-bit, little-endian hex).
844
1777
  * Matches the algorithm used by ECMA-376 Part 1, §18.2.27.
@@ -864,6 +1797,15 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
864
1797
  if (fOpts.type && fOpts.type !== FormulaType.NORMAL) fAttrs.t = fOpts.type;
865
1798
  if (fOpts.reference) fAttrs.ref = fOpts.reference;
866
1799
  if (fOpts.sharedIndex !== void 0) fAttrs.si = fOpts.sharedIndex;
1800
+ if (fOpts.aca) fAttrs.aca = 1;
1801
+ if (fOpts.dt2D) fAttrs.dt2D = 1;
1802
+ if (fOpts.dtr) fAttrs.dtr = 1;
1803
+ if (fOpts.del1) fAttrs.del1 = 1;
1804
+ if (fOpts.del2) fAttrs.del2 = 1;
1805
+ if (fOpts.r1) fAttrs.r1 = fOpts.r1;
1806
+ if (fOpts.r2) fAttrs.r2 = fOpts.r2;
1807
+ if (fOpts.ca) fAttrs.ca = 1;
1808
+ if (fOpts.bx) fAttrs.bx = 1;
867
1809
  if (fOpts.formula !== void 0 && fOpts.formula !== "") return `<f${attrs(fAttrs)}>${escapeXml(fOpts.formula)}</f>`;
868
1810
  if (Object.keys(fAttrs).length > 0) return selfCloseElement("f", attrs(fAttrs));
869
1811
  return "";
@@ -895,6 +1837,15 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
895
1837
  if (cell.styleIndex !== void 0) return selfCloseElement("c", attrs(cellAttrs));
896
1838
  return "";
897
1839
  }
1840
+ if (typeof value === "object" && !(value instanceof Date)) {
1841
+ if (sharedStrings) {
1842
+ cellAttrs.t = "s";
1843
+ const idx = sharedStrings.registerRich(value);
1844
+ return `<c${attrs(cellAttrs)}><v>${idx}</v></c>`;
1845
+ }
1846
+ cellAttrs.t = "inlineStr";
1847
+ return `<c${attrs(cellAttrs)}><is>${buildRstXml(value)}</is></c>`;
1848
+ }
898
1849
  if (typeof value === "string") {
899
1850
  if (sharedStrings) {
900
1851
  cellAttrs.t = "s";
@@ -942,8 +1893,18 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
942
1893
  */
943
1894
  var File = class {
944
1895
  worksheetOptions;
1896
+ chartsheetOptions;
945
1897
  corePropsOptions;
946
1898
  dxfOptions;
1899
+ protectionOptions;
1900
+ externalLinkOptions;
1901
+ customViewOptions;
1902
+ fileRecoveryPrOpts;
1903
+ functionGroupOpts;
1904
+ webPublishingOpts;
1905
+ fileSharingOpts;
1906
+ volTypeOpts;
1907
+ webPublishObjectOpts;
947
1908
  _coreProperties;
948
1909
  _appProperties;
949
1910
  _contentTypes;
@@ -959,8 +1920,18 @@ var File = class {
959
1920
  _pivotCacheRefs = [];
960
1921
  constructor(options) {
961
1922
  this.worksheetOptions = options.worksheets ?? [];
1923
+ this.chartsheetOptions = options.chartsheets ?? [];
962
1924
  this.corePropsOptions = options;
963
1925
  this.dxfOptions = options.dxfs ?? [];
1926
+ this.protectionOptions = options.workbookProtection;
1927
+ this.externalLinkOptions = options.externalLinks ?? [];
1928
+ this.customViewOptions = options.customWorkbookViews;
1929
+ this.fileRecoveryPrOpts = options.fileRecoveryPr;
1930
+ this.functionGroupOpts = options.functionGroups;
1931
+ this.webPublishingOpts = options.webPublishing;
1932
+ this.fileSharingOpts = options.fileSharing;
1933
+ this.volTypeOpts = options.volTypes;
1934
+ this.webPublishObjectOpts = options.webPublishObjects;
964
1935
  }
965
1936
  get coreProperties() {
966
1937
  return this._coreProperties ??= new CoreProperties(this.corePropsOptions);
@@ -993,12 +1964,20 @@ var File = class {
993
1964
  }
994
1965
  get workbookXml() {
995
1966
  if (!this._workbookXml) {
996
- const sheets = this.worksheetOptions.map((ws, i) => ({
997
- name: ws.name ?? `Sheet${i + 1}`,
998
- sheetId: i + 1,
999
- rId: `rId${i + 1}`
1000
- }));
1001
- this._workbookXml = new WorkbookXml(sheets, this._pivotCacheRefs);
1967
+ const sheets = [];
1968
+ let sheetId = 1;
1969
+ let rId = 1;
1970
+ for (const ws of this.worksheetOptions) sheets.push({
1971
+ name: ws.name ?? `Sheet${sheetId}`,
1972
+ sheetId: sheetId++,
1973
+ rId: `rId${rId++}`
1974
+ });
1975
+ for (const cs of this.chartsheetOptions) sheets.push({
1976
+ name: cs.name ?? `Chart${sheetId}`,
1977
+ sheetId: sheetId++,
1978
+ rId: `rId${rId++}`
1979
+ });
1980
+ this._workbookXml = new WorkbookXml(sheets, this._pivotCacheRefs, this.protectionOptions, this.customViewOptions, this.fileRecoveryPrOpts, this.functionGroupOpts, this.webPublishingOpts, this.fileSharingOpts, void 0, void 0, void 0, this.volTypeOpts, this.webPublishObjectOpts);
1002
1981
  }
1003
1982
  return this._workbookXml;
1004
1983
  }
@@ -1023,9 +2002,15 @@ var File = class {
1023
2002
  rId
1024
2003
  });
1025
2004
  }
2005
+ get externalLinks() {
2006
+ return this.externalLinkOptions;
2007
+ }
1026
2008
  get worksheetConfigs() {
1027
2009
  return this.worksheetOptions;
1028
2010
  }
2011
+ get chartsheetConfigs() {
2012
+ return this.chartsheetOptions;
2013
+ }
1029
2014
  get worksheets() {
1030
2015
  if (!this._worksheets) this._worksheets = this.worksheetOptions.map((ws) => new Worksheet(ws));
1031
2016
  return this._worksheets;
@@ -1044,6 +2029,7 @@ var File = class {
1044
2029
  this._workbookRels = new Relationships();
1045
2030
  let rid = 1;
1046
2031
  for (let i = 0; i < this.worksheetOptions.length; i++) this._workbookRels.addRelationship(rid++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", `worksheets/sheet${i + 1}.xml`);
2032
+ for (let i = 0; i < this.chartsheetOptions.length; i++) this._workbookRels.addRelationship(rid++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet", `chartsheets/sheet${i + 1}.xml`);
1047
2033
  this._workbookRels.addRelationship(rid++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", "styles.xml");
1048
2034
  this._workbookRels.addRelationship(rid++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", "theme/theme1.xml");
1049
2035
  this._workbookRels.addRelationship(rid++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", "sharedStrings.xml");
@@ -1052,79 +2038,76 @@ var File = class {
1052
2038
  }
1053
2039
  };
1054
2040
  //#endregion
1055
- //#region src/file/comments.ts
1056
- /**
1057
- * Generates xl/comments{n}.xml — cell comment data.
1058
- *
1059
- * @module
1060
- */
1061
- var Comments = class extends BaseXmlComponent {
1062
- entries;
1063
- constructor(entries) {
1064
- super("comments");
1065
- this.entries = entries;
1066
- }
1067
- toXml(_context) {
1068
- const authors = this.collectAuthors();
1069
- const p = ["<comments xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">", `<authors>`];
1070
- for (const author of authors) p.push(`<author>${escapeXml(author)}</author>`);
1071
- p.push("</authors><commentList>");
1072
- for (const entry of this.entries) {
1073
- const authorId = authors.indexOf(entry.author);
1074
- p.push(`<comment ref="${entry.cell}" authorId="${authorId}"><text><t>${escapeXml(entry.text)}</t></text></comment>`);
1075
- }
1076
- p.push("</commentList></comments>");
1077
- return p.join("");
1078
- }
1079
- collectAuthors() {
1080
- const seen = /* @__PURE__ */ new Set();
1081
- const result = [];
1082
- for (const entry of this.entries) if (!seen.has(entry.author)) {
1083
- seen.add(entry.author);
1084
- result.push(entry.author);
1085
- }
1086
- return result.length > 0 ? result : [""];
1087
- }
1088
- };
1089
- //#endregion
1090
- //#region src/file/drawing/drawing.ts
1091
- /**
1092
- * XLSX Drawing component — generates xl/drawings/drawing{n}.xml.
1093
- *
1094
- * Uses the spreadsheetDrawing namespace (default, no prefix) for anchoring
1095
- * images and charts to worksheet cells.
1096
- *
1097
- * @module
1098
- */
1099
- const XDR_NS = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing";
1100
- const A_NS = "http://schemas.openxmlformats.org/drawingml/2006/main";
1101
- const R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
1102
- const C_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
1103
- var Drawing = class extends BaseXmlComponent {
1104
- images;
1105
- charts;
1106
- constructor(images, charts = []) {
1107
- super("wsDr");
1108
- this.images = images;
1109
- this.charts = charts;
1110
- }
1111
- toXml(_context) {
1112
- const p = [`<wsDr xmlns="${XDR_NS}" xmlns:a="${A_NS}" xmlns:r="${R_NS}">`];
1113
- let id = 1;
1114
- for (const img of this.images) {
1115
- p.push(`<twoCellAnchor editAs="oneCell"><from><col>${img.col - 1}</col><colOff>${img.colOffset ?? 0}</colOff><row>${img.row - 1}</row><rowOff>${img.rowOffset ?? 0}</rowOff></from>`, `<to><col>${img.col}</col><colOff>0</colOff><row>${img.row}</row><rowOff>0</rowOff></to>`, `<pic><nvPicPr><cNvPr id="${id}" name="Picture ${id}"/><cNvPicPr preferRelativeResize="1"/></nvPicPr>`, `<blipFill><a:blip r:embed="${img.rId}"/><a:stretch><a:fillRect/></a:stretch></blipFill>`, `<spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="400000" cy="300000"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></spPr></pic>`, `<clientData/></twoCellAnchor>`);
1116
- id++;
1117
- }
1118
- for (const chart of this.charts) {
1119
- p.push(`<twoCellAnchor editAs="oneCell"><from><col>${chart.col - 1}</col><colOff>${chart.colOffset ?? 0}</colOff><row>${chart.row - 1}</row><rowOff>${chart.rowOffset ?? 0}</rowOff></from>`, `<to><col>${chart.col + 8}</col><colOff>0</colOff><row>${chart.row + 15}</row><rowOff>0</rowOff></to>`, `<graphicFrame><nvGraphicFramePr><cNvPr id="${id}" name="Chart ${id}"/><cNvGraphicFramePr><a:graphicFrameLocks noGrp="1"/></cNvGraphicFramePr></nvGraphicFramePr>`, `<xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/></xfrm>`, `<a:graphic><a:graphicData uri="${C_URI}"><c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:r="${R_NS}" r:id="${chart.rId}"/></a:graphicData></a:graphic></graphicFrame>`, `<clientData/></twoCellAnchor>`);
1120
- id++;
1121
- }
1122
- p.push("</wsDr>");
1123
- return p.join("");
1124
- }
1125
- };
1126
- //#endregion
1127
2041
  //#region src/file/pivot/pivot-utils.ts
2042
+ /** Pivot filter type (ST_PivotFilterType) */
2043
+ const PivotFilterType = {
2044
+ UNKNOWN: "unknown",
2045
+ COUNT: "count",
2046
+ PERCENT: "percent",
2047
+ SUM: "sum",
2048
+ CAPTION_EQUAL: "captionEqual",
2049
+ CAPTION_NOT_EQUAL: "captionNotEqual",
2050
+ CAPTION_BEGINS_WITH: "captionBeginsWith",
2051
+ CAPTION_NOT_BEGINS_WITH: "captionNotBeginsWith",
2052
+ CAPTION_ENDS_WITH: "captionEndsWith",
2053
+ CAPTION_NOT_ENDS_WITH: "captionNotEndsWith",
2054
+ CAPTION_CONTAINS: "captionContains",
2055
+ CAPTION_NOT_CONTAINS: "captionNotContains",
2056
+ CAPTION_GREATER_THAN: "captionGreaterThan",
2057
+ CAPTION_GREATER_THAN_OR_EQUAL: "captionGreaterThanOrEqual",
2058
+ CAPTION_LESS_THAN: "captionLessThan",
2059
+ CAPTION_LESS_THAN_OR_EQUAL: "captionLessThanOrEqual",
2060
+ CAPTION_BETWEEN: "captionBetween",
2061
+ CAPTION_NOT_BETWEEN: "captionNotBetween",
2062
+ VALUE_EQUAL: "valueEqual",
2063
+ VALUE_NOT_EQUAL: "valueNotEqual",
2064
+ VALUE_GREATER_THAN: "valueGreaterThan",
2065
+ VALUE_GREATER_THAN_OR_EQUAL: "valueGreaterThanOrEqual",
2066
+ VALUE_LESS_THAN: "valueLessThan",
2067
+ VALUE_LESS_THAN_OR_EQUAL: "valueLessThanOrEqual",
2068
+ VALUE_BETWEEN: "valueBetween",
2069
+ VALUE_NOT_BETWEEN: "valueNotBetween",
2070
+ DATE_EQUAL: "dateEqual",
2071
+ DATE_NOT_EQUAL: "dateNotEqual",
2072
+ DATE_OLDER_THAN: "dateOlderThan",
2073
+ DATE_OLDER_THAN_OR_EQUAL: "dateOlderThanOrEqual",
2074
+ DATE_NEWER_THAN: "dateNewerThan",
2075
+ DATE_NEWER_THAN_OR_EQUAL: "dateNewerThanOrEqual",
2076
+ DATE_BETWEEN: "dateBetween",
2077
+ DATE_NOT_BETWEEN: "dateNotBetween",
2078
+ TOMORROW: "tomorrow",
2079
+ TODAY: "today",
2080
+ YESTERDAY: "yesterday",
2081
+ NEXT_WEEK: "nextWeek",
2082
+ THIS_WEEK: "thisWeek",
2083
+ LAST_WEEK: "lastWeek",
2084
+ NEXT_MONTH: "nextMonth",
2085
+ THIS_MONTH: "thisMonth",
2086
+ LAST_MONTH: "lastMonth",
2087
+ NEXT_QUARTER: "nextQuarter",
2088
+ THIS_QUARTER: "thisQuarter",
2089
+ LAST_QUARTER: "lastQuarter",
2090
+ NEXT_YEAR: "nextYear",
2091
+ THIS_YEAR: "thisYear",
2092
+ LAST_YEAR: "lastYear",
2093
+ YEAR_TO_DATE: "yearToDate",
2094
+ Q1: "Q1",
2095
+ Q2: "Q2",
2096
+ Q3: "Q3",
2097
+ Q4: "Q4",
2098
+ M1: "M1",
2099
+ M2: "M2",
2100
+ M3: "M3",
2101
+ M4: "M4",
2102
+ M5: "M5",
2103
+ M6: "M6",
2104
+ M7: "M7",
2105
+ M8: "M8",
2106
+ M9: "M9",
2107
+ M10: "M10",
2108
+ M11: "M11",
2109
+ M12: "M12"
2110
+ };
1128
2111
  /**
1129
2112
  * Extract unique values from source data for a given field index.
1130
2113
  */
@@ -1133,7 +2116,7 @@ function collectUniqueValues(records, fieldIdx) {
1133
2116
  const result = [];
1134
2117
  for (const row of records) {
1135
2118
  const val = row[fieldIdx];
1136
- const key = String(val);
2119
+ const key = val instanceof Date ? val.toISOString() : String(val);
1137
2120
  if (!seen.has(key)) {
1138
2121
  seen.add(key);
1139
2122
  result.push(val);
@@ -1195,17 +2178,75 @@ var PivotCacheDefinitionXml = class extends BaseXmlComponent {
1195
2178
  sourceSheet;
1196
2179
  sourceData;
1197
2180
  recordsRid;
1198
- constructor(_cacheIdx, sourceRef, sourceSheet, sourceData, recordsRid) {
2181
+ olapPr;
2182
+ cacheDefOpts;
2183
+ constructor(_cacheIdx, sourceRef, sourceSheet, sourceData, recordsRid, olapPr, cacheDefOpts) {
1199
2184
  super("pivotCacheDefinition");
1200
2185
  this.sourceRef = sourceRef;
1201
2186
  this.sourceSheet = sourceSheet;
1202
2187
  this.sourceData = sourceData;
1203
2188
  this.recordsRid = recordsRid;
2189
+ this.olapPr = olapPr;
2190
+ this.cacheDefOpts = cacheDefOpts;
1204
2191
  }
1205
2192
  toXml(_context) {
1206
2193
  const p = [];
1207
- p.push(`<pivotCacheDefinition xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="${escapeXml(this.recordsRid)}" recordCount="${this.sourceData.records.length}" createdVersion="6" refreshedVersion="6" minRefreshableVersion="3">`);
1208
- p.push(`<cacheSource type="worksheet"><worksheetSource ref="${escapeXml(this.sourceRef)}" sheet="${escapeXml(this.sourceSheet)}"/></cacheSource>`);
2194
+ const rootAttrs = [
2195
+ "xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"",
2196
+ "xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"",
2197
+ `r:id="${escapeXml(this.recordsRid)}"`,
2198
+ `recordCount="${this.sourceData.records.length}"`,
2199
+ "createdVersion=\"6\"",
2200
+ "refreshedVersion=\"6\"",
2201
+ "minRefreshableVersion=\"3\""
2202
+ ];
2203
+ if (this.cacheDefOpts) {
2204
+ const cd = this.cacheDefOpts;
2205
+ if (cd.invalid) rootAttrs.push("invalid=\"1\"");
2206
+ if (cd.saveData === false) rootAttrs.push("saveData=\"0\"");
2207
+ if (cd.optimizeMemory) rootAttrs.push("optimizeMemory=\"1\"");
2208
+ if (cd.enableRefresh === false) rootAttrs.push("enableRefresh=\"0\"");
2209
+ if (cd.refreshedBy) rootAttrs.push(`refreshedBy="${escapeXml(cd.refreshedBy)}"`);
2210
+ if (cd.refreshedDate !== void 0) rootAttrs.push(`refreshedDate="${cd.refreshedDate}"`);
2211
+ if (cd.refreshedDateIso) rootAttrs.push(`refreshedDateIso="${escapeXml(cd.refreshedDateIso)}"`);
2212
+ if (cd.backgroundQuery) rootAttrs.push("backgroundQuery=\"1\"");
2213
+ if (cd.missingItemsLimit !== void 0) rootAttrs.push(`missingItemsLimit="${cd.missingItemsLimit}"`);
2214
+ if (cd.upgradeOnRefresh) rootAttrs.push("upgradeOnRefresh=\"1\"");
2215
+ if (cd.supportSubquery) rootAttrs.push("supportSubquery=\"1\"");
2216
+ if (cd.supportAdvancedDrill) rootAttrs.push("supportAdvancedDrill=\"1\"");
2217
+ }
2218
+ p.push(`<pivotCacheDefinition ${rootAttrs.join(" ")}>`);
2219
+ if (this.cacheDefOpts?.consolidation) {
2220
+ const con = this.cacheDefOpts.consolidation;
2221
+ const conParts = ["<cacheSource type=\"consolidation\"><consolidation"];
2222
+ if (con.autoPage === false) conParts.push(" autoPage=\"0\"");
2223
+ conParts.push(">");
2224
+ if (con.pages && con.pages.length > 0) {
2225
+ conParts.push(`<pages count="${con.pages.length}">`);
2226
+ for (const pg of con.pages) {
2227
+ const pgItems = pg.items ?? [];
2228
+ conParts.push(`<page${pgItems.length ? ` count="${pgItems.length}"` : ""}>`);
2229
+ for (const pi of pgItems) conParts.push(`<pageItem name="${escapeXml(pi.name)}"/>`);
2230
+ conParts.push("</page>");
2231
+ }
2232
+ conParts.push("</pages>");
2233
+ }
2234
+ conParts.push(`<rangeSets count="${con.rangeSets.length}">`);
2235
+ for (const rs of con.rangeSets) {
2236
+ const rsAttrs = [];
2237
+ if (rs.i1 !== void 0) rsAttrs.push(`i1="${rs.i1}"`);
2238
+ if (rs.i2 !== void 0) rsAttrs.push(`i2="${rs.i2}"`);
2239
+ if (rs.i3 !== void 0) rsAttrs.push(`i3="${rs.i3}"`);
2240
+ if (rs.i4 !== void 0) rsAttrs.push(`i4="${rs.i4}"`);
2241
+ if (rs.ref) rsAttrs.push(`ref="${escapeXml(rs.ref)}"`);
2242
+ if (rs.name) rsAttrs.push(`name="${escapeXml(rs.name)}"`);
2243
+ if (rs.sheet) rsAttrs.push(`sheet="${escapeXml(rs.sheet)}"`);
2244
+ if (rs.rId) rsAttrs.push(`r:id="${escapeXml(rs.rId)}"`);
2245
+ conParts.push(`<rangeSet ${rsAttrs.join(" ")}/>`);
2246
+ }
2247
+ conParts.push("</rangeSets></consolidation></cacheSource>");
2248
+ p.push(conParts.join(""));
2249
+ } else p.push(`<cacheSource type="worksheet"><worksheetSource ref="${escapeXml(this.sourceRef)}" sheet="${escapeXml(this.sourceSheet)}"/></cacheSource>`);
1209
2250
  const fields = this.sourceData.fieldNames;
1210
2251
  p.push(`<cacheFields count="${fields.length}">`);
1211
2252
  for (let i = 0; i < fields.length; i++) {
@@ -1229,18 +2270,247 @@ var PivotCacheDefinitionXml = class extends BaseXmlComponent {
1229
2270
  const allInteger = this.sourceData.records.every((row) => typeof row[i] === "number" && Number.isInteger(row[i]));
1230
2271
  p.push(`<cacheField name="${escapeXml(fieldName)}" numFmtId="0"><sharedItems containsSemiMixedTypes="0" containsString="0" containsNumber="1" containsInteger="${allInteger ? "1" : "0"}" minValue="${min}" maxValue="${max}" count="${uniqueVals.length}"/></cacheField>`);
1231
2272
  } else {
1232
- p.push(`<cacheField name="${escapeXml(fieldName)}" numFmtId="0"><sharedItems count="${uniqueVals.length}">`);
1233
- for (const v of uniqueVals) p.push(`<s v="${escapeXml(String(v))}"/>`);
1234
- p.push("</sharedItems></cacheField>");
2273
+ let hasDate = false;
2274
+ let hasMissing = false;
2275
+ for (const v of uniqueVals) {
2276
+ if (v instanceof Date) hasDate = true;
2277
+ if (v === null) hasMissing = true;
2278
+ }
2279
+ const siAttrs = [`count="${uniqueVals.length}"`];
2280
+ if (hasDate) siAttrs.push("containsDate=\"1\"");
2281
+ if (hasMissing) siAttrs.push("containsBlank=\"1\"");
2282
+ p.push(`<cacheField name="${escapeXml(fieldName)}" numFmtId="0"><sharedItems ${siAttrs.join(" ")}>`);
2283
+ for (const v of uniqueVals) if (v === null) p.push("<m/>");
2284
+ else if (v instanceof Date) p.push(`<d v="${v.toISOString().replace(/\.\d{3}Z$/, "Z")}"/>`);
2285
+ else p.push(`<s v="${escapeXml(String(v))}"/>`);
2286
+ p.push("</sharedItems>");
2287
+ const fg = this.cacheDefOpts?.fieldGroups?.get(i);
2288
+ if (fg) {
2289
+ const fgParts = ["<fieldGroup"];
2290
+ if (fg.parent !== void 0) fgParts.push(` par="${fg.parent}"`);
2291
+ if (fg.base !== void 0) fgParts.push(` base="${fg.base}"`);
2292
+ fgParts.push(">");
2293
+ if (fg.rangePr) {
2294
+ const rp = fg.rangePr;
2295
+ const rpAttrs = [];
2296
+ if (rp.autoStart === false) rpAttrs.push("autoStart=\"0\"");
2297
+ if (rp.autoEnd === false) rpAttrs.push("autoEnd=\"0\"");
2298
+ if (rp.groupBy && rp.groupBy !== "range") rpAttrs.push(`groupBy="${rp.groupBy}"`);
2299
+ if (rp.startNum !== void 0) rpAttrs.push(`startNum="${rp.startNum}"`);
2300
+ if (rp.endNum !== void 0) rpAttrs.push(`endNum="${rp.endNum}"`);
2301
+ if (rp.startDate) rpAttrs.push(`startDate="${escapeXml(rp.startDate)}"`);
2302
+ if (rp.endDate) rpAttrs.push(`endDate="${escapeXml(rp.endDate)}"`);
2303
+ if (rp.groupInterval !== void 0) rpAttrs.push(`groupInterval="${rp.groupInterval}"`);
2304
+ fgParts.push(`<rangePr${rpAttrs.length ? " " + rpAttrs.join(" ") : ""}/>`);
2305
+ }
2306
+ if (fg.discretePr && fg.discretePr.length > 0) {
2307
+ fgParts.push(`<discretePr count="${fg.discretePr.length}">`);
2308
+ for (const idx of fg.discretePr) fgParts.push(`<x v="${idx}"/>`);
2309
+ fgParts.push("</discretePr>");
2310
+ }
2311
+ if (fg.groupItems && fg.groupItems.length > 0) {
2312
+ fgParts.push(`<groupItems count="${fg.groupItems.length}">`);
2313
+ for (const gi of fg.groupItems) fgParts.push(`<s v="${escapeXml(gi)}"/>`);
2314
+ fgParts.push("</groupItems>");
2315
+ }
2316
+ fgParts.push("</fieldGroup>");
2317
+ p.push(fgParts.join(""));
2318
+ }
2319
+ p.push("</cacheField>");
1235
2320
  }
1236
2321
  }
1237
2322
  p.push("</cacheFields>");
1238
- p.push("</pivotCacheDefinition>");
1239
- return p.join("");
1240
- }
1241
- };
1242
- //#endregion
1243
- //#region src/file/pivot/pivot-cache-records-xml.ts
2323
+ if (this.cacheDefOpts?.mpMaps) for (const mp of this.cacheDefOpts.mpMaps) p.push(`<mpMap x="${mp.x}"/>`);
2324
+ if (this.olapPr) {
2325
+ const olAttrs = [];
2326
+ if (this.olapPr.local) olAttrs.push(` local="${escapeXml(this.olapPr.local)}"`);
2327
+ if (this.olapPr.localConnection) olAttrs.push(` localConnection="${escapeXml(this.olapPr.localConnection)}"`);
2328
+ if (this.olapPr.sendLocale) olAttrs.push(` sendLocale="1"`);
2329
+ if (this.olapPr.rowDrillCount !== void 0) olAttrs.push(` rowDrillCount="${this.olapPr.rowDrillCount}"`);
2330
+ if (this.olapPr.colDrillCount !== void 0) olAttrs.push(` colDrillCount="${this.olapPr.colDrillCount}"`);
2331
+ if (this.olapPr.localRefresh) olAttrs.push(" localRefresh=\"1\"");
2332
+ if (this.olapPr.serverFill === false) olAttrs.push(" serverFill=\"0\"");
2333
+ if (this.olapPr.serverNumberFormat === false) olAttrs.push(" serverNumberFormat=\"0\"");
2334
+ if (this.olapPr.serverFont === false) olAttrs.push(" serverFont=\"0\"");
2335
+ if (this.olapPr.serverFontColor === false) olAttrs.push(" serverFontColor=\"0\"");
2336
+ if (olAttrs.length > 0) p.push(`<olapPr${olAttrs.join("")}/>`);
2337
+ }
2338
+ if (this.cacheDefOpts?.cacheHierarchies && this.cacheDefOpts.cacheHierarchies.length > 0) {
2339
+ const chs = this.cacheDefOpts.cacheHierarchies;
2340
+ p.push(`<cacheHierarchies count="${chs.length}">`);
2341
+ for (const ch of chs) {
2342
+ const chAttrs = [`uniqueName="${escapeXml(ch.uniqueName)}"`, `count="${ch.count}"`];
2343
+ if (ch.caption) chAttrs.push(`caption="${escapeXml(ch.caption)}"`);
2344
+ if (ch.measure) chAttrs.push("measure=\"1\"");
2345
+ if (ch.set) chAttrs.push("set=\"1\"");
2346
+ if (ch.parentSet !== void 0) chAttrs.push(`parentSet="${ch.parentSet}"`);
2347
+ if (ch.iconSet !== void 0 && ch.iconSet !== 0) chAttrs.push(`iconSet="${ch.iconSet}"`);
2348
+ if (ch.attribute) chAttrs.push("attribute=\"1\"");
2349
+ if (ch.time) chAttrs.push("time=\"1\"");
2350
+ if (ch.keyAttribute) chAttrs.push("keyAttribute=\"1\"");
2351
+ if (ch.defaultMemberUniqueName) chAttrs.push(`defaultMemberUniqueName="${escapeXml(ch.defaultMemberUniqueName)}"`);
2352
+ if (ch.allUniqueName) chAttrs.push(`allUniqueName="${escapeXml(ch.allUniqueName)}"`);
2353
+ if (ch.allCaption) chAttrs.push(`allCaption="${escapeXml(ch.allCaption)}"`);
2354
+ if (ch.dimensionUniqueName) chAttrs.push(`dimensionUniqueName="${escapeXml(ch.dimensionUniqueName)}"`);
2355
+ if (ch.displayFolder) chAttrs.push(`displayFolder="${escapeXml(ch.displayFolder)}"`);
2356
+ if (ch.measureGroup) chAttrs.push(`measureGroup="${escapeXml(ch.measureGroup)}"`);
2357
+ if (ch.measures) chAttrs.push("measures=\"1\"");
2358
+ if (ch.oneField) chAttrs.push("oneField=\"1\"");
2359
+ if (ch.hidden) chAttrs.push("hidden=\"1\"");
2360
+ const hasGroupLevels = ch.groupLevels && ch.groupLevels.length > 0;
2361
+ const hasFieldsUsage = ch.fieldsUsage && ch.fieldsUsage.length > 0;
2362
+ if (hasGroupLevels || hasFieldsUsage) {
2363
+ p.push(`<cacheHierarchy ${chAttrs.join(" ")}>`);
2364
+ if (hasFieldsUsage) {
2365
+ const fuParts = [`<fieldsUsage count="${ch.fieldsUsage.length}">`];
2366
+ for (const fu of ch.fieldsUsage) fuParts.push(`<fieldUsage v="${fu.value}"/>`);
2367
+ fuParts.push("</fieldsUsage>");
2368
+ p.push(fuParts.join(""));
2369
+ }
2370
+ if (hasGroupLevels) {
2371
+ const glParts = [`<groupLevels count="${ch.groupLevels.length}">`];
2372
+ for (const gl of ch.groupLevels) {
2373
+ const glAttrs = [`uniqueName="${escapeXml(gl.uniqueName)}"`, `caption="${escapeXml(gl.caption)}"`];
2374
+ if (gl.user) glAttrs.push("user=\"1\"");
2375
+ if (gl.customRollUp) glAttrs.push("customRollUp=\"1\"");
2376
+ if (gl.groups && gl.groups.length > 0) {
2377
+ glParts.push(`<groupLevel ${glAttrs.join(" ")}><groups count="${gl.groups.length}">`);
2378
+ for (const lg of gl.groups) {
2379
+ const lgAttrs = [
2380
+ `name="${escapeXml(lg.name)}"`,
2381
+ `uniqueName="${escapeXml(lg.uniqueName)}"`,
2382
+ `caption="${escapeXml(lg.caption)}"`
2383
+ ];
2384
+ if (lg.uniqueParent) lgAttrs.push(`uniqueParent="${escapeXml(lg.uniqueParent)}"`);
2385
+ if (lg.id !== void 0) lgAttrs.push(`id="${lg.id}"`);
2386
+ glParts.push(`<group ${lgAttrs.join(" ")}><groupMembers count="${lg.members.length}">`);
2387
+ for (const gm of lg.members) {
2388
+ const gmAttrs = [`uniqueName="${escapeXml(gm.uniqueName)}"`];
2389
+ if (gm.group) gmAttrs.push("group=\"1\"");
2390
+ glParts.push(`<groupMember ${gmAttrs.join(" ")}/>`);
2391
+ }
2392
+ glParts.push("</groupMembers></group>");
2393
+ }
2394
+ glParts.push("</groups></groupLevel>");
2395
+ } else glParts.push(`<groupLevel ${glAttrs.join(" ")}/>`);
2396
+ }
2397
+ glParts.push("</groupLevels>");
2398
+ p.push(glParts.join(""));
2399
+ }
2400
+ p.push("</cacheHierarchy>");
2401
+ } else p.push(`<cacheHierarchy ${chAttrs.join(" ")}/>`);
2402
+ }
2403
+ p.push("</cacheHierarchies>");
2404
+ }
2405
+ if (this.cacheDefOpts?.kpis && this.cacheDefOpts.kpis.length > 0) {
2406
+ const kpis = this.cacheDefOpts.kpis;
2407
+ p.push(`<kpis count="${kpis.length}">`);
2408
+ for (const k of kpis) {
2409
+ const kAttrs = [`uniqueName="${escapeXml(k.uniqueName)}"`, `value="${escapeXml(k.value)}"`];
2410
+ if (k.caption) kAttrs.push(`caption="${escapeXml(k.caption)}"`);
2411
+ if (k.displayFolder) kAttrs.push(`displayFolder="${escapeXml(k.displayFolder)}"`);
2412
+ if (k.measureGroup) kAttrs.push(`measureGroup="${escapeXml(k.measureGroup)}"`);
2413
+ if (k.parent) kAttrs.push(`parent="${escapeXml(k.parent)}"`);
2414
+ if (k.goal) kAttrs.push(`goal="${escapeXml(k.goal)}"`);
2415
+ if (k.status) kAttrs.push(`status="${escapeXml(k.status)}"`);
2416
+ if (k.trend) kAttrs.push(`trend="${escapeXml(k.trend)}"`);
2417
+ if (k.weight) kAttrs.push(`weight="${escapeXml(k.weight)}"`);
2418
+ if (k.time) kAttrs.push(`time="${escapeXml(k.time)}"`);
2419
+ p.push(`<kpi ${kAttrs.join(" ")}/>`);
2420
+ }
2421
+ p.push("</kpis>");
2422
+ }
2423
+ if (this.cacheDefOpts?.measureGroups && this.cacheDefOpts.measureGroups.length > 0) {
2424
+ const mgs = this.cacheDefOpts.measureGroups;
2425
+ p.push(`<measureGroups count="${mgs.length}">`);
2426
+ for (const mg of mgs) p.push(`<measureGroup name="${escapeXml(mg.name)}" caption="${escapeXml(mg.caption)}"/>`);
2427
+ p.push("</measureGroups>");
2428
+ }
2429
+ if (this.cacheDefOpts?.measureDimensionMaps && this.cacheDefOpts.measureDimensionMaps.length > 0) {
2430
+ const mdm = this.cacheDefOpts.measureDimensionMaps;
2431
+ p.push(`<maps count="${mdm.length}">`);
2432
+ for (const m of mdm) {
2433
+ const mAttrs = [];
2434
+ if (m.measureGroup !== void 0) mAttrs.push(`measureGroup="${m.measureGroup}"`);
2435
+ if (m.dimension !== void 0) mAttrs.push(`dimension="${m.dimension}"`);
2436
+ p.push(`<map ${mAttrs.join(" ")}/>`);
2437
+ }
2438
+ p.push("</maps>");
2439
+ }
2440
+ if (this.cacheDefOpts?.dimensions && this.cacheDefOpts.dimensions.length > 0) {
2441
+ const dims = this.cacheDefOpts.dimensions;
2442
+ p.push(`<dimensions count="${dims.length}">`);
2443
+ for (const d of dims) {
2444
+ const dAttrs = [
2445
+ `name="${escapeXml(d.name)}"`,
2446
+ `uniqueName="${escapeXml(d.uniqueName)}"`,
2447
+ `caption="${escapeXml(d.caption)}"`
2448
+ ];
2449
+ if (d.measure) dAttrs.push("measure=\"1\"");
2450
+ p.push(`<dimension ${dAttrs.join(" ")}/>`);
2451
+ }
2452
+ p.push("</dimensions>");
2453
+ }
2454
+ const cd = this.cacheDefOpts;
2455
+ const hasEntries = cd?.entries && cd.entries.length > 0;
2456
+ const hasSets = cd?.sets && cd.sets.length > 0;
2457
+ const hasServerFormats = cd?.serverFormats && cd.serverFormats.length > 0;
2458
+ const hasQueryCache = cd?.queryCache && cd.queryCache.length > 0;
2459
+ if (hasEntries || hasSets || hasServerFormats || hasQueryCache) {
2460
+ p.push("<tupleCache>");
2461
+ if (hasEntries) {
2462
+ const entParts = [`<entries count="${cd.entries.length}">`];
2463
+ for (const ent of cd.entries) if (ent.type === "m") entParts.push("<m/>");
2464
+ else if (ent.type === "e" && ent.value !== void 0) entParts.push(`<e v="${ent.value}"/>`);
2465
+ else if (ent.value !== void 0) entParts.push(`<${ent.type} v="${ent.value}"/>`);
2466
+ entParts.push("</entries>");
2467
+ p.push(entParts.join(""));
2468
+ }
2469
+ if (hasSets) {
2470
+ p.push(`<sets count="${cd.sets.length}">`);
2471
+ for (const s of cd.sets) {
2472
+ const sAttrs = [`maxRank="${s.maxRank}"`, `setDefinition="${escapeXml(s.setDefinition)}"`];
2473
+ if (s.count !== void 0) sAttrs.push(`count="${s.count}"`);
2474
+ if (s.sortType && s.sortType !== "none") sAttrs.push(`sortType="${s.sortType}"`);
2475
+ if (s.queryFailed) sAttrs.push("queryFailed=\"1\"");
2476
+ p.push(`<set ${sAttrs.join(" ")}/>`);
2477
+ }
2478
+ p.push("</sets>");
2479
+ }
2480
+ if (hasServerFormats) {
2481
+ p.push(`<serverFormats count="${cd.serverFormats.length}">`);
2482
+ for (const sf of cd.serverFormats) {
2483
+ const sfAttrs = [];
2484
+ if (sf.culture) sfAttrs.push(`culture="${escapeXml(sf.culture)}"`);
2485
+ if (sf.format) sfAttrs.push(`format="${escapeXml(sf.format)}"`);
2486
+ p.push(`<serverFormat ${sfAttrs.join(" ")}/>`);
2487
+ }
2488
+ p.push("</serverFormats>");
2489
+ }
2490
+ if (hasQueryCache) {
2491
+ const qc = cd.queryCache;
2492
+ p.push(`<queryCache count="${qc.length}">`);
2493
+ for (const q of qc) {
2494
+ let qInner = "";
2495
+ if (q.tpls && q.tpls.length > 0) {
2496
+ qInner = `<tpls count="${q.tpls.length}">`;
2497
+ for (const tpl of q.tpls) if (tpl.items && tpl.items.length > 0) qInner += `<tpl>${tpl.items.map((i) => `<x v="${i}"/>`).join("")}</tpl>`;
2498
+ else qInner += "<tpl/>";
2499
+ qInner += "</tpls>";
2500
+ }
2501
+ if (qInner) p.push(`<query mdx="${escapeXml(q.mdx)}">${qInner}</query>`);
2502
+ else p.push(`<query mdx="${escapeXml(q.mdx)}"/>`);
2503
+ }
2504
+ p.push("</queryCache>");
2505
+ }
2506
+ p.push("</tupleCache>");
2507
+ }
2508
+ p.push("</pivotCacheDefinition>");
2509
+ return p.join("");
2510
+ }
2511
+ };
2512
+ //#endregion
2513
+ //#region src/file/pivot/pivot-cache-records-xml.ts
1244
2514
  /**
1245
2515
  * PivotCacheRecords XML generator.
1246
2516
  *
@@ -1273,7 +2543,9 @@ var PivotCacheRecordsXml = class extends BaseXmlComponent {
1273
2543
  p.push("<r>");
1274
2544
  for (let i = 0; i < row.length; i++) {
1275
2545
  const val = row[i];
1276
- if (this.numericFields[i]) p.push(`<n v="${val}"/>`);
2546
+ if (val === null) p.push("<m/>");
2547
+ else if (val instanceof Date) p.push(`<d v="${val.toISOString().replace(/\.\d{3}Z$/, "Z")}"/>`);
2548
+ else if (this.numericFields[i]) p.push(`<n v="${val}"/>`);
1277
2549
  else {
1278
2550
  const idx = this.fieldIndexMaps[i].get(String(val)) ?? 0;
1279
2551
  p.push(`<x v="${idx}"/>`);
@@ -1317,7 +2589,9 @@ var PivotTableXml = class extends BaseXmlComponent {
1317
2589
  const rowFieldIndices = rowFieldNames.map((n) => fields.indexOf(n));
1318
2590
  const colFieldIndices = colFieldNames.map((n) => fields.indexOf(n));
1319
2591
  const dataFieldIndices = dataFields.map((df) => fields.indexOf(df.field));
1320
- const pivotFieldsXml = this.buildPivotFields(rowFieldIndices, colFieldIndices, dataFieldIndices);
2592
+ const pageFieldIndices = (o.pages ?? []).map((n) => fields.indexOf(n));
2593
+ const pivotFieldsXml = this.buildPivotFields(rowFieldIndices, colFieldIndices, dataFieldIndices, pageFieldIndices);
2594
+ const pageFieldsXml = this.buildPageFields(pageFieldIndices);
1321
2595
  const rowFieldsXml = this.buildRowFields(rowFieldIndices);
1322
2596
  const rowItemsXml = this.buildRowItems(rowFieldIndices);
1323
2597
  const colFieldsXml = this.buildColFields(colFieldIndices);
@@ -1325,26 +2599,134 @@ var PivotTableXml = class extends BaseXmlComponent {
1325
2599
  const dataFieldsXml = this.buildDataFields(dataFields, dataFieldIndices);
1326
2600
  const locationRef = this.computeLocationRef(location, rowFieldIndices, colFieldIndices, dataFields);
1327
2601
  const p = [];
1328
- p.push(`<pivotTableDefinition xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" name="${escapeXml(name)}" cacheId="${this.cacheId}" dataCaption="Values" updatedVersion="6" minRefreshableVersion="3" createdVersion="6" applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" autoFormatId="0" useAutoFormatting="1" itemPrintTitles="1" indent="0" outline="1" outlineData="1" compact="1" compactData="1" rowGrandTotals="1" colGrandTotals="1">`);
2602
+ const defAttrs = [
2603
+ `name="${escapeXml(name)}"`,
2604
+ `cacheId="${this.cacheId}"`,
2605
+ "dataCaption=\"Values\"",
2606
+ "updatedVersion=\"6\"",
2607
+ "minRefreshableVersion=\"3\"",
2608
+ "createdVersion=\"6\"",
2609
+ "applyNumberFormats=\"0\"",
2610
+ "applyBorderFormats=\"0\"",
2611
+ "applyFontFormats=\"0\"",
2612
+ "applyPatternFormats=\"0\"",
2613
+ "applyAlignmentFormats=\"0\"",
2614
+ "applyWidthHeightFormats=\"1\"",
2615
+ "autoFormatId=\"0\"",
2616
+ "useAutoFormatting=\"1\"",
2617
+ "itemPrintTitles=\"1\"",
2618
+ "indent=\"0\"",
2619
+ "outline=\"1\"",
2620
+ "outlineData=\"1\"",
2621
+ "compact=\"1\"",
2622
+ "compactData=\"1\"",
2623
+ "rowGrandTotals=\"1\"",
2624
+ "colGrandTotals=\"1\""
2625
+ ];
2626
+ if (o.dataOnRows) defAttrs.push("dataOnRows=\"1\"");
2627
+ if (o.grandTotalCaption) defAttrs.push(`grandTotalCaption="${escapeXml(o.grandTotalCaption)}"`);
2628
+ if (o.errorCaption) defAttrs.push(`errorCaption="${escapeXml(o.errorCaption)}"`);
2629
+ if (o.showError) defAttrs.push("showError=\"1\"");
2630
+ if (o.missingCaption) defAttrs.push(`missingCaption="${escapeXml(o.missingCaption)}"`);
2631
+ if (o.showMissing === false) defAttrs.push("showMissing=\"0\"");
2632
+ if (o.pageStyle) defAttrs.push(`pageStyle="${escapeXml(o.pageStyle)}"`);
2633
+ if (o.pivotTableStyle) defAttrs.push(`pivotTableStyle="${escapeXml(o.pivotTableStyle)}"`);
2634
+ if (o.tag) defAttrs.push(`tag="${escapeXml(o.tag)}"`);
2635
+ if (o.showItems === false) defAttrs.push("showItems=\"0\"");
2636
+ if (o.editData) defAttrs.push("editData=\"1\"");
2637
+ if (o.disableFieldList) defAttrs.push("disableFieldList=\"1\"");
2638
+ if (o.showCalcMbrs === false) defAttrs.push("showCalcMbrs=\"0\"");
2639
+ if (o.visualTotals) defAttrs.push("visualTotals=\"1\"");
2640
+ if (o.showMultipleLabel === false) defAttrs.push("showMultipleLabel=\"0\"");
2641
+ if (o.showDataDropDown === false) defAttrs.push("showDataDropDown=\"0\"");
2642
+ if (o.showDrill === false) defAttrs.push("showDrill=\"0\"");
2643
+ if (o.printDrill) defAttrs.push("printDrill=\"1\"");
2644
+ if (o.showMemberPropertyTips) defAttrs.push("showMemberPropertyTips=\"1\"");
2645
+ if (o.showDataTips === false) defAttrs.push("showDataTips=\"0\"");
2646
+ if (o.enableWizard === false) defAttrs.push("enableWizard=\"0\"");
2647
+ if (o.enableDrill === false) defAttrs.push("enableDrill=\"0\"");
2648
+ if (o.enableFieldProperties === false) defAttrs.push("enableFieldProperties=\"0\"");
2649
+ if (o.pageWrap !== void 0) defAttrs.push(`pageWrap="${o.pageWrap}"`);
2650
+ if (o.pageOverThenDown) defAttrs.push("pageOverThenDown=\"1\"");
2651
+ if (o.subtotalHiddenItems) defAttrs.push("subtotalHiddenItems=\"1\"");
2652
+ if (o.fieldPrintTitles) defAttrs.push("fieldPrintTitles=\"1\"");
2653
+ if (o.mergeItem) defAttrs.push("mergeItem=\"1\"");
2654
+ if (o.showDropZones === false) defAttrs.push("showDropZones=\"0\"");
2655
+ if (o.showEmptyRow) defAttrs.push("showEmptyRow=\"1\"");
2656
+ if (o.showEmptyCol) defAttrs.push("showEmptyCol=\"1\"");
2657
+ if (o.showHeaders === false) defAttrs.push("showHeaders=\"0\"");
2658
+ if (o.published) defAttrs.push("published=\"1\"");
2659
+ if (o.gridDropZones === false) defAttrs.push("gridDropZones=\"0\"");
2660
+ if (o.multipleFieldFilters === false) defAttrs.push("multipleFieldFilters=\"0\"");
2661
+ if (o.rowHeaderCaption) defAttrs.push(`rowHeaderCaption="${escapeXml(o.rowHeaderCaption)}"`);
2662
+ if (o.colHeaderCaption) defAttrs.push(`colHeaderCaption="${escapeXml(o.colHeaderCaption)}"`);
2663
+ if (o.fieldListSortAscending) defAttrs.push("fieldListSortAscending=\"1\"");
2664
+ if (o.mdxSubqueries) defAttrs.push("mdxSubqueries=\"1\"");
2665
+ if (o.customListSort === false) defAttrs.push("customListSort=\"0\"");
2666
+ p.push(`<pivotTableDefinition xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" ${defAttrs.join(" ")}>`);
1329
2667
  p.push(`<location ref="${escapeXml(locationRef)}" firstHeaderRow="1" firstDataRow="${colFieldIndices.length + 1}" firstDataCol="${rowFieldIndices.length}"/>`);
1330
2668
  p.push(pivotFieldsXml);
2669
+ if (o.pivotHierarchies && o.pivotHierarchies.length > 0) p.push(this.buildPivotHierarchies(o.pivotHierarchies));
2670
+ if (pageFieldIndices.length > 0) p.push(pageFieldsXml);
1331
2671
  p.push(rowFieldsXml);
1332
2672
  p.push(rowItemsXml);
1333
2673
  if (colFieldIndices.length > 0) p.push(colFieldsXml);
1334
2674
  p.push(colItemsXml);
1335
2675
  if (dataFields.length > 0) p.push(dataFieldsXml);
1336
2676
  p.push(`<pivotTableStyleInfo name="${escapeXml(style)}" showRowHeaders="1" showColHeaders="1" showRowStripes="0" showColStripes="0" showLastColumn="1"/>`);
2677
+ if (o.filters && o.filters.length > 0) p.push(this.buildFilters(o.filters));
2678
+ if (o.calculatedItems && o.calculatedItems.length > 0) p.push(this.buildCalculatedItems(o.calculatedItems));
2679
+ if (o.calculatedMembers && o.calculatedMembers.length > 0) p.push(this.buildCalculatedMembers(o.calculatedMembers));
2680
+ if (o.formats && o.formats.length > 0) {
2681
+ const fmtParts = [`<formats count="${o.formats.length}">`];
2682
+ for (const fmt of o.formats) {
2683
+ const fmtAttrs = [];
2684
+ if (fmt.action && fmt.action !== "formatting") fmtAttrs.push(`action="${fmt.action}"`);
2685
+ if (fmt.dxfId !== void 0) fmtAttrs.push(`dxfId="${fmt.dxfId}"`);
2686
+ fmtParts.push(`<format${fmtAttrs.length ? " " + fmtAttrs.join(" ") : ""}>${this.buildPivotAreaXml(fmt.pivotArea)}</format>`);
2687
+ }
2688
+ fmtParts.push("</formats>");
2689
+ p.push(fmtParts.join(""));
2690
+ }
2691
+ if (o.pivotConditionalFormats && o.pivotConditionalFormats.length > 0) p.push(this.buildPivotConditionalFormats(o.pivotConditionalFormats));
2692
+ if (o.chartFormats && o.chartFormats.length > 0) p.push(this.buildChartFormats(o.chartFormats));
2693
+ if (o.rowHierarchiesUsage && o.rowHierarchiesUsage.length > 0) {
2694
+ const rhu = o.rowHierarchiesUsage;
2695
+ p.push(`<rowHierarchiesUsage count="${rhu.length}">${rhu.map((h) => `<rowHierarchyUsage hierarchyUsage="${h.hierarchyUsage}"/>`).join("")}</rowHierarchiesUsage>`);
2696
+ }
2697
+ if (o.colHierarchiesUsage && o.colHierarchiesUsage.length > 0) {
2698
+ const chu = o.colHierarchiesUsage;
2699
+ p.push(`<colHierarchiesUsage count="${chu.length}">${chu.map((h) => `<colHierarchyUsage hierarchyUsage="${h.hierarchyUsage}"/>`).join("")}</colHierarchiesUsage>`);
2700
+ }
1337
2701
  p.push("</pivotTableDefinition>");
1338
2702
  return p.join("");
1339
2703
  }
1340
- buildPivotFields(rowIndices, colIndices, dataIndices) {
2704
+ buildPivotFields(rowIndices, colIndices, dataIndices, pageIndices) {
1341
2705
  const fields = this.sourceData.fieldNames;
2706
+ const o = this.options;
1342
2707
  const parts = [`<pivotFields count="${fields.length}">`];
1343
2708
  for (let i = 0; i < fields.length; i++) {
1344
2709
  const isRow = rowIndices.includes(i);
1345
2710
  const isCol = colIndices.includes(i);
1346
- if (dataIndices.includes(i)) parts.push(`<pivotField dataField="1" showAll="0"/>`);
1347
- else if (isRow) {
2711
+ const isData = dataIndices.includes(i);
2712
+ const isPage = pageIndices.includes(i);
2713
+ if (isData) {
2714
+ const dataFieldIdx = dataIndices.indexOf(i);
2715
+ const df = o.data[dataFieldIdx];
2716
+ const dfAttrs = ["dataField=\"1\"", "showAll=\"0\""];
2717
+ if (df?.showDataAs) dfAttrs.push(`showDataAs="${df.showDataAs}"`);
2718
+ if (df?.baseField !== void 0) dfAttrs.push(`baseField="${df.baseField}"`);
2719
+ if (df?.baseItem !== void 0) dfAttrs.push(`baseItem="${df.baseItem}"`);
2720
+ if (o.autoSortScope || df?.sortByTupleItems && df.sortByTupleItems.length > 0) {
2721
+ const scopeChildren = [];
2722
+ if (o.autoSortScope) scopeChildren.push(this.buildPivotAreaXml(o.autoSortScope));
2723
+ if (df?.sortByTupleItems && df.sortByTupleItems.length > 0) {
2724
+ const tplXml = df.sortByTupleItems.map((v) => `<tpl><x v="${v}"/></tpl>`).join("");
2725
+ scopeChildren.push(`<sortByTuple>${tplXml}</sortByTuple>`);
2726
+ }
2727
+ parts.push(`<pivotField ${dfAttrs.join(" ")}><autoSortScope>${scopeChildren.join("")}</autoSortScope></pivotField>`);
2728
+ } else parts.push(`<pivotField ${dfAttrs.join(" ")}/>`);
2729
+ } else if (isRow) {
1348
2730
  const uniqueVals = collectUniqueValues(this.sourceData.records, i);
1349
2731
  parts.push(`<pivotField axis="axisRow" showAll="0">`);
1350
2732
  parts.push(`<items count="${uniqueVals.length + 1}">`);
@@ -1358,11 +2740,25 @@ var PivotTableXml = class extends BaseXmlComponent {
1358
2740
  for (let j = 0; j < uniqueVals.length; j++) parts.push(`<item x="${j}"/>`);
1359
2741
  parts.push(`<item t="default"/>`);
1360
2742
  parts.push("</items></pivotField>");
2743
+ } else if (isPage) {
2744
+ const uniqueVals = collectUniqueValues(this.sourceData.records, i);
2745
+ parts.push(`<pivotField axis="axisPage" showAll="0">`);
2746
+ parts.push(`<items count="${uniqueVals.length + 1}">`);
2747
+ for (let j = 0; j < uniqueVals.length; j++) parts.push(`<item x="${j}"/>`);
2748
+ parts.push(`<item t="default"/>`);
2749
+ parts.push("</items></pivotField>");
1361
2750
  } else parts.push(`<pivotField showAll="0"/>`);
1362
2751
  }
1363
2752
  parts.push("</pivotFields>");
1364
2753
  return parts.join("");
1365
2754
  }
2755
+ buildPageFields(pageIndices) {
2756
+ if (pageIndices.length === 0) return "";
2757
+ const parts = [`<pageFields count="${pageIndices.length}">`];
2758
+ for (let i = 0; i < pageIndices.length; i++) parts.push(`<pageField fld="${pageIndices[i]}" hier="${i}"/>`);
2759
+ parts.push("</pageFields>");
2760
+ return parts.join("");
2761
+ }
1366
2762
  buildRowFields(rowIndices) {
1367
2763
  if (rowIndices.length === 0) return "<rowFields count=\"0\"/>";
1368
2764
  const parts = [`<rowFields count="${rowIndices.length}">`];
@@ -1429,8 +2825,15 @@ var PivotTableXml = class extends BaseXmlComponent {
1429
2825
  for (let i = 0; i < dataFields.length; i++) {
1430
2826
  const df = dataFields[i];
1431
2827
  const subtotal = df.summarize ?? "sum";
1432
- const name = df.name ?? `${subtotal === "sum" ? "Sum" : subtotal} of ${df.field}`;
1433
- parts.push(`<dataField name="${escapeXml(name)}" fld="${dataFieldIndices[i]}" subtotal="${subtotal}"/>`);
2828
+ const dfAttrs = [
2829
+ `name="${escapeXml(df.name ?? `${subtotal === "sum" ? "Sum" : subtotal} of ${df.field}`)}"`,
2830
+ `fld="${dataFieldIndices[i]}"`,
2831
+ `subtotal="${subtotal}"`
2832
+ ];
2833
+ if (df.showDataAs) dfAttrs.push(`showDataAs="${df.showDataAs}"`);
2834
+ if (df.baseField !== void 0) dfAttrs.push(`baseField="${df.baseField}"`);
2835
+ if (df.baseItem !== void 0) dfAttrs.push(`baseItem="${df.baseItem}"`);
2836
+ parts.push(`<dataField ${dfAttrs.join(" ")}/>`);
1434
2837
  }
1435
2838
  parts.push("</dataFields>");
1436
2839
  return parts.join("");
@@ -1449,6 +2852,147 @@ var PivotTableXml = class extends BaseXmlComponent {
1449
2852
  colCount += 1;
1450
2853
  return `${startCol}${startRow}:${colIndexToLetter(letterToColIndex(startCol) + colCount - 1)}${startRow + rowCount - 1}`;
1451
2854
  }
2855
+ buildFilters(filters) {
2856
+ const parts = [`<filters count="${filters.length}">`];
2857
+ for (const f of filters) {
2858
+ const fAttrs = {
2859
+ fld: f.fld,
2860
+ type: f.type,
2861
+ id: f.id
2862
+ };
2863
+ if (f.mpFld !== void 0) fAttrs.mpFld = f.mpFld;
2864
+ if (f.evalOrder !== void 0) fAttrs.evalOrder = f.evalOrder;
2865
+ if (f.iMeasureHier !== void 0) fAttrs.iMeasureHier = f.iMeasureHier;
2866
+ if (f.iMeasureFld !== void 0) fAttrs.iMeasureFld = f.iMeasureFld;
2867
+ if (f.name !== void 0) fAttrs.name = f.name;
2868
+ if (f.description !== void 0) fAttrs.description = f.description;
2869
+ if (f.stringValue1 !== void 0) fAttrs.stringValue1 = f.stringValue1;
2870
+ if (f.stringValue2 !== void 0) fAttrs.stringValue2 = f.stringValue2;
2871
+ parts.push(`<filter${attrs(fAttrs)}><autoFilter/></filter>`);
2872
+ }
2873
+ parts.push("</filters>");
2874
+ return parts.join("");
2875
+ }
2876
+ buildPivotHierarchies(hierarchies) {
2877
+ const parts = [`<pivotHierarchies count="${hierarchies.length}">`];
2878
+ for (const h of hierarchies) {
2879
+ const hAttrs = [];
2880
+ if (h.outline) hAttrs.push("outline=\"1\"");
2881
+ if (h.multipleItemSelectionAllowed) hAttrs.push("multipleItemSelectionAllowed=\"1\"");
2882
+ if (h.subtotalTop) hAttrs.push("subtotalTop=\"1\"");
2883
+ if (h.showInFieldList === false) hAttrs.push("showInFieldList=\"0\"");
2884
+ if (h.dragToRow === false) hAttrs.push("dragToRow=\"0\"");
2885
+ if (h.dragToCol === false) hAttrs.push("dragToCol=\"0\"");
2886
+ if (h.dragToPage === false) hAttrs.push("dragToPage=\"0\"");
2887
+ if (h.dragToData) hAttrs.push("dragToData=\"1\"");
2888
+ if (h.dragOff === false) hAttrs.push("dragOff=\"0\"");
2889
+ if (h.includeNewItemsInFilter) hAttrs.push("includeNewItemsInFilter=\"1\"");
2890
+ if (h.caption) hAttrs.push(`caption="${escapeXml(h.caption)}"`);
2891
+ const inner = (h.memberProperties ? `<mps count="${h.memberProperties.length}">${h.memberProperties.map((mp) => {
2892
+ const mpAttrs = [`field="${mp.field}"`];
2893
+ if (mp.name !== void 0) mpAttrs.push(`name="${escapeXml(mp.name)}"`);
2894
+ if (mp.showCell) mpAttrs.push("showCell=\"1\"");
2895
+ if (mp.showTip) mpAttrs.push("showTip=\"1\"");
2896
+ return `<mp ${mpAttrs.join(" ")}/>`;
2897
+ }).join("")}</mps>` : "") + (h.members ? `<members count="${h.members.length}">${h.members.map((m) => `<member name="${escapeXml(m.name)}"/>`).join("")}</members>` : "");
2898
+ if (inner) parts.push(`<pivotHierarchy ${hAttrs.join(" ")}>${inner}</pivotHierarchy>`);
2899
+ else parts.push(`<pivotHierarchy ${hAttrs.join(" ")}/>`);
2900
+ }
2901
+ parts.push("</pivotHierarchies>");
2902
+ return parts.join("");
2903
+ }
2904
+ buildCalculatedItems(items) {
2905
+ const parts = [`<calculatedItems count="${items.length}">`];
2906
+ for (const item of items) {
2907
+ const ciAttrs = [];
2908
+ if (item.field !== void 0) ciAttrs.push(`field="${item.field}"`);
2909
+ if (item.formula) ciAttrs.push(`formula="${escapeXml(item.formula)}"`);
2910
+ const inner = item.pivotArea ? this.buildPivotAreaXml(item.pivotArea) : "";
2911
+ if (inner) parts.push(`<calculatedItem ${ciAttrs.join(" ")}>${inner}</calculatedItem>`);
2912
+ else parts.push(`<calculatedItem ${ciAttrs.join(" ")}/>`);
2913
+ }
2914
+ parts.push("</calculatedItems>");
2915
+ return parts.join("");
2916
+ }
2917
+ buildCalculatedMembers(members) {
2918
+ const parts = [`<calculatedMembers count="${members.length}">`];
2919
+ for (const m of members) {
2920
+ const mAttrs = [`name="${escapeXml(m.name)}"`, `mdx="${escapeXml(m.mdx)}"`];
2921
+ if (m.memberName) mAttrs.push(`memberName="${escapeXml(m.memberName)}"`);
2922
+ if (m.hierarchy) mAttrs.push(`hierarchy="${escapeXml(m.hierarchy)}"`);
2923
+ if (m.parent) mAttrs.push(`parent="${escapeXml(m.parent)}"`);
2924
+ if (m.solveOrder !== void 0) mAttrs.push(`solveOrder="${m.solveOrder}"`);
2925
+ if (m.set) mAttrs.push("set=\"1\"");
2926
+ parts.push(`<calculatedMember ${mAttrs.join(" ")}/>`);
2927
+ }
2928
+ parts.push("</calculatedMembers>");
2929
+ return parts.join("");
2930
+ }
2931
+ buildPivotConditionalFormats(formats) {
2932
+ const parts = [`<conditionalFormats count="${formats.length}">`];
2933
+ for (const cf of formats) {
2934
+ const cfAttrs = [`priority="${cf.priority}"`];
2935
+ if (cf.scope && cf.scope !== "selection") cfAttrs.push(`scope="${cf.scope}"`);
2936
+ if (cf.type && cf.type !== "none") cfAttrs.push(`type="${cf.type}"`);
2937
+ const areasXml = cf.pivotAreas?.map((a) => this.buildPivotAreaXml(a)).join("") ?? "";
2938
+ const pivotAreasXml = areasXml ? `<pivotAreas>${areasXml}</pivotAreas>` : "";
2939
+ parts.push(`<conditionalFormat ${cfAttrs.join(" ")}>${pivotAreasXml}</conditionalFormat>`);
2940
+ }
2941
+ parts.push("</conditionalFormats>");
2942
+ return parts.join("");
2943
+ }
2944
+ buildChartFormats(formats) {
2945
+ const parts = [`<chartFormats count="${formats.length}">`];
2946
+ for (const cf of formats) {
2947
+ const cfAttrs = [`chart="${cf.chart}"`, `format="${cf.format}"`];
2948
+ if (cf.series) cfAttrs.push("series=\"1\"");
2949
+ const areaXml = cf.pivotArea ? this.buildPivotAreaXml(cf.pivotArea) : "";
2950
+ if (areaXml) parts.push(`<chartFormat ${cfAttrs.join(" ")}>${areaXml}</chartFormat>`);
2951
+ else parts.push(`<chartFormat ${cfAttrs.join(" ")}/>`);
2952
+ }
2953
+ parts.push("</chartFormats>");
2954
+ return parts.join("");
2955
+ }
2956
+ buildPivotAreaXml(area) {
2957
+ const aAttrs = [];
2958
+ if (area.field !== void 0) aAttrs.push(`field="${area.field}"`);
2959
+ if (area.type) aAttrs.push(`type="${area.type}"`);
2960
+ if (area.dataOnly === false) aAttrs.push("dataOnly=\"0\"");
2961
+ if (area.labelOnly) aAttrs.push("labelOnly=\"1\"");
2962
+ if (area.grandRow) aAttrs.push("grandRow=\"1\"");
2963
+ if (area.grandCol) aAttrs.push("grandCol=\"1\"");
2964
+ if (area.cacheIndex) aAttrs.push("cacheIndex=\"1\"");
2965
+ if (area.outline === false) aAttrs.push("outline=\"0\"");
2966
+ if (area.offset) aAttrs.push(`offset="${escapeXml(area.offset)}"`);
2967
+ if (area.collapsedLevelsAreSubtotals) aAttrs.push("collapsedLevelsAreSubtotals=\"1\"");
2968
+ if (area.axis) aAttrs.push(`axis="${area.axis}"`);
2969
+ if (area.fieldPosition !== void 0) aAttrs.push(`fieldPosition="${area.fieldPosition}"`);
2970
+ const refsXml = area.references ? this.buildPivotAreaReferences(area.references) : "";
2971
+ if (refsXml) return `<pivotArea ${aAttrs.join(" ")}>${refsXml}</pivotArea>`;
2972
+ return `<pivotArea ${aAttrs.join(" ")}/>`;
2973
+ }
2974
+ buildPivotAreaReferences(refs) {
2975
+ const parts = [`<references count="${refs.length}">`];
2976
+ for (const ref of refs) {
2977
+ const rAttrs = [];
2978
+ if (ref.field !== void 0) rAttrs.push(`field="${ref.field}"`);
2979
+ if (ref.count !== void 0) rAttrs.push(`count="${ref.count}"`);
2980
+ if (ref.selected === false) rAttrs.push("selected=\"0\"");
2981
+ if (ref.byPosition) rAttrs.push("byPosition=\"1\"");
2982
+ if (ref.relative) rAttrs.push("relative=\"1\"");
2983
+ if (ref.defaultSubtotal) rAttrs.push("defaultSubtotal=\"1\"");
2984
+ if (ref.sumSubtotal) rAttrs.push("sumSubtotal=\"1\"");
2985
+ if (ref.countASubtotal) rAttrs.push("countASubtotal=\"1\"");
2986
+ if (ref.avgSubtotal) rAttrs.push("avgSubtotal=\"1\"");
2987
+ if (ref.maxSubtotal) rAttrs.push("maxSubtotal=\"1\"");
2988
+ if (ref.minSubtotal) rAttrs.push("minSubtotal=\"1\"");
2989
+ const xXml = ref.x ? ref.x.map((v) => `<x v="${v}"/>`).join("") : "";
2990
+ if (xXml) parts.push(`<reference ${rAttrs.join(" ")}>${xXml}</reference>`);
2991
+ else parts.push(`<reference ${rAttrs.join(" ")}/>`);
2992
+ }
2993
+ parts.push("</references>");
2994
+ return parts.join("");
2995
+ }
1452
2996
  };
1453
2997
  function letterToColIndex(letters) {
1454
2998
  let col = 0;
@@ -1477,6 +3021,1158 @@ function cartesianOfCounts(counts) {
1477
3021
  return result;
1478
3022
  }
1479
3023
  //#endregion
3024
+ //#region src/file/table/table-xml.ts
3025
+ /**
3026
+ * Table XML generator — generates xl/tables/table{n}.xml.
3027
+ *
3028
+ * Implements CT_Table from sml.xsd (transitional schema).
3029
+ *
3030
+ * @module
3031
+ */
3032
+ const TotalsRowFunction = {
3033
+ NONE: "none",
3034
+ SUM: "sum",
3035
+ MIN: "min",
3036
+ MAX: "max",
3037
+ AVERAGE: "average",
3038
+ COUNT: "count",
3039
+ COUNT_NUMS: "countNums",
3040
+ STD_DEV: "stdDev",
3041
+ VAR: "var",
3042
+ CUSTOM: "custom"
3043
+ };
3044
+ const TableType = {
3045
+ WORKSHEET: "worksheet",
3046
+ XML: "xml",
3047
+ QUERY_TABLE: "queryTable"
3048
+ };
3049
+ /**
3050
+ * Table XML component — generates xl/tables/table{n}.xml.
3051
+ *
3052
+ * Follows the zero-allocation string concatenation pattern used by other
3053
+ * XLSX components.
3054
+ */
3055
+ var TableXml = class extends BaseXmlComponent {
3056
+ opts;
3057
+ constructor(options) {
3058
+ super("table");
3059
+ this.opts = options;
3060
+ }
3061
+ toXml(_context) {
3062
+ const o = this.opts;
3063
+ const p = [];
3064
+ const rootAttrs = {
3065
+ id: o.id,
3066
+ name: o.name ?? o.displayName,
3067
+ displayName: o.displayName,
3068
+ ref: o.ref
3069
+ };
3070
+ if (o.tableType && o.tableType !== "worksheet") rootAttrs.tableType = o.tableType;
3071
+ if (o.headerRowCount !== void 0 && o.headerRowCount !== 1) rootAttrs.headerRowCount = o.headerRowCount;
3072
+ if (o.totalsRowCount !== void 0 && o.totalsRowCount > 0) rootAttrs.totalsRowCount = o.totalsRowCount;
3073
+ if (o.totalsRowShown === false) rootAttrs.totalsRowShown = 0;
3074
+ if (o.insertRowShift) rootAttrs.insertRowShift = 1;
3075
+ if (o.published) rootAttrs.published = 1;
3076
+ if (o.headerRowDxfId !== void 0) rootAttrs.headerRowDxfId = o.headerRowDxfId;
3077
+ if (o.dataDxfId !== void 0) rootAttrs.dataDxfId = o.dataDxfId;
3078
+ if (o.totalsRowDxfId !== void 0) rootAttrs.totalsRowDxfId = o.totalsRowDxfId;
3079
+ if (o.headerRowBorderDxfId !== void 0) rootAttrs.headerRowBorderDxfId = o.headerRowBorderDxfId;
3080
+ if (o.tableBorderDxfId !== void 0) rootAttrs.tableBorderDxfId = o.tableBorderDxfId;
3081
+ if (o.totalsRowBorderDxfId !== void 0) rootAttrs.totalsRowBorderDxfId = o.totalsRowBorderDxfId;
3082
+ if (o.headerRowCellStyle) rootAttrs.headerRowCellStyle = o.headerRowCellStyle;
3083
+ if (o.dataCellStyle) rootAttrs.dataCellStyle = o.dataCellStyle;
3084
+ if (o.totalsRowCellStyle) rootAttrs.totalsRowCellStyle = o.totalsRowCellStyle;
3085
+ p.push(`<table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="xr xr2" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2"${this.buildAttrs(rootAttrs)}>`);
3086
+ if (o.autoFilter !== void 0) p.push(`<autoFilter ref="${escapeXml(o.autoFilter)}"/>`);
3087
+ p.push(`<tableColumns count="${o.columns.length}">`);
3088
+ for (let i = 0; i < o.columns.length; i++) {
3089
+ const col = o.columns[i];
3090
+ const colAttrs = {
3091
+ id: i + 1,
3092
+ name: col.name
3093
+ };
3094
+ const inner = [];
3095
+ if (col.calculatedColumnFormula !== void 0) {
3096
+ const fAttrs = col.calculatedColumnFormulaArray ? " array=\"1\"" : "";
3097
+ inner.push(`<calculatedColumnFormula${fAttrs}>${escapeXml(col.calculatedColumnFormula)}</calculatedColumnFormula>`);
3098
+ }
3099
+ if (col.totalsRowFormula !== void 0) {
3100
+ const fAttrs = col.totalsRowFormulaArray ? " array=\"1\"" : "";
3101
+ inner.push(`<totalsRowFormula${fAttrs}>${escapeXml(col.totalsRowFormula)}</totalsRowFormula>`);
3102
+ }
3103
+ if (col.totalsRowFunction === TotalsRowFunction.CUSTOM && col.totalsRowLabel) {}
3104
+ if (col.totalsRowFunction !== void 0 && col.totalsRowFunction !== TotalsRowFunction.NONE) colAttrs.totalsRowFunction = col.totalsRowFunction;
3105
+ if (col.totalsRowLabel !== void 0) colAttrs.totalsRowLabel = col.totalsRowLabel;
3106
+ if (col.uniqueName) colAttrs.uniqueName = col.uniqueName;
3107
+ if (col.queryTableFieldId !== void 0) colAttrs.queryTableFieldId = col.queryTableFieldId;
3108
+ if (col.headerRowDxfId !== void 0) colAttrs.headerRowDxfId = col.headerRowDxfId;
3109
+ if (col.dataDxfId !== void 0) colAttrs.dataDxfId = col.dataDxfId;
3110
+ if (col.totalsRowDxfId !== void 0) colAttrs.totalsRowDxfId = col.totalsRowDxfId;
3111
+ if (col.headerRowCellStyle) colAttrs.headerRowCellStyle = col.headerRowCellStyle;
3112
+ if (col.dataCellStyle) colAttrs.dataCellStyle = col.dataCellStyle;
3113
+ if (col.totalsRowCellStyle) colAttrs.totalsRowCellStyle = col.totalsRowCellStyle;
3114
+ if (inner.length > 0) p.push(`<tableColumn${this.buildAttrs(colAttrs)}>${inner.join("")}</tableColumn>`);
3115
+ else p.push(`<tableColumn${this.buildAttrs(colAttrs)}/>`);
3116
+ }
3117
+ p.push("</tableColumns>");
3118
+ if (o.style) {
3119
+ const s = o.style;
3120
+ const styleAttrs = {};
3121
+ if (s.name !== void 0) styleAttrs.name = s.name;
3122
+ if (s.showFirstColumn) styleAttrs.showFirstColumn = 1;
3123
+ if (s.showLastColumn) styleAttrs.showLastColumn = 1;
3124
+ if (s.showRowStripes !== false) styleAttrs.showRowStripes = 1;
3125
+ if (s.showColumnStripes) styleAttrs.showColumnStripes = 1;
3126
+ p.push(`<tableStyleInfo${this.buildAttrs(styleAttrs)}/>`);
3127
+ } else p.push("<tableStyleInfo name=\"TableStyleMedium9\" showFirstColumn=\"0\" showLastColumn=\"0\" showRowStripes=\"1\" showColumnStripes=\"0\"/>");
3128
+ p.push("</table>");
3129
+ return p.join("");
3130
+ }
3131
+ buildAttrs(attrs) {
3132
+ const parts = [];
3133
+ for (const [k, v] of Object.entries(attrs)) {
3134
+ if (v === void 0) continue;
3135
+ parts.push(` ${k}="${typeof v === "string" ? escapeXml(v) : String(v)}"`);
3136
+ }
3137
+ return parts.join("");
3138
+ }
3139
+ };
3140
+ //#endregion
3141
+ //#region src/file/dialogsheet/dialogsheet.ts
3142
+ /**
3143
+ * Dialogsheet XML generator — produces xl/dialogsheets/sheetN.xml.
3144
+ *
3145
+ * A dialogsheet is a legacy Excel 5.0 dialog sheet (no cell data).
3146
+ *
3147
+ * Reference: OOXML transitional, sml.xsd, CT_Dialogsheet
3148
+ *
3149
+ * @module
3150
+ */
3151
+ var Dialogsheet = class extends BaseXmlComponent {
3152
+ opts;
3153
+ constructor(options) {
3154
+ super("dialogsheet");
3155
+ this.opts = options;
3156
+ }
3157
+ toXml(_context) {
3158
+ const p = ["<dialogsheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">"];
3159
+ if (this.opts.tabColor) p.push(`<sheetPr><tabColor${attrs({ rgb: this.opts.tabColor })}/></sheetPr>`);
3160
+ p.push("<sheetViews><sheetView workbookViewId=\"0\"/></sheetViews>");
3161
+ if (this.opts.sheetProtection) {
3162
+ const sp = this.opts.sheetProtection;
3163
+ const spAttrs = {};
3164
+ if (sp.content) spAttrs.sheet = "1";
3165
+ if (sp.objects) spAttrs.objects = "1";
3166
+ if (sp.scenarios) spAttrs.scenarios = "1";
3167
+ if (Object.keys(spAttrs).length > 0) p.push(`<sheetProtection${attrs(spAttrs)}/>`);
3168
+ }
3169
+ if (this.opts.pageMargins) {
3170
+ const pm = this.opts.pageMargins;
3171
+ p.push(`<pageMargins${attrs({
3172
+ left: pm.left ?? .7,
3173
+ right: pm.right ?? .7,
3174
+ top: pm.top ?? .75,
3175
+ bottom: pm.bottom ?? .75,
3176
+ header: pm.header ?? .3,
3177
+ footer: pm.footer ?? .3
3178
+ })}/>`);
3179
+ }
3180
+ if (this.opts.pageSetup) {
3181
+ const ps = this.opts.pageSetup;
3182
+ p.push(`<pageSetup${attrs({
3183
+ paperSize: ps.paperSize,
3184
+ orientation: ps.orientation,
3185
+ horizontalDpi: ps.horizontalDpi,
3186
+ verticalDpi: ps.verticalDpi,
3187
+ copies: ps.copies
3188
+ })}/>`);
3189
+ }
3190
+ p.push("</dialogsheet>");
3191
+ return p.join("");
3192
+ }
3193
+ };
3194
+ //#endregion
3195
+ //#region src/file/query-table/query-table-xml.ts
3196
+ /**
3197
+ * QueryTable XML generator — produces xl/queryTables/queryTable{n}.xml.
3198
+ *
3199
+ * A query table represents data retrieved from an external data source.
3200
+ *
3201
+ * Reference: OOXML transitional, sml.xsd, CT_QueryTable
3202
+ *
3203
+ * @module
3204
+ */
3205
+ var QueryTableXml = class extends BaseXmlComponent {
3206
+ opts;
3207
+ constructor(options) {
3208
+ super("queryTable");
3209
+ this.opts = options;
3210
+ }
3211
+ toXml(_context) {
3212
+ const o = this.opts;
3213
+ const a = {
3214
+ name: o.name ?? "QueryTable1",
3215
+ connectionId: o.connectionId,
3216
+ autoFormat: o.autoFormat ? 1 : void 0,
3217
+ preserveFormatting: o.preserveFormatting ? 1 : void 0,
3218
+ adjustColumnWidth: o.adjustColumnWidth !== false ? 1 : 0,
3219
+ refreshOnLoad: o.refreshOnLoad ? 1 : void 0,
3220
+ backgroundRefresh: o.backgroundRefresh ? 1 : void 0,
3221
+ rowNumbers: o.rowNumbers ? 1 : void 0,
3222
+ disableRefresh: o.disableRefresh ? 1 : void 0,
3223
+ firstBackgroundRefresh: o.firstBackgroundRefresh ? 1 : void 0,
3224
+ growShrinkType: o.growShrinkType ? 1 : void 0,
3225
+ fillFormulas: o.fillFormulas ? 1 : void 0,
3226
+ removeDataOnSave: o.removeDataOnSave ? 1 : void 0,
3227
+ disableEdit: o.disableEdit ? 1 : void 0,
3228
+ intermediate: o.intermediate ? 1 : void 0
3229
+ };
3230
+ const children = [];
3231
+ if (o.queryTableRefresh) children.push(buildQueryTableRefresh(o.queryTableRefresh));
3232
+ if (children.length > 0) return `<queryTable xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"${attrs(a)}>${children.join("")}</queryTable>`;
3233
+ return `<queryTable xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"${attrs(a)}/>`;
3234
+ }
3235
+ };
3236
+ function buildQueryTableRefresh(opts) {
3237
+ const a = {};
3238
+ if (opts.nextId !== void 0) a.nextId = opts.nextId;
3239
+ if (opts.minimumVersion !== void 0) a.minimumVersion = opts.minimumVersion;
3240
+ if (opts.preserveFormatting) a.preserveFormatting = 1;
3241
+ if (opts.adjustColumnWidth !== void 0) a.adjustColumnWidth = opts.adjustColumnWidth ? 1 : 0;
3242
+ if (opts.refreshOnLoad) a.refreshOnLoad = 1;
3243
+ if (opts.backgroundRefresh) a.backgroundRefresh = 1;
3244
+ if (opts.rowCount !== void 0) a.rowCount = opts.rowCount;
3245
+ const children = [];
3246
+ if (opts.deletedFields && opts.deletedFields.length > 0) {
3247
+ const dfParts = opts.deletedFields.map((df) => `<deletedField name="${escapeXml(df.name)}"/>`);
3248
+ children.push(`<queryTableDeletedFields count="${opts.deletedFields.length}">${dfParts.join("")}</queryTableDeletedFields>`);
3249
+ }
3250
+ if (opts.queryTableFields && opts.queryTableFields.length > 0) {
3251
+ const fParts = [`<queryTableFields count="${opts.queryTableFields.length}">`];
3252
+ for (const f of opts.queryTableFields) {
3253
+ const fAttrs = { id: f.id };
3254
+ if (f.name !== void 0) fAttrs.name = f.name;
3255
+ if (f.tableColumnId !== void 0) fAttrs.tableColumnId = f.tableColumnId;
3256
+ if (f.row !== void 0) fAttrs.row = f.row;
3257
+ if (f.fillFormatting) fAttrs.fillFormatting = 1;
3258
+ if (f.textFormatting) fAttrs.textFormatting = 1;
3259
+ if (f.numberFormatting) fAttrs.numberFormatting = 1;
3260
+ if (f.borderFormatting) fAttrs.borderFormatting = 1;
3261
+ if (f.width !== void 0) fAttrs.width = f.width;
3262
+ if (f.clipped) fAttrs.clipped = 1;
3263
+ fParts.push(`<queryTableField${attrs(fAttrs)}/>`);
3264
+ }
3265
+ fParts.push("</queryTableFields>");
3266
+ children.push(fParts.join(""));
3267
+ }
3268
+ if (children.length > 0) return `<queryTableRefresh${attrs(a)}>${children.join("")}</queryTableRefresh>`;
3269
+ return `<queryTableRefresh${attrs(a)}/>`;
3270
+ }
3271
+ //#endregion
3272
+ //#region src/file/metadata/metadata-xml.ts
3273
+ /**
3274
+ * Metadata XML generator — produces xl/metadata.xml.
3275
+ *
3276
+ * Contains cell metadata and value metadata for rich data types.
3277
+ *
3278
+ * Reference: OOXML transitional, sml.xsd, CT_Metadata
3279
+ *
3280
+ * @module
3281
+ */
3282
+ var MetadataXml = class extends BaseXmlComponent {
3283
+ opts;
3284
+ constructor(options) {
3285
+ super("metadata");
3286
+ this.opts = options;
3287
+ }
3288
+ toXml(_context) {
3289
+ const p = ["<metadata xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">"];
3290
+ const types = this.opts.types ?? [];
3291
+ p.push(`<metadataTypes count="${types.length}">`);
3292
+ for (const t of types) p.push(`<metadataType${attrs({
3293
+ name: t.name,
3294
+ minVersion: t.minVersion,
3295
+ minSupportedVersion: t.minSupportedVersion,
3296
+ ghostRow: t.ghostRow ? 1 : void 0,
3297
+ ghostCol: t.ghostCol ? 1 : void 0,
3298
+ edit: t.edit ? 1 : void 0,
3299
+ delete: t.delete ? 1 : void 0,
3300
+ copy: t.copy ? 1 : void 0,
3301
+ paste: t.paste ? 1 : void 0,
3302
+ pasteAll: t.pasteAll ? 1 : void 0,
3303
+ pasteFormulas: t.pasteFormulas ? 1 : void 0,
3304
+ pasteValues: t.pasteValues ? 1 : void 0,
3305
+ pasteFormats: t.pasteFormats ? 1 : void 0,
3306
+ pasteComments: t.pasteComments ? 1 : void 0,
3307
+ pasteDataValidation: t.pasteDataValidation ? 1 : void 0,
3308
+ pasteBorders: t.pasteBorders ? 1 : void 0,
3309
+ pasteColWidths: t.pasteColWidths ? 1 : void 0,
3310
+ pasteNumberFormats: t.pasteNumberFormats ? 1 : void 0,
3311
+ merge: t.merge ? 1 : void 0,
3312
+ splitFirst: t.splitFirst ? 1 : void 0,
3313
+ splitAll: t.splitAll ? 1 : void 0,
3314
+ rowColShift: t.rowColShift ? 1 : void 0,
3315
+ clearAll: t.clearAll ? 1 : void 0,
3316
+ clearFormats: t.clearFormats ? 1 : void 0,
3317
+ clearContents: t.clearContents ? 1 : void 0,
3318
+ clearComments: t.clearComments ? 1 : void 0,
3319
+ assign: t.assign ? 1 : void 0,
3320
+ coerce: t.coerce ? 1 : void 0,
3321
+ adjust: t.adjust ? 1 : void 0,
3322
+ cellMeta: t.cellMeta ? 1 : void 0
3323
+ })}/>`);
3324
+ p.push("</metadataTypes>");
3325
+ const strings = this.opts.strings ?? [];
3326
+ if (strings.length > 0) {
3327
+ p.push(`<metadataStrings count="${strings.length}">`);
3328
+ for (const s of strings) p.push(`<s v="${s.value}"/>`);
3329
+ p.push("</metadataStrings>");
3330
+ }
3331
+ const future = this.opts.futureMetadata ?? [];
3332
+ if (future.length > 0) for (const f of future) {
3333
+ p.push(`<futureMetadata name="${f.name}" type="${f.type}"><bk/>`);
3334
+ p.push("</futureMetadata>");
3335
+ }
3336
+ const cmBlocks = this.opts.cellMetadataBlocks ?? [];
3337
+ if (cmBlocks.length > 0) {
3338
+ p.push(`<cellMetadata count="${cmBlocks.length}">`);
3339
+ for (const blk of cmBlocks) {
3340
+ const records = blk.records ?? [];
3341
+ if (records.length > 0) {
3342
+ const rcParts = records.map((r) => `<rc t="${r.t}" v="${r.v}"/>`);
3343
+ p.push(`<bk>${rcParts.join("")}</bk>`);
3344
+ } else p.push("<bk/>");
3345
+ }
3346
+ p.push("</cellMetadata>");
3347
+ } else p.push("<cellMetadata count=\"0\"/>");
3348
+ const vmBlocks = this.opts.valueMetadataBlocks ?? [];
3349
+ if (vmBlocks.length > 0) {
3350
+ p.push(`<valueMetadata count="${vmBlocks.length}">`);
3351
+ for (const blk of vmBlocks) {
3352
+ const records = blk.records ?? [];
3353
+ if (records.length > 0) {
3354
+ const rcParts = records.map((r) => `<rc t="${r.t}" v="${r.v}"/>`);
3355
+ p.push(`<bk>${rcParts.join("")}</bk>`);
3356
+ } else p.push("<bk/>");
3357
+ }
3358
+ p.push("</valueMetadata>");
3359
+ } else p.push("<valueMetadata count=\"0\"/>");
3360
+ const mdxMeta = this.opts.mdxMetadata;
3361
+ if (mdxMeta && mdxMeta.length > 0) {
3362
+ p.push(`<mdxMetadata count="${mdxMeta.length}">`);
3363
+ for (const m of mdxMeta) {
3364
+ const mAttrs = {
3365
+ n: m.n,
3366
+ f: m.f
3367
+ };
3368
+ let child = "";
3369
+ if (m.tuple) {
3370
+ const tAttrs = {};
3371
+ if (m.tuple.c !== void 0) tAttrs.c = m.tuple.c;
3372
+ child = `<t${attrs(tAttrs)}/>`;
3373
+ } else if (m.set) child = `<ms ns="${m.set.ns}"/>`;
3374
+ else if (m.memberProp) child = `<p n="${m.memberProp.n}" np="${m.memberProp.np}"/>`;
3375
+ else if (m.kpi) child = `<k n="${m.kpi.n}" np="${m.kpi.np}" p="${escapeXml(m.kpi.p)}"/>`;
3376
+ if (child) p.push(`<mdx${attrs(mAttrs)}>${child}</mdx>`);
3377
+ else p.push(`<mdx${attrs(mAttrs)}/>`);
3378
+ }
3379
+ p.push("</mdxMetadata>");
3380
+ }
3381
+ p.push("</metadata>");
3382
+ return p.join("");
3383
+ }
3384
+ };
3385
+ //#endregion
3386
+ //#region src/file/revision-log/revision-headers-xml.ts
3387
+ /**
3388
+ * Revision Headers XML generator — produces xl/revisionHeaders.xml.
3389
+ *
3390
+ * Reference: OOXML transitional, sml.xsd, CT_RevisionHeaders
3391
+ *
3392
+ * @module
3393
+ */
3394
+ var RevisionHeadersXml = class extends BaseXmlComponent {
3395
+ opts;
3396
+ users;
3397
+ constructor(options, users) {
3398
+ super("headers");
3399
+ this.opts = options;
3400
+ this.users = users;
3401
+ }
3402
+ toXml(_context) {
3403
+ const p = ["<headers xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\""];
3404
+ const rootAttrs = {
3405
+ guid: this.opts.guid,
3406
+ lastGuid: this.opts.lastGuid,
3407
+ shared: this.opts.shared,
3408
+ history: this.opts.history,
3409
+ trackRevisions: this.opts.trackRevisions,
3410
+ revisionId: this.opts.revisionId,
3411
+ version: this.opts.version,
3412
+ keepChangeHistory: this.opts.keepChangeHistory,
3413
+ protected: this.opts.protected,
3414
+ preserveHistory: this.opts.preserveHistory
3415
+ };
3416
+ p.push(`${attrs(rootAttrs)}>`);
3417
+ for (const h of this.opts.headers) {
3418
+ const headerAttrs = {
3419
+ guid: h.guid,
3420
+ dateTime: h.dateTime,
3421
+ maxSheetId: h.maxSheetId,
3422
+ userName: h.userName
3423
+ };
3424
+ const content = [];
3425
+ if (h.sheetIds && h.sheetIds.length > 0) {
3426
+ const idParts = [];
3427
+ for (const sid of h.sheetIds) idParts.push(`<sheetId val="${sid.id}"/>`);
3428
+ content.push(`<sheetIdMap${attrs({ count: h.sheetIds.length })}>${idParts.join("")}</sheetIdMap>`);
3429
+ }
3430
+ p.push(`<header${attrs(headerAttrs)} r:id="${escapeXml(h.rId)}">${content.join("")}</header>`);
3431
+ }
3432
+ p.push("</headers>");
3433
+ return p.join("");
3434
+ }
3435
+ /** Build users XML (CT_Users) — separate file xl/users.xml */
3436
+ buildUsersXml() {
3437
+ if (!this.users?.users || this.users.users.length === 0) return "";
3438
+ const u = this.users.users;
3439
+ const parts = ["<users xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"", ` count="${u.length}">`];
3440
+ for (const user of u) {
3441
+ const uAttrs = {
3442
+ guid: user.guid,
3443
+ name: user.name,
3444
+ id: user.id,
3445
+ dateTime: user.dateTime
3446
+ };
3447
+ parts.push(`<userInfo${attrs(uAttrs)}/>`);
3448
+ }
3449
+ parts.push("</users>");
3450
+ return parts.join("");
3451
+ }
3452
+ };
3453
+ //#endregion
3454
+ //#region src/file/revision-log/revision-xml.ts
3455
+ /**
3456
+ * Revision Log XML generator — produces xl/revisions/revisionN.xml.
3457
+ *
3458
+ * Reference: OOXML transitional, sml.xsd, CT_Revisions
3459
+ *
3460
+ * @module
3461
+ */
3462
+ function buildRowColumn(opts) {
3463
+ const a = {
3464
+ rId: opts.rId,
3465
+ action: {
3466
+ insertRow: "ir",
3467
+ insertCol: "ic",
3468
+ deleteRow: "dr",
3469
+ deleteCol: "dc"
3470
+ }[opts.action],
3471
+ sId: opts.sheetIndex,
3472
+ edge: opts.edge ? 1 : void 0
3473
+ };
3474
+ if (opts.action.includes("Row")) a.row = opts.row;
3475
+ else a.col = opts.col;
3476
+ return `<rrc${attrs(a)}/>`;
3477
+ }
3478
+ function buildCellChange(opts) {
3479
+ const a = {
3480
+ rId: opts.rId,
3481
+ sId: opts.sheetIndex,
3482
+ quotePrefix: opts.quotePrefix ? 1 : void 0,
3483
+ oldQuotePrefix: opts.oldQuotePrefix ? 1 : void 0,
3484
+ ph: opts.ph ? 1 : void 0,
3485
+ oldPh: opts.oldPh ? 1 : void 0
3486
+ };
3487
+ const children = [];
3488
+ if (opts.oldValue !== void 0) {
3489
+ const oldType = opts.oldType ?? (typeof opts.oldValue === "number" ? "n" : "s");
3490
+ if (opts.formula) children.push(`<f>${escapeXml(opts.formula)}</f>`);
3491
+ children.push(`<oc${attrs({
3492
+ t: oldType,
3493
+ vm: opts.numFmtId
3494
+ })}><v>${escapeXml(String(opts.oldValue))}</v></oc>`);
3495
+ }
3496
+ if (opts.newValue !== void 0) {
3497
+ const newType = opts.newType ?? (typeof opts.newValue === "number" ? "n" : "s");
3498
+ children.push(`<nc${attrs({ t: newType })}><v>${escapeXml(String(opts.newValue))}</v></nc>`);
3499
+ }
3500
+ if (opts.xfDxf !== void 0) {
3501
+ children.push(`<ndxf><font/><numFmt/><fill/><border/><protection/></ndxf>`);
3502
+ children.push(`<odxf><font/><numFmt/><fill/><border/><protection/></odxf>`);
3503
+ }
3504
+ return `<rcc${attrs({
3505
+ ref: opts.ref,
3506
+ ...a
3507
+ })}>${children.join("")}</rcc>`;
3508
+ }
3509
+ function buildMove(opts) {
3510
+ return `<rm${attrs({
3511
+ rId: opts.rId,
3512
+ sId: opts.sheetIndex,
3513
+ source: opts.source,
3514
+ destination: opts.destination,
3515
+ sourceSheetId: opts.sourceSheetId
3516
+ })}/>`;
3517
+ }
3518
+ function buildFormatting(opts) {
3519
+ return `<rfmt${attrs({
3520
+ rId: opts.rId,
3521
+ sId: opts.sheetIndex,
3522
+ ref: opts.ref,
3523
+ s: opts.s,
3524
+ xfDxf: opts.xfDxf
3525
+ })}/>`;
3526
+ }
3527
+ function buildInsertSheet(opts) {
3528
+ return `<ris${attrs({
3529
+ rId: opts.rId,
3530
+ sId: opts.sheetIndex,
3531
+ name: opts.name,
3532
+ sheetPosition: opts.sheetPosition
3533
+ })}/>`;
3534
+ }
3535
+ function buildComment(opts) {
3536
+ const a = {
3537
+ rId: opts.rId,
3538
+ sId: opts.sheetIndex,
3539
+ ref: opts.ref,
3540
+ alwaysShow: opts.alwaysShow ? 1 : void 0,
3541
+ old: opts.old ? 1 : void 0,
3542
+ hiddenRow: opts.hiddenRow ? 1 : void 0,
3543
+ hiddenColumn: opts.hiddenColumn ? 1 : void 0,
3544
+ oldLength: opts.oldLength,
3545
+ newLength: opts.newLength
3546
+ };
3547
+ const children = [];
3548
+ if (opts.text) children.push(`<t>${escapeXml(opts.text)}</t>`);
3549
+ if (opts.author) children.push(`<author>${escapeXml(opts.author)}</author>`);
3550
+ if (children.length > 0) return `<rcmt${attrs(a)}>${children.join("")}</rcmt>`;
3551
+ return `<rcmt${attrs(a)}/>`;
3552
+ }
3553
+ function buildDefinedName(opts) {
3554
+ const a = {
3555
+ rId: opts.rId,
3556
+ name: opts.name,
3557
+ localSheetId: opts.localSheetId,
3558
+ customView: opts.customView ? 1 : void 0,
3559
+ function: opts["function"] ? 1 : void 0,
3560
+ oldFunction: opts.oldFunction ? 1 : void 0,
3561
+ functionGroupId: opts.functionGroupId,
3562
+ oldFunctionGroupId: opts.oldFunctionGroupId,
3563
+ shortcutKey: opts.shortcutKey,
3564
+ oldShortcutKey: opts.oldShortcutKey,
3565
+ oldHidden: opts.oldHidden ? 1 : void 0,
3566
+ customMenu: opts.customMenu,
3567
+ oldCustomMenu: opts.oldCustomMenu,
3568
+ oldDescription: opts.oldDescription,
3569
+ help: opts.help,
3570
+ oldHelp: opts.oldHelp,
3571
+ statusBar: opts.statusBar,
3572
+ oldStatusBar: opts.oldStatusBar
3573
+ };
3574
+ const children = [];
3575
+ if (opts.value) children.push(`<formula>${escapeXml(opts.value)}</formula>`);
3576
+ if (opts.oldComment) children.push(`<oldFormula>${escapeXml(opts.oldComment)}</oldFormula>`);
3577
+ return `<rdn${attrs(a)}>${children.join("")}</rdn>`;
3578
+ }
3579
+ function buildAutoFormatting(opts) {
3580
+ return `<raf${attrs({
3581
+ rId: opts.rId,
3582
+ sId: opts.sheetIndex,
3583
+ ref: opts.ref
3584
+ })}/>`;
3585
+ }
3586
+ function buildCustomView(opts) {
3587
+ return `<rcv${attrs({
3588
+ rId: opts.rId,
3589
+ guid: opts.guid
3590
+ })}/>`;
3591
+ }
3592
+ function buildSheetRename(opts) {
3593
+ return `<rsnm${attrs({
3594
+ rId: opts.rId,
3595
+ sId: opts.sheetIndex,
3596
+ oldName: opts.oldName,
3597
+ newName: opts.newName
3598
+ })}/>`;
3599
+ }
3600
+ function buildQueryTableField(opts) {
3601
+ return `<rqt${attrs({
3602
+ rId: opts.rId,
3603
+ sId: opts.sheetIndex,
3604
+ fieldId: opts.fieldId
3605
+ })}/>`;
3606
+ }
3607
+ function buildConflict(opts) {
3608
+ return `<rcft${attrs({
3609
+ rId: opts.rId,
3610
+ sId: opts.sheetIndex
3611
+ })}/>`;
3612
+ }
3613
+ var RevisionLogXml = class extends BaseXmlComponent {
3614
+ entries;
3615
+ constructor(entries) {
3616
+ super("revisions");
3617
+ this.entries = entries;
3618
+ }
3619
+ toXml(_context) {
3620
+ const p = ["<revisions xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">"];
3621
+ const localReviewedList = [];
3622
+ for (const entry of this.entries) switch (entry.type) {
3623
+ case "rowColumn":
3624
+ p.push(buildRowColumn(entry.data));
3625
+ break;
3626
+ case "cellChange":
3627
+ p.push(buildCellChange(entry.data));
3628
+ break;
3629
+ case "move":
3630
+ p.push(buildMove(entry.data));
3631
+ break;
3632
+ case "formatting":
3633
+ p.push(buildFormatting(entry.data));
3634
+ break;
3635
+ case "insertSheet":
3636
+ p.push(buildInsertSheet(entry.data));
3637
+ break;
3638
+ case "comment":
3639
+ p.push(buildComment(entry.data));
3640
+ break;
3641
+ case "definedName":
3642
+ p.push(buildDefinedName(entry.data));
3643
+ break;
3644
+ case "reviewed":
3645
+ localReviewedList.push(`<reviewed rId="${entry.data.rId}"/>`);
3646
+ p.push(`<reviewed rId="${entry.data.rId}"/>`);
3647
+ break;
3648
+ case "undo":
3649
+ p.push(`<undo rId="${entry.data.rId}"/>`);
3650
+ break;
3651
+ case "autoFormatting":
3652
+ p.push(buildAutoFormatting(entry.data));
3653
+ break;
3654
+ case "customView":
3655
+ p.push(buildCustomView(entry.data));
3656
+ break;
3657
+ case "sheetRename":
3658
+ p.push(buildSheetRename(entry.data));
3659
+ break;
3660
+ case "queryTableField":
3661
+ p.push(buildQueryTableField(entry.data));
3662
+ break;
3663
+ case "conflict":
3664
+ p.push(buildConflict(entry.data));
3665
+ break;
3666
+ }
3667
+ if (localReviewedList.length > 0) p.push(`<reviewedList>${localReviewedList.join("")}</reviewedList>`);
3668
+ p.push("</revisions>");
3669
+ return p.join("");
3670
+ }
3671
+ };
3672
+ //#endregion
3673
+ //#region src/file/connection/connection-xml.ts
3674
+ /**
3675
+ * Connection XML generator — produces xl/connections.xml.
3676
+ *
3677
+ * Reference: OOXML transitional, sml.xsd, CT_Connections
3678
+ *
3679
+ * @module
3680
+ */
3681
+ var ConnectionsXml = class extends BaseXmlComponent {
3682
+ connections;
3683
+ constructor(connections) {
3684
+ super("connections");
3685
+ this.connections = connections;
3686
+ }
3687
+ toXml(_context) {
3688
+ const p = ["<connections xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">"];
3689
+ for (const c of this.connections) {
3690
+ const cAttrs = { id: c.id };
3691
+ if (c.name !== void 0) cAttrs.name = c.name;
3692
+ if (c.type !== void 0) cAttrs.type = c.type;
3693
+ if (c.refreshOnLoad) cAttrs.refreshOnLoad = 1;
3694
+ if (c.refreshedVersion !== void 0) cAttrs.refreshedVersion = c.refreshedVersion;
3695
+ else cAttrs.refreshedVersion = 6;
3696
+ if (c.backgroundRefresh) cAttrs.backgroundRefresh = 1;
3697
+ if (c.saveData === false) cAttrs.saveData = 0;
3698
+ if (c.savePassword) cAttrs.savePassword = 1;
3699
+ if (c.description !== void 0) cAttrs.description = c.description;
3700
+ if (c.credentials !== void 0) cAttrs.credentials = c.credentials;
3701
+ const children = [];
3702
+ if (c.dbPr) {
3703
+ const dbAttrs = { connection: c.dbPr.connection };
3704
+ if (c.dbPr.command !== void 0) dbAttrs.command = c.dbPr.command;
3705
+ if (c.dbPr.commandType !== void 0) dbAttrs.commandType = c.dbPr.commandType;
3706
+ if (c.dbPr.serverCommand !== void 0) dbAttrs.serverCommand = c.dbPr.serverCommand;
3707
+ children.push(`<dbPr${attrs(dbAttrs)}/>`);
3708
+ }
3709
+ if (c.webPr) {
3710
+ const wpAttrs = { url: c.webPr.url };
3711
+ if (c.webPr.sourceData) wpAttrs.sourceData = 1;
3712
+ if (c.webPr.htmlFormat !== void 0) wpAttrs.htmlFormat = c.webPr.htmlFormat;
3713
+ if (c.webPr.consecutive) wpAttrs.consecutive = 1;
3714
+ if (c.webPr.firstRowHeader) wpAttrs.firstRowHeader = 1;
3715
+ if (c.webPr.parsePre) wpAttrs.parsePre = 1;
3716
+ if (c.webPr.xl2000) wpAttrs.xl2000 = 1;
3717
+ const wpChildren = [];
3718
+ if (c.webPr.htmlTables && c.webPr.htmlTables.length > 0) wpChildren.push(`<tables>${c.webPr.htmlTables.map((t) => `<x v="${escapeXml(t)}"/>`).join("")}</tables>`);
3719
+ if (c.webPr.textFields && c.webPr.textFields.length > 0) wpChildren.push(buildTextFields(c.webPr.textFields));
3720
+ if (wpChildren.length > 0) children.push(`<webPr${attrs(wpAttrs)}>${wpChildren.join("")}</webPr>`);
3721
+ else children.push(`<webPr${attrs(wpAttrs)}/>`);
3722
+ }
3723
+ if (c.textPr) {
3724
+ const tpAttrs = {};
3725
+ if (c.textPr.codePage !== void 0) tpAttrs.codePage = c.textPr.codePage;
3726
+ if (c.textPr.characterSet !== void 0) tpAttrs.characterSet = c.textPr.characterSet;
3727
+ if (c.textPr.sourceFile !== void 0) tpAttrs.sourceFile = c.textPr.sourceFile;
3728
+ if (c.textPr.delimited !== void 0) tpAttrs.delimited = c.textPr.delimited ? 1 : 0;
3729
+ if (c.textPr.tab !== void 0) tpAttrs.tab = c.textPr.tab ? 1 : 0;
3730
+ if (c.textPr.space !== void 0) tpAttrs.space = c.textPr.space ? 1 : 0;
3731
+ if (c.textPr.comma !== void 0) tpAttrs.comma = c.textPr.comma ? 1 : 0;
3732
+ if (c.textPr.semicolon !== void 0) tpAttrs.semicolon = c.textPr.semicolon ? 1 : 0;
3733
+ if (c.textPr.custom !== void 0) tpAttrs.custom = c.textPr.custom;
3734
+ if (c.textPr.decimal !== void 0) tpAttrs.decimal = c.textPr.decimal;
3735
+ if (c.textPr.thousands !== void 0) tpAttrs.thousands = c.textPr.thousands;
3736
+ if (c.textPr.trailingMinus !== void 0) tpAttrs.trailingMinus = c.textPr.trailingMinus ? 1 : 0;
3737
+ const tpChildren = [];
3738
+ if (c.textPr.textFields && c.textPr.textFields.length > 0) tpChildren.push(buildTextFields(c.textPr.textFields));
3739
+ if (tpChildren.length > 0) children.push(`<textPr${attrs(tpAttrs)}>${tpChildren.join("")}</textPr>`);
3740
+ else children.push(`<textPr${attrs(tpAttrs)}/>`);
3741
+ }
3742
+ if (c.parameters && c.parameters.length > 0) {
3743
+ const paramParts = [`<parameters count="${c.parameters.length}">`];
3744
+ for (const param of c.parameters) {
3745
+ const paramAttrs = { name: param.name };
3746
+ if (param.sqlType !== void 0) paramAttrs.sqlType = param.sqlType;
3747
+ if (param.characterSet !== void 0) paramAttrs.characterSet = param.characterSet;
3748
+ if (param.stringValue !== void 0) paramAttrs.stringValue = param.stringValue;
3749
+ if (param.integerValue !== void 0) paramAttrs.integerValue = param.integerValue;
3750
+ if (param.booleanValue !== void 0) paramAttrs.booleanValue = param.booleanValue ? 1 : 0;
3751
+ if (param.refreshOnChange) paramAttrs.refreshOnChange = 1;
3752
+ if (param.prompt) paramAttrs.prompt = 1;
3753
+ if (param.reference !== void 0) paramAttrs.reference = param.reference;
3754
+ if (param.parameterType !== void 0) paramAttrs.parameterType = param.parameterType;
3755
+ paramParts.push(`<parameter${attrs(paramAttrs)}/>`);
3756
+ }
3757
+ paramParts.push("</parameters>");
3758
+ children.push(paramParts.join(""));
3759
+ }
3760
+ if (children.length > 0) p.push(`<connection${attrs(cAttrs)}>${children.join("")}</connection>`);
3761
+ else p.push(`<connection${attrs(cAttrs)}/>`);
3762
+ }
3763
+ p.push("</connections>");
3764
+ return p.join("");
3765
+ }
3766
+ };
3767
+ function buildTextFields(fields) {
3768
+ const parts = [`<textFields count="${fields.length}">`];
3769
+ for (const f of fields) {
3770
+ const fAttrs = { type: f.type };
3771
+ if (f.dataType !== void 0) fAttrs.dataType = f.dataType;
3772
+ parts.push(`<textField${attrs(fAttrs)}/>`);
3773
+ }
3774
+ parts.push("</textFields>");
3775
+ return parts.join("");
3776
+ }
3777
+ //#endregion
3778
+ //#region src/file/xml-mapping/xml-mapping-xml.ts
3779
+ /**
3780
+ * XML Mapping elements — produces XML spreadsheet mapping elements.
3781
+ *
3782
+ * Reference: OOXML transitional, sml.xsd
3783
+ * CT_MapInfo, CT_Schema, CT_Map, CT_DataBinding,
3784
+ * CT_SingleXmlCells, CT_SingleXmlCell, CT_XmlCellPr, CT_XmlColumnPr, CT_XmlPr
3785
+ *
3786
+ * @module
3787
+ */
3788
+ function schemaToXml(s) {
3789
+ const a = { ID: s.id };
3790
+ if (s.schemaRef !== void 0) a.SchemaRef = s.schemaRef;
3791
+ if (s.namespace !== void 0) a.Namespace = s.namespace;
3792
+ if (s.schemaLanguage !== void 0) a.SchemaLanguage = s.schemaLanguage;
3793
+ if (s.schemaID !== void 0) a.SchemaID = s.schemaID;
3794
+ if (s.elementFormDefault !== void 0) a.ElementFormDefault = s.elementFormDefault;
3795
+ if (s.attributeFormDefault !== void 0) a.AttributeFormDefault = s.attributeFormDefault;
3796
+ return `<Schema${attrs(a)}/>`;
3797
+ }
3798
+ function dataBindingToXml(db) {
3799
+ const a = {};
3800
+ if (db.dataBindingName !== void 0) a.DataBindingName = db.dataBindingName;
3801
+ if (db.fileBinding !== void 0) a.FileBinding = db.fileBinding ? 1 : 0;
3802
+ if (db.fileBindingName !== void 0) a.FileBindingName = db.fileBindingName;
3803
+ if (db.connectionID !== void 0) a.ConnectionID = db.connectionID;
3804
+ if (db.dataBindingLoadMode !== void 0) a.DataBindingLoadMode = db.dataBindingLoadMode;
3805
+ return `<DataBinding${attrs(a)}/>`;
3806
+ }
3807
+ function mapToXml(m) {
3808
+ const a = {
3809
+ ID: m.id,
3810
+ Name: m.name,
3811
+ RootElement: m.rootElement,
3812
+ SchemaID: m.schemaID
3813
+ };
3814
+ if (m.showImportExportValidationErrors !== void 0) a.ShowImportExportValidationErrors = m.showImportExportValidationErrors ? 1 : 0;
3815
+ if (m.append !== void 0) a.Append = m.append ? 1 : 0;
3816
+ if (m.dataBindingLoadMode !== void 0) a.DataBindingLoadMode = m.dataBindingLoadMode;
3817
+ if (m.autoFit !== void 0) a.AutoFit = m.autoFit ? 1 : 0;
3818
+ if (m.fileBinding !== void 0) a.FileBinding = m.fileBinding ? 1 : 0;
3819
+ if (m.fileBindingName !== void 0) a.FileBindingName = m.fileBindingName;
3820
+ if (m.preserveFormat !== void 0) a.PreserveFormat = m.preserveFormat ? 1 : 0;
3821
+ if (m.preserveSortAFLayout !== void 0) a.PreserveSortAFLayout = m.preserveSortAFLayout ? 1 : 0;
3822
+ const children = [];
3823
+ if (m.dataBinding) children.push(dataBindingToXml(m.dataBinding));
3824
+ if (children.length > 0) return `<Map${attrs(a)}>${children.join("")}</Map>`;
3825
+ return `<Map${attrs(a)}/>`;
3826
+ }
3827
+ function xmlPrToXml(xp) {
3828
+ const a = {
3829
+ mapId: xp.mapId,
3830
+ xpath: xp.xpath,
3831
+ xmlDataType: xp.xmlDataType
3832
+ };
3833
+ if (xp.xmlElement !== void 0) a.xmlElement = xp.xmlElement;
3834
+ return `<xmlPr${attrs(a)}/>`;
3835
+ }
3836
+ function xmlCellPrToXml(xcp) {
3837
+ const a = { id: xcp.id };
3838
+ if (xcp.uniqueName !== void 0) a.uniqueName = xcp.uniqueName;
3839
+ return `<xmlCellPr${attrs(a)}>${xmlPrToXml(xcp.xmlPr)}</xmlCellPr>`;
3840
+ }
3841
+ function singleXmlCellToXml(sxc) {
3842
+ return `<singleXmlCell${attrs({
3843
+ id: sxc.id,
3844
+ r: sxc.r,
3845
+ connectionId: sxc.connectionId
3846
+ })}>${xmlCellPrToXml(sxc.xmlCellPr)}</singleXmlCell>`;
3847
+ }
3848
+ var MapInfoXml = class extends BaseXmlComponent {
3849
+ options;
3850
+ constructor(options) {
3851
+ super("MapInfo");
3852
+ this.options = options;
3853
+ }
3854
+ toXml(_context) {
3855
+ const p = ["<MapInfo xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\""];
3856
+ p.push(` SelectionNamespaces="${this.options.selectionNamespaces}">`);
3857
+ for (const s of this.options.schemas) p.push(schemaToXml(s));
3858
+ for (const m of this.options.maps) p.push(mapToXml(m));
3859
+ p.push("</MapInfo>");
3860
+ return p.join("");
3861
+ }
3862
+ };
3863
+ var SingleXmlCellsXml = class extends BaseXmlComponent {
3864
+ cells;
3865
+ constructor(cells) {
3866
+ super("singleXmlCells");
3867
+ this.cells = cells;
3868
+ }
3869
+ toXml(_context) {
3870
+ const p = ["<singleXmlCells xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">"];
3871
+ for (const cell of this.cells) p.push(singleXmlCellToXml(cell));
3872
+ p.push("</singleXmlCells>");
3873
+ return p.join("");
3874
+ }
3875
+ };
3876
+ var XmlColumnPrXml = class extends BaseXmlComponent {
3877
+ options;
3878
+ constructor(options) {
3879
+ super("xmlColumnPr");
3880
+ this.options = options;
3881
+ }
3882
+ toXml(_context) {
3883
+ return `<xmlColumnPr${attrs({
3884
+ xpath: this.options.xpath,
3885
+ xmlDataType: this.options.xmlDataType,
3886
+ mapId: this.options.mapId
3887
+ })}/>`;
3888
+ }
3889
+ };
3890
+ //#endregion
3891
+ //#region src/file/calc-chain.ts
3892
+ /**
3893
+ * Calculation Chain — generates xl/calcChain.xml.
3894
+ *
3895
+ * The calculation chain lists formula cells in calculation order,
3896
+ * enabling faster recalculation in spreadsheet applications.
3897
+ *
3898
+ * Reference: OOXML transitional, sml.xsd, CT_CalcChain / CT_CalcCell
3899
+ *
3900
+ * @module
3901
+ */
3902
+ var CalcChain = class extends BaseXmlComponent {
3903
+ cells = [];
3904
+ constructor() {
3905
+ super("calcChain");
3906
+ }
3907
+ addCell(cell) {
3908
+ this.cells.push(cell);
3909
+ }
3910
+ get count() {
3911
+ return this.cells.length;
3912
+ }
3913
+ toXml(_context) {
3914
+ const parts = ["<calcChain xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">"];
3915
+ for (const cell of this.cells) {
3916
+ const cellAttrs = {
3917
+ r: cell.reference,
3918
+ i: cell.sheetIndex
3919
+ };
3920
+ if (cell.array) cellAttrs.a = true;
3921
+ parts.push(`<c${attrs(cellAttrs)}/>`);
3922
+ }
3923
+ parts.push("</calcChain>");
3924
+ return parts.join("");
3925
+ }
3926
+ };
3927
+ //#endregion
3928
+ //#region src/file/chartsheet/chartsheet.ts
3929
+ /**
3930
+ * Chartsheet XML generator — produces xl/chartsheets/sheetN.xml.
3931
+ *
3932
+ * A chartsheet is a worksheet that contains only a chart (no cells).
3933
+ *
3934
+ * Reference: OOXML transitional, sml.xsd, CT_Chartsheet
3935
+ *
3936
+ * @module
3937
+ */
3938
+ var Chartsheet = class extends BaseXmlComponent {
3939
+ opts;
3940
+ drawingRId = "rId1";
3941
+ constructor(options) {
3942
+ super("chartsheet");
3943
+ this.opts = options;
3944
+ }
3945
+ setDrawingRId(rId) {
3946
+ this.drawingRId = rId;
3947
+ }
3948
+ toXml(_context) {
3949
+ const p = ["<chartsheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">"];
3950
+ if (this.opts.tabColor || this.opts.published) {
3951
+ const prAttrs = [];
3952
+ if (this.opts.tabColor) prAttrs.push(`<tabColor${attrs({ rgb: this.opts.tabColor })}/>`);
3953
+ const spAttr = this.opts.published ? " published=\"1\"" : "";
3954
+ p.push(`<sheetPr${spAttr}>${prAttrs.join("")}</sheetPr>`);
3955
+ }
3956
+ const svAttrs = ["workbookViewId=\"0\""];
3957
+ if (this.opts.zoomToFit) svAttrs.push("zoomToFit=\"1\"");
3958
+ p.push(`<sheetViews><sheetView ${svAttrs.join(" ")}/></sheetViews>`);
3959
+ if (this.opts.sheetProtection) {
3960
+ const sp = this.opts.sheetProtection;
3961
+ const spAttrs = [];
3962
+ if (sp.content) spAttrs.push(` content="1"`);
3963
+ if (sp.objects) spAttrs.push(` objects="1"`);
3964
+ if (spAttrs.length > 0) p.push(`<sheetProtection${spAttrs.join("")}/>`);
3965
+ }
3966
+ if (this.opts.pageMargins) {
3967
+ const pm = this.opts.pageMargins;
3968
+ p.push(`<pageMargins${attrs({
3969
+ left: pm.left ?? .7,
3970
+ right: pm.right ?? .7,
3971
+ top: pm.top ?? .75,
3972
+ bottom: pm.bottom ?? .75,
3973
+ header: pm.header ?? .3,
3974
+ footer: pm.footer ?? .3
3975
+ })}/>`);
3976
+ }
3977
+ if (this.opts.pageSetup) {
3978
+ const ps = this.opts.pageSetup;
3979
+ p.push(`<pageSetup${attrs({
3980
+ paperSize: ps.paperSize,
3981
+ orientation: ps.orientation,
3982
+ horizontalDpi: ps.horizontalDpi,
3983
+ verticalDpi: ps.verticalDpi,
3984
+ copies: ps.copies
3985
+ })}/>`);
3986
+ }
3987
+ if (this.opts.headerFooter) {
3988
+ const hf = this.opts.headerFooter;
3989
+ const hfParts = [];
3990
+ if (hf.differentFirst) hfParts.push(` differentFirst="1"`);
3991
+ if (hf.differentOddEven) hfParts.push(` differentOddEven="1"`);
3992
+ const hfContent = [];
3993
+ if (hf.oddHeader) hfContent.push(`<oddHeader>${escapeXml(hf.oddHeader)}</oddHeader>`);
3994
+ if (hf.oddFooter) hfContent.push(`<oddFooter>${escapeXml(hf.oddFooter)}</oddFooter>`);
3995
+ p.push(`<headerFooter${hfParts.join("")}>${hfContent.join("")}</headerFooter>`);
3996
+ }
3997
+ p.push(`<drawing r:id="${escapeXml(this.drawingRId)}"/>`);
3998
+ p.push("</chartsheet>");
3999
+ return p.join("");
4000
+ }
4001
+ };
4002
+ //#endregion
4003
+ //#region src/file/comments.ts
4004
+ /**
4005
+ * Generates xl/comments{n}.xml — cell comment data.
4006
+ *
4007
+ * @module
4008
+ */
4009
+ var Comments = class extends BaseXmlComponent {
4010
+ entries;
4011
+ constructor(entries) {
4012
+ super("comments");
4013
+ this.entries = entries;
4014
+ }
4015
+ toXml(_context) {
4016
+ const authors = this.collectAuthors();
4017
+ const p = ["<comments xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">", `<authors>`];
4018
+ for (const author of authors) p.push(`<author>${escapeXml(author)}</author>`);
4019
+ p.push("</authors><commentList>");
4020
+ for (const entry of this.entries) {
4021
+ const authorId = authors.indexOf(entry.author);
4022
+ const textXml = typeof entry.text === "string" ? `<t>${escapeXml(entry.text)}</t>` : buildRstXml(entry.text);
4023
+ let commentPrXml = "";
4024
+ if (entry.commentPr) {
4025
+ const cp = entry.commentPr;
4026
+ const cpAttrs = [];
4027
+ if (cp.locked === false) cpAttrs.push("locked=\"0\"");
4028
+ if (cp.defaultSize === false) cpAttrs.push("defaultSize=\"0\"");
4029
+ if (cp.print === false) cpAttrs.push("print=\"0\"");
4030
+ if (cp.disabled) cpAttrs.push("disabled=\"1\"");
4031
+ if (cp.autoFill === false) cpAttrs.push("autoFill=\"0\"");
4032
+ if (cp.autoLine === false) cpAttrs.push("autoLine=\"0\"");
4033
+ if (cp.altText) cpAttrs.push(`altText="${escapeXml(cp.altText)}"`);
4034
+ if (cp.textHAlign && cp.textHAlign !== "left") cpAttrs.push(`textHAlign="${cp.textHAlign}"`);
4035
+ if (cp.textVAlign && cp.textVAlign !== "top") cpAttrs.push(`textVAlign="${cp.textVAlign}"`);
4036
+ if (cp.lockText === false) cpAttrs.push("lockText=\"0\"");
4037
+ if (cp.justLastX) cpAttrs.push("justLastX=\"1\"");
4038
+ if (cp.autoScale) cpAttrs.push("autoScale=\"1\"");
4039
+ const anchorAttrs = [];
4040
+ if (cp.anchor?.moveWithCells) anchorAttrs.push("moveWithCells=\"1\"");
4041
+ if (cp.anchor?.sizeWithCells) anchorAttrs.push("sizeWithCells=\"1\"");
4042
+ commentPrXml = `<commentPr${cpAttrs.length ? " " + cpAttrs.join(" ") : ""}><anchor${anchorAttrs.length ? " " + anchorAttrs.join(" ") : ""}/></commentPr>`;
4043
+ }
4044
+ p.push(`<comment ref="${entry.cell}" authorId="${authorId}"><text>${textXml}</text>${commentPrXml}</comment>`);
4045
+ }
4046
+ p.push("</commentList></comments>");
4047
+ return p.join("");
4048
+ }
4049
+ collectAuthors() {
4050
+ const seen = /* @__PURE__ */ new Set();
4051
+ const result = [];
4052
+ for (const entry of this.entries) if (!seen.has(entry.author)) {
4053
+ seen.add(entry.author);
4054
+ result.push(entry.author);
4055
+ }
4056
+ return result.length > 0 ? result : [""];
4057
+ }
4058
+ };
4059
+ //#endregion
4060
+ //#region src/file/drawing/drawing.ts
4061
+ /**
4062
+ * XLSX Drawing component — generates xl/drawings/drawing{n}.xml.
4063
+ *
4064
+ * Uses the spreadsheetDrawing namespace (default, no prefix) for anchoring
4065
+ * images and charts to worksheet cells.
4066
+ *
4067
+ * @module
4068
+ */
4069
+ const XDR_NS = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing";
4070
+ const A_NS = "http://schemas.openxmlformats.org/drawingml/2006/main";
4071
+ const R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
4072
+ const C_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
4073
+ var Drawing = class extends BaseXmlComponent {
4074
+ images;
4075
+ charts;
4076
+ constructor(images, charts = []) {
4077
+ super("wsDr");
4078
+ this.images = images;
4079
+ this.charts = charts;
4080
+ }
4081
+ toXml(_context) {
4082
+ const p = [`<wsDr xmlns="${XDR_NS}" xmlns:a="${A_NS}" xmlns:r="${R_NS}">`];
4083
+ let id = 1;
4084
+ for (const img of this.images) {
4085
+ p.push(`<twoCellAnchor editAs="oneCell"><from><col>${img.col - 1}</col><colOff>${img.colOffset ?? 0}</colOff><row>${img.row - 1}</row><rowOff>${img.rowOffset ?? 0}</rowOff></from>`, `<to><col>${img.col}</col><colOff>0</colOff><row>${img.row}</row><rowOff>0</rowOff></to>`, `<pic><nvPicPr><cNvPr id="${id}" name="Picture ${id}"/><cNvPicPr preferRelativeResize="1"/></nvPicPr>`, `<blipFill><a:blip r:embed="${img.rId}"/><a:stretch><a:fillRect/></a:stretch></blipFill>`, `<spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="400000" cy="300000"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></spPr></pic>`, `<clientData fLocksWithSheet="${img.locksWithSheet !== false ? 1 : 0}" fPrintsWithSheet="${img.printsWithSheet !== false ? 1 : 0}"/></twoCellAnchor>`);
4086
+ id++;
4087
+ }
4088
+ for (const chart of this.charts) {
4089
+ p.push(`<twoCellAnchor editAs="oneCell"><from><col>${chart.col - 1}</col><colOff>${chart.colOffset ?? 0}</colOff><row>${chart.row - 1}</row><rowOff>${chart.rowOffset ?? 0}</rowOff></from>`, `<to><col>${chart.col + 8}</col><colOff>0</colOff><row>${chart.row + 15}</row><rowOff>0</rowOff></to>`, `<graphicFrame><nvGraphicFramePr><cNvPr id="${id}" name="Chart ${id}"/><cNvGraphicFramePr><a:graphicFrameLocks noGrp="1"/></cNvGraphicFramePr></nvGraphicFramePr>`, `<xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/></xfrm>`, `<a:graphic><a:graphicData uri="${C_URI}"><c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:r="${R_NS}" r:id="${chart.rId}"/></a:graphicData></a:graphic></graphicFrame>`, `<clientData fLocksWithSheet="${chart.locksWithSheet !== false ? 1 : 0}" fPrintsWithSheet="${chart.printsWithSheet !== false ? 1 : 0}"/></twoCellAnchor>`);
4090
+ id++;
4091
+ }
4092
+ p.push("</wsDr>");
4093
+ return p.join("");
4094
+ }
4095
+ };
4096
+ //#endregion
4097
+ //#region src/file/external-link/external-link-xml.ts
4098
+ /**
4099
+ * External Link XML generator — produces xl/externalLinks/externalLinkN.xml.
4100
+ *
4101
+ * Reference: OOXML transitional, sml.xsd, CT_ExternalLink
4102
+ *
4103
+ * @module
4104
+ */
4105
+ var ExternalLinkXml = class extends BaseXmlComponent {
4106
+ opts;
4107
+ constructor(options) {
4108
+ super("externalLink");
4109
+ this.opts = options;
4110
+ }
4111
+ toXml(_context) {
4112
+ const p = ["<externalLink xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">"];
4113
+ if (this.opts.externalBook) {
4114
+ const book = this.opts.externalBook;
4115
+ const bookParts = [];
4116
+ if (book.sheetNames && book.sheetNames.length > 0) {
4117
+ bookParts.push("<sheetNames>");
4118
+ for (const name of book.sheetNames) bookParts.push(`<sheetName val="${escapeXml(name)}"/>`);
4119
+ bookParts.push("</sheetNames>");
4120
+ }
4121
+ if (book.definedNames && book.definedNames.length > 0) {
4122
+ bookParts.push("<definedNames>");
4123
+ for (const dn of book.definedNames) {
4124
+ const dnAttrs = { name: dn.name };
4125
+ if (dn.refersTo !== void 0) dnAttrs.refersTo = dn.refersTo;
4126
+ if (dn.sheetId !== void 0) dnAttrs.sheetId = dn.sheetId;
4127
+ bookParts.push(`<definedName${attrs(dnAttrs)}/>`);
4128
+ }
4129
+ bookParts.push("</definedNames>");
4130
+ }
4131
+ if (book.sheetDataSet && book.sheetDataSet.length > 0) {
4132
+ bookParts.push("<sheetDataSet>");
4133
+ for (const sd of book.sheetDataSet) {
4134
+ const sdAttrs = { sheetId: sd.sheetId };
4135
+ if (sd.refreshError) sdAttrs.refreshError = 1;
4136
+ bookParts.push(`<sheetData${attrs(sdAttrs)}>`);
4137
+ if (sd.rows) for (const row of sd.rows) {
4138
+ bookParts.push(`<row r="${row.rowNumber}">`);
4139
+ if (row.cells) for (const cell of row.cells) {
4140
+ const cellAttrs = { r: cell.reference };
4141
+ if (cell.type !== void 0) cellAttrs.t = cell.type;
4142
+ if (cell.value !== void 0) bookParts.push(`<cell${attrs(cellAttrs)}><v>${escapeXml(cell.value)}</v></cell>`);
4143
+ else bookParts.push(`<cell${attrs(cellAttrs)}/>`);
4144
+ }
4145
+ bookParts.push("</row>");
4146
+ }
4147
+ bookParts.push("</sheetData>");
4148
+ }
4149
+ bookParts.push("</sheetDataSet>");
4150
+ }
4151
+ const ridAttr = this.opts.bookRId ? ` r:id="${this.opts.bookRId}"` : "";
4152
+ p.push(`<externalBook${ridAttr}${bookParts.length > 0 ? `>${bookParts.join("")}</externalBook>` : "/>"}`);
4153
+ }
4154
+ if (this.opts.oleLink) {
4155
+ const oleRId = this.opts.oleRId ? ` r:id="${escapeXml(this.opts.oleRId)}"` : "";
4156
+ const oleChildren = [];
4157
+ if (this.opts.oleLink.oleItems && this.opts.oleLink.oleItems.length > 0) {
4158
+ const itemParts = [`<oleItems>`];
4159
+ for (const item of this.opts.oleLink.oleItems) {
4160
+ const itemAttrs = [`name="${escapeXml(item.name)}"`];
4161
+ if (item.advise) itemAttrs.push("advise=\"1\"");
4162
+ if (item.prefer) itemAttrs.push("prefer=\"1\"");
4163
+ itemParts.push(`<oleItem ${itemAttrs.join(" ")}/>`);
4164
+ }
4165
+ itemParts.push("</oleItems>");
4166
+ oleChildren.push(itemParts.join(""));
4167
+ }
4168
+ if (oleChildren.length > 0) p.push(`<oleLink${oleRId}>${oleChildren.join("")}</oleLink>`);
4169
+ else p.push(`<oleLink${oleRId}/>`);
4170
+ }
4171
+ p.push("</externalLink>");
4172
+ return p.join("");
4173
+ }
4174
+ };
4175
+ //#endregion
1480
4176
  //#region src/file/vml-notes.ts
1481
4177
  var VmlNotes = class {
1482
4178
  comments;
@@ -1538,7 +4234,10 @@ var Compiler = class {
1538
4234
  let globalChartIdx = 0;
1539
4235
  let globalPivotIdx = 0;
1540
4236
  let globalPivotCacheIdx = 0;
4237
+ let globalTableIdx = 0;
1541
4238
  const pivotCacheDataMap = /* @__PURE__ */ new Map();
4239
+ const calcChain = new CalcChain();
4240
+ const allTableParts = [];
1542
4241
  for (let i = 0; i < worksheets.length; i++) {
1543
4242
  const ws = worksheets[i];
1544
4243
  const imgOpts = ws.imageOptions;
@@ -1546,15 +4245,35 @@ var Compiler = class {
1546
4245
  const hlOpts = ws.hyperlinkOptions;
1547
4246
  const sheetName = file.worksheetConfigs[i]?.name ?? `Sheet${i + 1}`;
1548
4247
  let sheetXml = fmt(ws);
4248
+ const sheetIdx = i + 1;
4249
+ const wsRows = ws.worksheetRows;
4250
+ for (let ri = 0; ri < wsRows.length; ri++) {
4251
+ const rowOpts = wsRows[ri];
4252
+ const rowNumber = rowOpts.rowNumber ?? ri + 1;
4253
+ if (!rowOpts.cells) continue;
4254
+ for (let ci = 0; ci < rowOpts.cells.length; ci++) {
4255
+ const cell = rowOpts.cells[ci];
4256
+ if (!cell.formula) continue;
4257
+ const ref = cell.reference ?? columnToLetter$1(ci + 1) + rowNumber;
4258
+ calcChain.addCell({
4259
+ reference: ref,
4260
+ sheetIndex: sheetIdx,
4261
+ array: cell.formula.type === "array"
4262
+ });
4263
+ }
4264
+ }
1549
4265
  const hasMedia = imgOpts.length > 0 || chartOpts.length > 0;
1550
4266
  const hasExternalHyperlinks = hlOpts.some((h) => h.target.type === "external");
1551
4267
  const commentOpts = ws.commentOptions;
1552
4268
  const hasComments = commentOpts.length > 0;
1553
4269
  const pivotOpts = ws.pivotTables;
1554
4270
  const hasPivots = pivotOpts.length > 0;
4271
+ const tableOpts = ws.tables;
4272
+ const hasTables = tableOpts.length > 0;
4273
+ const bgImg = ws.background;
1555
4274
  let wsRels;
1556
4275
  let nextRid = 0;
1557
- if (hasMedia || hasExternalHyperlinks || hasComments || hasPivots) wsRels = new Relationships();
4276
+ if (hasMedia || hasExternalHyperlinks || hasComments || hasPivots || hasTables || bgImg) wsRels = new Relationships();
1558
4277
  if (hasExternalHyperlinks) for (const hl of hlOpts) {
1559
4278
  if (hl.target.type !== "external") continue;
1560
4279
  const rid = ++nextRid;
@@ -1634,6 +4353,22 @@ var Compiler = class {
1634
4353
  file.contentTypes.addComments(commentsIdx);
1635
4354
  file.contentTypes.addVmlDrawing();
1636
4355
  }
4356
+ if (bgImg) {
4357
+ const ext = bgImg.type === "jpg" ? "jpeg" : bgImg.type;
4358
+ const mediaKey = `bg_${i}`;
4359
+ const mediaIdx = globalMediaIdx + 1;
4360
+ file.media.addImage(mediaKey, {
4361
+ fileName: `image${mediaIdx}.${ext}`,
4362
+ type: ext,
4363
+ data: bgImg.data,
4364
+ width: 0,
4365
+ height: 0
4366
+ });
4367
+ globalMediaIdx++;
4368
+ const bgRid = ++nextRid;
4369
+ wsRels.addRelationship(bgRid, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `../media/image${mediaIdx}.${ext}`);
4370
+ sheetXml = sheetXml.replace("<!--BACKGROUND_PICTURE-->", `<picture r:id="rId${bgRid}"/>`);
4371
+ }
1637
4372
  if (hasPivots) for (const pt of pivotOpts) {
1638
4373
  globalPivotIdx++;
1639
4374
  const pivotIdx = globalPivotIdx;
@@ -1694,6 +4429,24 @@ var Compiler = class {
1694
4429
  wsRels.addRelationship(ptRid, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable", `../pivotTables/pivotTable${pivotIdx}.xml`);
1695
4430
  file.contentTypes.addPivotTable(pivotIdx);
1696
4431
  }
4432
+ const wsTableParts = [];
4433
+ if (hasTables) for (const tbl of tableOpts) {
4434
+ globalTableIdx++;
4435
+ const tableIdx = globalTableIdx;
4436
+ const tableXml = new TableXml({
4437
+ ...tbl,
4438
+ id: tbl.id ?? tableIdx
4439
+ });
4440
+ mapping[`Table${tableIdx}`] = {
4441
+ data: fmt(tableXml),
4442
+ path: `xl/tables/table${tableIdx}.xml`
4443
+ };
4444
+ const tblRid = ++nextRid;
4445
+ wsRels.addRelationship(tblRid, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table", `../tables/table${tableIdx}.xml`);
4446
+ wsTableParts.push({ rId: `rId${tblRid}` });
4447
+ allTableParts.push({ rId: `rId${tblRid}` });
4448
+ file.contentTypes.addTable(tableIdx);
4449
+ }
1697
4450
  if (hasPivots) {
1698
4451
  const rendered = renderPivotSheetData(pivotOpts, worksheets, file.sharedStrings, file.worksheetConfigs, sheetName);
1699
4452
  if (rendered.sheetData.length > 0) {
@@ -1701,6 +4454,10 @@ var Compiler = class {
1701
4454
  if (!sheetXml.includes("<dimension")) sheetXml = sheetXml.replace("<sheetViews", `<dimension ref="${rendered.dimensionRef}"/><sheetViews`);
1702
4455
  }
1703
4456
  }
4457
+ if (wsTableParts.length > 0) {
4458
+ const tablePartsXml = WorkbookXml.buildTablePartsXml(wsTableParts);
4459
+ sheetXml = sheetXml.slice(0, -12) + tablePartsXml + "</worksheet>";
4460
+ }
1704
4461
  if (wsRels) mapping[`WorksheetRels${i}`] = {
1705
4462
  data: fmt(wsRels),
1706
4463
  path: `xl/worksheets/_rels/sheet${i + 1}.xml.rels`
@@ -1710,8 +4467,83 @@ var Compiler = class {
1710
4467
  path: `xl/worksheets/sheet${i + 1}.xml`
1711
4468
  };
1712
4469
  }
4470
+ const chartsheetConfigs = file.chartsheetConfigs;
4471
+ for (let i = 0; i < chartsheetConfigs.length; i++) {
4472
+ const csOpts = chartsheetConfigs[i];
4473
+ const chartsheet = new Chartsheet(csOpts);
4474
+ const chartDef = csOpts.chart;
4475
+ const csChartGlobalIdx = file.charts.array.length;
4476
+ const csChartKey = `cs_chart_${csChartGlobalIdx}`;
4477
+ file.charts.addChart(csChartKey, {
4478
+ key: csChartKey,
4479
+ chartSpace: new ChartSpace({
4480
+ type: chartDef.type,
4481
+ title: chartDef.title,
4482
+ categories: chartDef.categories,
4483
+ series: chartDef.series
4484
+ })
4485
+ });
4486
+ const csRels = new Relationships();
4487
+ const csDrawingIdx = i + 1;
4488
+ csRels.addRelationship(1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing", `../drawings/drawing${csDrawingIdx}.xml`);
4489
+ chartsheet.setDrawingRId("rId1");
4490
+ const csDrawingRels = new Relationships();
4491
+ csDrawingRels.addRelationship(1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", `../charts/chart${csChartGlobalIdx + 1}.xml`);
4492
+ const csDrawingXml = `<xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><xdr:absoluteAnchor><xdr:pos x="0" y="0"/><xdr:ext cx="9308969" cy="6096000"/><xdr:graphicFrame><xdr:nvGraphicFramePr><xdr:cNvPr id="1" name="Chart ${i + 1}"/><xdr:cNvGraphicFramePr><a:graphicFrameLocks noGrp="1"/></xdr:cNvGraphicFramePr></xdr:nvGraphicFramePr><xdr:xfrm><a:off x="0" y="0"/><a:ext cx="9308969" cy="6096000"/></xdr:xfrm><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart"><c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" r:id="rId1"/></a:graphicData></a:graphic></xdr:graphicFrame><xdr:clientData/></xdr:absoluteAnchor></xdr:wsDr>`;
4493
+ mapping[`ChartsheetDrawing${i}`] = {
4494
+ data: csDrawingXml,
4495
+ path: `xl/drawings/drawing${csDrawingIdx}.xml`
4496
+ };
4497
+ mapping[`ChartsheetDrawingRels${i}`] = {
4498
+ data: fmt(csDrawingRels),
4499
+ path: `xl/drawings/_rels/drawing${csDrawingIdx}.xml.rels`
4500
+ };
4501
+ file.contentTypes.addDrawing(csDrawingIdx);
4502
+ mapping[`ChartsheetRels${i}`] = {
4503
+ data: fmt(csRels),
4504
+ path: `xl/chartsheets/_rels/sheet${i + 1}.xml.rels`
4505
+ };
4506
+ mapping[`Chartsheet${i}`] = {
4507
+ data: chartsheet.toXml(context),
4508
+ path: `xl/chartsheets/sheet${i + 1}.xml`
4509
+ };
4510
+ file.contentTypes.addChartsheet(i + 1);
4511
+ }
4512
+ let workbookXml = fmt(file.workbookXml);
4513
+ const extLinks = file.externalLinks;
4514
+ if (extLinks.length > 0) {
4515
+ const extRefs = [];
4516
+ for (let ei = 0; ei < extLinks.length; ei++) {
4517
+ const elIdx = ei + 1;
4518
+ const elRid = file.workbookRelationships.relationshipCount + 1;
4519
+ file.workbookRelationships.addRelationship(elRid, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink", `externalLinks/externalLink${elIdx}.xml`);
4520
+ const elOpts = extLinks[ei];
4521
+ let bookRId;
4522
+ if (elOpts.externalBook?.target) {
4523
+ const elRels = new Relationships();
4524
+ elRels.addRelationship(1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath", elOpts.externalBook.target, TargetModeType.EXTERNAL);
4525
+ bookRId = "rId1";
4526
+ mapping[`ExternalLinkRels${elIdx}`] = {
4527
+ data: fmt(elRels),
4528
+ path: `xl/externalLinks/_rels/externalLink${elIdx}.xml.rels`
4529
+ };
4530
+ }
4531
+ const elXml = new ExternalLinkXml({
4532
+ ...elOpts,
4533
+ bookRId
4534
+ });
4535
+ mapping[`ExternalLink${elIdx}`] = {
4536
+ data: fmt(elXml),
4537
+ path: `xl/externalLinks/externalLink${elIdx}.xml`
4538
+ };
4539
+ extRefs.push({ rId: `rId${elRid}` });
4540
+ file.contentTypes.addExternalLink(elIdx);
4541
+ }
4542
+ const extRefsXml = WorkbookXml.buildExternalReferencesXml(extRefs);
4543
+ workbookXml = workbookXml.replace("<!--EXTERNAL_REFS-->", extRefsXml);
4544
+ } else workbookXml = workbookXml.replace("<!--EXTERNAL_REFS-->", "");
1713
4545
  mapping["Workbook"] = {
1714
- data: fmt(file.workbookXml),
4546
+ data: workbookXml,
1715
4547
  path: "xl/workbook.xml"
1716
4548
  };
1717
4549
  mapping["WorkbookRelationships"] = {
@@ -1740,6 +4572,15 @@ var Compiler = class {
1740
4572
  };
1741
4573
  file.contentTypes.addChart(i + 1);
1742
4574
  }
4575
+ if (calcChain.count > 0) {
4576
+ mapping["CalcChain"] = {
4577
+ data: calcChain.toXml(context),
4578
+ path: "xl/calcChain.xml"
4579
+ };
4580
+ file.contentTypes.addCalcChain();
4581
+ const calcChainRid = file.workbookRelationships.relationshipCount + 1;
4582
+ file.workbookRelationships.addRelationship(calcChainRid, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/calcChain", "calcChain.xml");
4583
+ }
1743
4584
  const imageExts = /* @__PURE__ */ new Set();
1744
4585
  for (const img of file.media.array) {
1745
4586
  const ext = img.fileName.endsWith(".png") ? "png" : "jpeg";
@@ -1778,7 +4619,10 @@ function extractPivotSourceData(rows, sourceRef) {
1778
4619
  const colCount = endCol - startCol + 1;
1779
4620
  const headerRow = rows[startRow];
1780
4621
  const fieldNames = [];
1781
- if (headerRow?.cells) for (let c = startCol; c <= endCol && c < headerRow.cells.length; c++) fieldNames.push(String(headerRow.cells[c]?.value ?? `Col${c}`));
4622
+ if (headerRow?.cells) for (let c = startCol; c <= endCol && c < headerRow.cells.length; c++) {
4623
+ const hv = headerRow.cells[c]?.value;
4624
+ fieldNames.push(typeof hv === "string" ? hv : typeof hv === "number" || typeof hv === "boolean" ? String(hv) : `Col${c}`);
4625
+ }
1782
4626
  const records = [];
1783
4627
  for (let r = startRow + 1; r <= endRow; r++) {
1784
4628
  const row = rows[r];
@@ -1788,7 +4632,7 @@ function extractPivotSourceData(rows, sourceRef) {
1788
4632
  const val = row.cells[c]?.value;
1789
4633
  if (typeof val === "number") record.push(val);
1790
4634
  else if (val instanceof Date) record.push(val.getTime());
1791
- else record.push(String(val ?? ""));
4635
+ else record.push(typeof val === "string" ? val : typeof val === "boolean" ? String(val) : "");
1792
4636
  }
1793
4637
  if (record.length === colCount) records.push(record);
1794
4638
  }
@@ -1835,7 +4679,10 @@ function renderPivotSheetData(pivotOpts, worksheets, sharedStrings, worksheetCon
1835
4679
  let group = groupMap.get(groupKey);
1836
4680
  if (!group) {
1837
4681
  group = {
1838
- keys: rowFieldIndices.map((fi) => record[fi]),
4682
+ keys: rowFieldIndices.map((fi) => {
4683
+ const v = record[fi];
4684
+ return typeof v === "string" || typeof v === "number" ? v : String(v ?? "");
4685
+ }),
1839
4686
  values: dataFieldIndices.map(() => [])
1840
4687
  };
1841
4688
  groupMap.set(groupKey, group);
@@ -1928,6 +4775,16 @@ function colIndexToLetterCompiler(col) {
1928
4775
  }
1929
4776
  return result;
1930
4777
  }
4778
+ function columnToLetter$1(col) {
4779
+ let result = "";
4780
+ let n = col;
4781
+ while (n > 0) {
4782
+ const remainder = (n - 1) % 26;
4783
+ result = String.fromCharCode(65 + remainder) + result;
4784
+ n = Math.floor((n - 1) / 26);
4785
+ }
4786
+ return result;
4787
+ }
1931
4788
  //#endregion
1932
4789
  //#region src/export/packer/packer.ts
1933
4790
  /**
@@ -2312,6 +5169,6 @@ function findLocalChild(parent, name) {
2312
5169
  return (parent.elements ?? []).find((el) => localName(el) === name);
2313
5170
  }
2314
5171
  //#endregion
2315
- export { File, File as Workbook, Packer, PatchType, SharedStrings, Styles, columnToLetter, dateToSerialNumber, letterToColumn, parseWorkbook, parseXlsx, patchWorkbook };
5172
+ export { ConnectionsXml, Dialogsheet, File, File as Workbook, MapInfoXml, MetadataXml, Packer, PatchType, PivotFilterType as PivotFilterTypeValue, QueryTableXml, RevisionHeadersXml, RevisionLogXml, SharedStrings, SingleXmlCellsXml, Styles, TableType, TotalsRowFunction, XmlColumnPrXml, columnToLetter, dateToSerialNumber, letterToColumn, parseWorkbook, parseXlsx, patchWorkbook };
2316
5173
 
2317
5174
  //# sourceMappingURL=index.mjs.map