@office-open/xlsx 0.7.1 → 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,5 +1,6 @@
1
- import { AppProperties, BaseXmlComponent, ChartCollection, ChartSpace, Formatter, IgnoreIfEmptyXmlComponent, OoxmlMimeType, Relationships, buildCorePropertiesXmlString, compileMapping, createPacker, parseArchive, parseCorePropsElement, strFromU8, toJson, toUint8Array, 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 { DefaultTheme } from "@office-open/core/theme";
3
4
  //#region src/file/content-types.ts
4
5
  /**
5
6
  * Content Types module for XLSX packages.
@@ -8,6 +9,7 @@ import { attr, attrNum, attrs, escapeXml, findChild, js2xml, selfCloseElement, t
8
9
  */
9
10
  const XLSX_MAIN = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
10
11
  const XLSX_WORKSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml";
12
+ const XLSX_CHARTSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml";
11
13
  const XLSX_STYLES = "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml";
12
14
  const XLSX_SHARED_STRINGS = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml";
13
15
  const XLSX_THEME = "application/vnd.openxmlformats-officedocument.theme+xml";
@@ -51,6 +53,13 @@ var ContentTypes = class extends BaseXmlComponent {
51
53
  key: `/xl/worksheets/sheet${index}.xml`
52
54
  });
53
55
  }
56
+ addChartsheet(index) {
57
+ this.dynamicEntries.push({
58
+ type: "Override",
59
+ contentType: XLSX_CHARTSHEET,
60
+ key: `/xl/chartsheets/sheet${index}.xml`
61
+ });
62
+ }
54
63
  addStyles() {
55
64
  this.dynamicEntries.push({
56
65
  type: "Override",
@@ -131,6 +140,62 @@ var ContentTypes = class extends BaseXmlComponent {
131
140
  key: `/xl/pivotCache/pivotCacheRecords${index}.xml`
132
141
  });
133
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
+ }
134
199
  toXml(_context) {
135
200
  const p = ["<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">", STATIC_XML];
136
201
  for (const e of this.dynamicEntries) if (e.type === "Default") p.push(`<Default ContentType="${e.contentType}" Extension="${e.key}"/>`);
@@ -177,34 +242,81 @@ var Media = class {
177
242
  *
178
243
  * @module
179
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
+ }
180
281
  var SharedStrings = class extends BaseXmlComponent {
181
- strings = [];
282
+ entries = [];
283
+ /** Dedup map for plain strings only. Rich text is not deduped. */
182
284
  indexMap = /* @__PURE__ */ new Map();
183
285
  constructor() {
184
286
  super("sst");
185
287
  }
186
288
  /**
187
- * Register a string and return its index.
289
+ * Register a plain string and return its index.
188
290
  * Returns existing index if the string is already registered.
189
291
  */
190
292
  register(s) {
191
293
  const existing = this.indexMap.get(s);
192
294
  if (existing !== void 0) return existing;
193
- const idx = this.strings.length;
194
- this.strings.push(s);
295
+ const idx = this.entries.length;
296
+ this.entries.push(s);
195
297
  this.indexMap.set(s, idx);
196
298
  return idx;
197
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
+ }
198
309
  get count() {
199
- return this.strings.length;
310
+ return this.entries.length;
200
311
  }
201
312
  /**
202
313
  * Zero-allocation fast path: directly concatenate XML string.
203
314
  * Bypasses the IXmlableObject intermediate tree entirely.
204
315
  */
205
316
  toXml(_context) {
206
- const p = ["<sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"", ` count="${this.strings.length}" uniqueCount="${this.indexMap.size}">`];
207
- 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>`);
208
320
  p.push("</sst>");
209
321
  return p.join("");
210
322
  }
@@ -220,14 +332,14 @@ var SharedStrings = class extends BaseXmlComponent {
220
332
  * @module
221
333
  */
222
334
  function fontKey(f) {
223
- 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}`;
224
336
  }
225
337
  function fillKey(f) {
226
- 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("|") ?? ""}`;
227
339
  }
228
340
  function borderKey(b) {
229
341
  const sk = (o) => `${o?.style ?? ""}_${o?.color ?? ""}`;
230
- 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)}`;
231
343
  }
232
344
  const BUILTIN_NUMFMTS = {
233
345
  General: 0,
@@ -277,6 +389,10 @@ var Styles = class extends BaseXmlComponent {
277
389
  }];
278
390
  cellXfKeys = /* @__PURE__ */ new Map();
279
391
  dxfs = [];
392
+ colors;
393
+ tableStyles;
394
+ /** Style sheet extensions (CT_ExtensionList) */
395
+ styleExtensions;
280
396
  constructor() {
281
397
  super("styleSheet");
282
398
  this.fontKeys.set(fontKey(this.fonts[0]), 0);
@@ -295,7 +411,10 @@ var Styles = class extends BaseXmlComponent {
295
411
  fillId: this.registerFill(opts.fill),
296
412
  borderId: this.registerBorder(opts.border),
297
413
  numFmtId: this.registerNumFmt(opts.numFmt),
298
- alignment: opts.alignment
414
+ alignment: opts.alignment,
415
+ quotePrefix: opts.quotePrefix,
416
+ pivotButton: opts.pivotButton,
417
+ protection: opts.protection
299
418
  };
300
419
  const key = this.cellXfKey(xf);
301
420
  const existing = this.cellXfKeys.get(key);
@@ -314,6 +433,18 @@ var Styles = class extends BaseXmlComponent {
314
433
  this.dxfs.push(opts);
315
434
  return idx;
316
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
+ }
317
448
  registerFont(opts) {
318
449
  if (!opts) return 0;
319
450
  const key = fontKey(opts);
@@ -356,8 +487,10 @@ var Styles = class extends BaseXmlComponent {
356
487
  }
357
488
  cellXfKey(xf) {
358
489
  const a = xf.alignment;
359
- const ak = a ? `h${a.horizontal ?? ""}v${a.vertical ?? ""}w${a.wrapText ? 1 : 0}r${a.textRotation ?? ""}i${a.indent ?? ""}` : "";
360
- 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}`;
361
494
  }
362
495
  /**
363
496
  * Zero-allocation fast path: directly concatenate XML string.
@@ -374,10 +507,20 @@ var Styles = class extends BaseXmlComponent {
374
507
  for (const f of this.fonts) p.push(`<font>${this.fontXmlStr(f)}</font>`);
375
508
  p.push("</fonts>");
376
509
  p.push(`<fills count="${this.fills.length}">`);
377
- 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 {
378
521
  const patternAttrs = attrs({ patternType: f.patternType ?? "solid" });
379
- const fgColor = f.color ? `<fgColor rgb="FF${f.color}"/>` : "";
380
- 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>`);
381
524
  }
382
525
  p.push("</fills>");
383
526
  p.push(`<borders count="${this.borders.length}">`);
@@ -397,8 +540,11 @@ var Styles = class extends BaseXmlComponent {
397
540
  if (xf.fontId > 0) xAttrs.applyFont = 1;
398
541
  if (xf.fillId > 0) xAttrs.applyFill = 1;
399
542
  if (xf.borderId > 0) xAttrs.applyBorder = 1;
400
- const alignStr = xf.alignment ? this.alignmentXmlStr(xf.alignment) : "";
401
- 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)}/>`);
402
548
  }
403
549
  p.push("</cellXfs>");
404
550
  p.push("<cellStyles count=\"1\"><cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/></cellStyles>");
@@ -418,8 +564,48 @@ var Styles = class extends BaseXmlComponent {
418
564
  }
419
565
  p.push("</dxfs>");
420
566
  } else p.push("<dxfs count=\"0\"/>");
421
- p.push("<tableStyles count=\"0\" defaultTableStyle=\"TableStyleMedium2\" defaultPivotStyle=\"PivotStyleLight16\"/>");
422
- 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/>");
423
609
  p.push("</styleSheet>");
424
610
  return p.join("");
425
611
  }
@@ -429,26 +615,38 @@ var Styles = class extends BaseXmlComponent {
429
615
  if (f.italic) parts.push("<i/>");
430
616
  if (f.underline) parts.push("<u/>");
431
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/>");
432
622
  if (f.size) parts.push(`<sz val="${f.size}"/>`);
433
623
  if (f.color) parts.push(`<color rgb="FF${f.color}"/>`);
434
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}"/>`);
435
629
  return parts.join("");
436
630
  }
437
631
  borderXmlStr(b) {
438
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
+ };
439
639
  for (const side of [
440
640
  "left",
441
641
  "right",
442
642
  "top",
443
643
  "bottom",
444
- "diagonal"
445
- ]) {
446
- const opts = b[side];
447
- if (opts && opts.style && opts.style !== "none") {
448
- const colorStr = opts.color ? `<color rgb="FF${opts.color}"/>` : "";
449
- parts.push(`<${side} style="${opts.style}">${colorStr}</${side}>`);
450
- } else parts.push(`<${side}/>`);
451
- }
644
+ "diagonal",
645
+ "vertical",
646
+ "horizontal"
647
+ ]) renderSide(side, b[side]);
648
+ renderSide("start", b.start, false);
649
+ renderSide("end", b.end, false);
452
650
  return parts.join("");
453
651
  }
454
652
  alignmentXmlStr(a) {
@@ -458,29 +656,17 @@ var Styles = class extends BaseXmlComponent {
458
656
  if (a.wrapText) aAttrs.wrapText = 1;
459
657
  if (a.textRotation !== void 0) aAttrs.textRotation = a.textRotation;
460
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;
461
663
  return `<alignment${attrs(aAttrs)}/>`;
462
664
  }
463
- };
464
- //#endregion
465
- //#region src/file/theme.ts
466
- /**
467
- * Default theme for XLSX files — matches Microsoft Office's output structure.
468
- * Produces xl/theme/theme1.xml that Excel accepts without repair warnings.
469
- *
470
- * The theme XML is completely static — identical for every XLSX file.
471
- * Pre-serialized as a string constant to avoid building the IXmlableObject
472
- * tree and re-serializing on every compile.
473
- *
474
- * @module
475
- */
476
- 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>";
477
- var DefaultTheme = class extends BaseXmlComponent {
478
- constructor() {
479
- super("a:theme");
480
- }
481
- /** Return pre-cached static theme XML — zero allocation. */
482
- toXml(_context) {
483
- 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)}/>`;
484
670
  }
485
671
  };
486
672
  //#endregion
@@ -493,32 +679,301 @@ var DefaultTheme = class extends BaseXmlComponent {
493
679
  var WorkbookXml = class extends BaseXmlComponent {
494
680
  sheets;
495
681
  pivotCaches;
496
- 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) {
497
694
  super("workbook");
498
695
  this.sheets = sheets;
499
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;
500
708
  }
501
709
  toXml(_context) {
502
- const p = [
503
- "<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\">",
504
- "<fileVersion appName=\"xl\" lastEdited=\"7\" lowestEdited=\"6\" rupBuild=\"29929\"/>",
505
- "<workbookPr/>",
506
- "<bookViews><workbookView xWindow=\"0\" yWindow=\"0\" windowWidth=\"28800\" windowHeight=\"12300\"/></bookViews>",
507
- "<sheets>"
508
- ];
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>");
509
812
  for (const s of this.sheets) {
510
813
  const stateAttr = s.state && s.state !== "visible" ? ` state="${s.state}"` : "";
511
- 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>");
512
873
  }
513
- p.push("</sheets>");
514
- p.push("<calcPr calcId=\"162913\"/>");
515
874
  if (this.pivotCaches.length > 0) {
516
- p.push("<pivotCaches>");
517
- for (const pc of this.pivotCaches) p.push(`<pivotCache cacheId="${pc.cacheId}" r:id="${pc.rId}"/>`);
518
- 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>");
519
878
  }
520
- p.push("</workbook>");
521
- 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");
522
977
  }
523
978
  };
524
979
  //#endregion
@@ -540,6 +995,8 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
540
995
  mergeCells;
541
996
  freezePanes;
542
997
  protection;
998
+ protectedRanges;
999
+ scenarioOpts;
543
1000
  autoFilter;
544
1001
  images;
545
1002
  chartOptions;
@@ -552,6 +1009,28 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
552
1009
  tabColor;
553
1010
  sheetView;
554
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;
555
1034
  constructor(options) {
556
1035
  super("worksheet");
557
1036
  this.rows = options.rows ?? [];
@@ -559,6 +1038,8 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
559
1038
  this.mergeCells = options.mergeCells ?? [];
560
1039
  this.freezePanes = options.freezePanes;
561
1040
  this.protection = options.protection;
1041
+ this.protectedRanges = options.protectedRanges ?? [];
1042
+ this.scenarioOpts = options.scenarios;
562
1043
  this.autoFilter = options.autoFilter;
563
1044
  this.images = options.images ?? [];
564
1045
  this.chartOptions = options.charts ?? [];
@@ -571,6 +1052,28 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
571
1052
  this.tabColor = options.tabColor;
572
1053
  this.sheetView = options.sheetView;
573
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 ?? [];
574
1077
  }
575
1078
  get imageOptions() {
576
1079
  return this.images;
@@ -590,6 +1093,12 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
590
1093
  get pivotTables() {
591
1094
  return this.pivotTableOptions;
592
1095
  }
1096
+ get tables() {
1097
+ return this.tableOptions;
1098
+ }
1099
+ get background() {
1100
+ return this.backgroundImage;
1101
+ }
593
1102
  /**
594
1103
  * Zero-allocation fast path: directly concatenate XML string.
595
1104
  * Bypasses the IXmlableObject intermediate tree entirely.
@@ -601,8 +1110,19 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
601
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\">"];
602
1111
  const hasTabColor = !!this.tabColor;
603
1112
  const hasOutline = this.columns.some((c) => c.outlineLevel !== void 0);
604
- 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) {
605
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;
606
1126
  if (this.tabColor) {
607
1127
  const tc = this.tabColor;
608
1128
  const tcAttrs = {};
@@ -611,8 +1131,18 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
611
1131
  if (tc.tint !== void 0) tcAttrs.tint = tc.tint;
612
1132
  prParts.push(`<tabColor${attrs(tcAttrs)}/>`);
613
1133
  }
614
- if (hasOutline) prParts.push("<outlinePr summaryBelow=\"1\" summaryRight=\"1\"/>");
615
- 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>`);
616
1146
  }
617
1147
  const maxRow = this.rows.length;
618
1148
  let maxCol = 0;
@@ -621,6 +1151,7 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
621
1151
  const dimRef = `A1:${this.defaultCellRef(maxRow, maxCol)}`;
622
1152
  p.push(`<dimension ref="${dimRef}"/>`);
623
1153
  }
1154
+ const pivotSelXml = this.sheetView?.pivotSelections ? this.sheetView.pivotSelections.map((ps) => this.buildPivotSelectionXml(ps)).join("") : "";
624
1155
  if (this.freezePanes) {
625
1156
  const fp = this.freezePanes;
626
1157
  const ySplit = fp.row ? fp.row : 0;
@@ -630,12 +1161,26 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
630
1161
  const topLeftCell = this.defaultCellRef(topRow, leftCol);
631
1162
  const activePane = ySplit > 0 && xSplit > 0 ? "bottomRight" : ySplit > 0 ? "bottomLeft" : "topRight";
632
1163
  const svAttrs = this.buildSheetViewAttrs();
633
- 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>");
634
1165
  } else {
635
1166
  const svAttrs = this.buildSheetViewAttrs();
636
- 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>`);
637
1170
  }
638
- 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\"/>");
639
1184
  if (this.columns.length > 0) {
640
1185
  p.push("<cols>");
641
1186
  for (const col of this.columns) {
@@ -650,6 +1195,8 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
650
1195
  if (col.hidden) colAttrs.hidden = 1;
651
1196
  if (col.outlineLevel !== void 0) colAttrs.outlineLevel = col.outlineLevel;
652
1197
  if (col.collapsed) colAttrs.collapsed = 1;
1198
+ if (col.bestFit) colAttrs.bestFit = 1;
1199
+ if (col.phonetic) colAttrs.phonetic = 1;
653
1200
  p.push(selfCloseElement("col", attrs(colAttrs)));
654
1201
  }
655
1202
  p.push("</cols>");
@@ -664,6 +1211,11 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
664
1211
  rowAttrs.customHeight = 1;
665
1212
  }
666
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;
667
1219
  if (rowOpts.cells) {
668
1220
  const rowParts = [];
669
1221
  for (let j = 0; j < rowOpts.cells.length; j++) {
@@ -676,10 +1228,92 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
676
1228
  } else p.push(`<row${attrs(rowAttrs)}/>`);
677
1229
  }
678
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
+ }
679
1306
  if (this.protection) {
680
1307
  const prot = this.protection;
681
1308
  const protAttrs = {};
682
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;
683
1317
  if (prot.sheet) protAttrs.sheet = 1;
684
1318
  if (prot.objects) protAttrs.objects = 1;
685
1319
  if (prot.scenarios) protAttrs.scenarios = 1;
@@ -698,6 +1332,55 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
698
1332
  if (prot.selectUnlockedCells) protAttrs.selectUnlockedCells = 1;
699
1333
  p.push(selfCloseElement("sheetProtection", attrs(protAttrs)));
700
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
+ }
701
1384
  if (this.autoFilter) if (typeof this.autoFilter === "string") p.push(selfCloseElement("autoFilter", attrs({ ref: this.autoFilter })));
702
1385
  else {
703
1386
  const af = this.autoFilter;
@@ -725,9 +1408,43 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
725
1408
  for (const sc of af.sort) {
726
1409
  const scAttrs = { ref: sc.ref };
727
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;
728
1414
  sortParts.push(selfCloseElement("sortCondition", attrs(scAttrs)));
729
1415
  }
730
- 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>`);
731
1448
  }
732
1449
  if (inner.length > 0) p.push(`<autoFilter ref="${af.ref}">`, ...inner, "</autoFilter>");
733
1450
  else p.push(selfCloseElement("autoFilter", attrs({ ref: af.ref })));
@@ -741,6 +1458,13 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
741
1458
  }
742
1459
  p.push("</mergeCells>");
743
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
+ }
744
1468
  if (this.conditionalFormats.length > 0) for (const cf of this.conditionalFormats) {
745
1469
  p.push(`<conditionalFormatting sqref="${cf.sqref}">`);
746
1470
  for (let ri = 0; ri < cf.rules.length; ri++) {
@@ -751,7 +1475,39 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
751
1475
  };
752
1476
  if (rule.operator) ruleAttrs.operator = rule.operator;
753
1477
  if (rule.dxfId !== void 0) ruleAttrs.dxfId = rule.dxfId;
754
- 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) {
755
1511
  const formulaParts = rule.formulas.map((f) => `<formula>${escapeXml(f)}</formula>`);
756
1512
  p.push(`<cfRule${attrs(ruleAttrs)}>`, ...formulaParts, "</cfRule>");
757
1513
  } else p.push(selfCloseElement("cfRule", attrs(ruleAttrs)));
@@ -771,6 +1527,9 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
771
1527
  if (dv.error) dvAttrs.error = dv.error;
772
1528
  if (dv.promptTitle) dvAttrs.promptTitle = dv.promptTitle;
773
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;
774
1533
  const inner = [];
775
1534
  if (dv.formula1 !== void 0) inner.push(`<formula1>${escapeXml(dv.formula1)}</formula1>`);
776
1535
  if (dv.formula2 !== void 0) inner.push(`<formula2>${escapeXml(dv.formula2)}</formula2>`);
@@ -794,6 +1553,16 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
794
1553
  }
795
1554
  p.push("</hyperlinks>");
796
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
+ }
797
1566
  p.push("<pageMargins left=\"0.75\" right=\"0.75\" top=\"1\" bottom=\"1\" header=\"0.5\" footer=\"0.5\"/>");
798
1567
  if (this.pageSetup) {
799
1568
  const ps = this.pageSetup;
@@ -806,6 +1575,13 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
806
1575
  if (ps.pageOrder && ps.pageOrder !== "downThenOver") psAttrs.pageOrder = ps.pageOrder;
807
1576
  if (ps.useFirstPageNumber) psAttrs.useFirstPageNumber = 1;
808
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;
809
1585
  p.push(selfCloseElement("pageSetup", attrs(psAttrs)));
810
1586
  }
811
1587
  if (this.headerFooter) {
@@ -813,6 +1589,8 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
813
1589
  const hfAttrs = {};
814
1590
  if (hf.differentOddEven) hfAttrs.differentOddEven = 1;
815
1591
  if (hf.differentFirst) hfAttrs.differentFirst = 1;
1592
+ if (hf.scaleWithDoc === false) hfAttrs.scaleWithDoc = 0;
1593
+ if (hf.alignWithMargins === false) hfAttrs.alignWithMargins = 0;
816
1594
  const inner = [];
817
1595
  if (hf.oddHeader) inner.push(`<oddHeader>${escapeXml(hf.oddHeader)}</oddHeader>`);
818
1596
  if (hf.oddFooter) inner.push(`<oddFooter>${escapeXml(hf.oddFooter)}</oddFooter>`);
@@ -823,9 +1601,125 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
823
1601
  if (inner.length > 0) p.push(`<headerFooter${attrs(hfAttrs)}>`, ...inner, "</headerFooter>");
824
1602
  else if (hfAttrs.differentOddEven || hfAttrs.differentFirst) p.push(selfCloseElement("headerFooter", attrs(hfAttrs)));
825
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>`);
826
1711
  p.push("</worksheet>");
827
1712
  return p.join("");
828
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
+ }
829
1723
  buildSheetViewAttrs() {
830
1724
  const sv = this.sheetView;
831
1725
  const svMap = { workbookViewId: 0 };
@@ -836,8 +1730,48 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
836
1730
  if (sv?.showZeros === false) svMap.showZeros = 0;
837
1731
  if (sv?.zoomScale !== void 0) svMap.zoomScale = sv.zoomScale;
838
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;
839
1744
  return attrs(svMap);
840
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
+ }
841
1775
  /**
842
1776
  * Excel legacy password hash (16-bit, little-endian hex).
843
1777
  * Matches the algorithm used by ECMA-376 Part 1, §18.2.27.
@@ -863,6 +1797,15 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
863
1797
  if (fOpts.type && fOpts.type !== FormulaType.NORMAL) fAttrs.t = fOpts.type;
864
1798
  if (fOpts.reference) fAttrs.ref = fOpts.reference;
865
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;
866
1809
  if (fOpts.formula !== void 0 && fOpts.formula !== "") return `<f${attrs(fAttrs)}>${escapeXml(fOpts.formula)}</f>`;
867
1810
  if (Object.keys(fAttrs).length > 0) return selfCloseElement("f", attrs(fAttrs));
868
1811
  return "";
@@ -894,6 +1837,15 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
894
1837
  if (cell.styleIndex !== void 0) return selfCloseElement("c", attrs(cellAttrs));
895
1838
  return "";
896
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
+ }
897
1849
  if (typeof value === "string") {
898
1850
  if (sharedStrings) {
899
1851
  cellAttrs.t = "s";
@@ -941,8 +1893,18 @@ var Worksheet = class extends IgnoreIfEmptyXmlComponent {
941
1893
  */
942
1894
  var File = class {
943
1895
  worksheetOptions;
1896
+ chartsheetOptions;
944
1897
  corePropsOptions;
945
1898
  dxfOptions;
1899
+ protectionOptions;
1900
+ externalLinkOptions;
1901
+ customViewOptions;
1902
+ fileRecoveryPrOpts;
1903
+ functionGroupOpts;
1904
+ webPublishingOpts;
1905
+ fileSharingOpts;
1906
+ volTypeOpts;
1907
+ webPublishObjectOpts;
946
1908
  _coreProperties;
947
1909
  _appProperties;
948
1910
  _contentTypes;
@@ -958,8 +1920,18 @@ var File = class {
958
1920
  _pivotCacheRefs = [];
959
1921
  constructor(options) {
960
1922
  this.worksheetOptions = options.worksheets ?? [];
1923
+ this.chartsheetOptions = options.chartsheets ?? [];
961
1924
  this.corePropsOptions = options;
962
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;
963
1935
  }
964
1936
  get coreProperties() {
965
1937
  return this._coreProperties ??= new CoreProperties(this.corePropsOptions);
@@ -992,12 +1964,20 @@ var File = class {
992
1964
  }
993
1965
  get workbookXml() {
994
1966
  if (!this._workbookXml) {
995
- const sheets = this.worksheetOptions.map((ws, i) => ({
996
- name: ws.name ?? `Sheet${i + 1}`,
997
- sheetId: i + 1,
998
- rId: `rId${i + 1}`
999
- }));
1000
- 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);
1001
1981
  }
1002
1982
  return this._workbookXml;
1003
1983
  }
@@ -1022,9 +2002,15 @@ var File = class {
1022
2002
  rId
1023
2003
  });
1024
2004
  }
2005
+ get externalLinks() {
2006
+ return this.externalLinkOptions;
2007
+ }
1025
2008
  get worksheetConfigs() {
1026
2009
  return this.worksheetOptions;
1027
2010
  }
2011
+ get chartsheetConfigs() {
2012
+ return this.chartsheetOptions;
2013
+ }
1028
2014
  get worksheets() {
1029
2015
  if (!this._worksheets) this._worksheets = this.worksheetOptions.map((ws) => new Worksheet(ws));
1030
2016
  return this._worksheets;
@@ -1043,6 +2029,7 @@ var File = class {
1043
2029
  this._workbookRels = new Relationships();
1044
2030
  let rid = 1;
1045
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`);
1046
2033
  this._workbookRels.addRelationship(rid++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", "styles.xml");
1047
2034
  this._workbookRels.addRelationship(rid++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", "theme/theme1.xml");
1048
2035
  this._workbookRels.addRelationship(rid++, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", "sharedStrings.xml");
@@ -1051,79 +2038,76 @@ var File = class {
1051
2038
  }
1052
2039
  };
1053
2040
  //#endregion
1054
- //#region src/file/comments.ts
1055
- /**
1056
- * Generates xl/comments{n}.xml — cell comment data.
1057
- *
1058
- * @module
1059
- */
1060
- var Comments = class extends BaseXmlComponent {
1061
- entries;
1062
- constructor(entries) {
1063
- super("comments");
1064
- this.entries = entries;
1065
- }
1066
- toXml(_context) {
1067
- const authors = this.collectAuthors();
1068
- const p = ["<comments xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">", `<authors>`];
1069
- for (const author of authors) p.push(`<author>${escapeXml(author)}</author>`);
1070
- p.push("</authors><commentList>");
1071
- for (const entry of this.entries) {
1072
- const authorId = authors.indexOf(entry.author);
1073
- p.push(`<comment ref="${entry.cell}" authorId="${authorId}"><text><t>${escapeXml(entry.text)}</t></text></comment>`);
1074
- }
1075
- p.push("</commentList></comments>");
1076
- return p.join("");
1077
- }
1078
- collectAuthors() {
1079
- const seen = /* @__PURE__ */ new Set();
1080
- const result = [];
1081
- for (const entry of this.entries) if (!seen.has(entry.author)) {
1082
- seen.add(entry.author);
1083
- result.push(entry.author);
1084
- }
1085
- return result.length > 0 ? result : [""];
1086
- }
1087
- };
1088
- //#endregion
1089
- //#region src/file/drawing/drawing.ts
1090
- /**
1091
- * XLSX Drawing component — generates xl/drawings/drawing{n}.xml.
1092
- *
1093
- * Uses the spreadsheetDrawing namespace (default, no prefix) for anchoring
1094
- * images and charts to worksheet cells.
1095
- *
1096
- * @module
1097
- */
1098
- const XDR_NS = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing";
1099
- const A_NS = "http://schemas.openxmlformats.org/drawingml/2006/main";
1100
- const R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
1101
- const C_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
1102
- var Drawing = class extends BaseXmlComponent {
1103
- images;
1104
- charts;
1105
- constructor(images, charts = []) {
1106
- super("wsDr");
1107
- this.images = images;
1108
- this.charts = charts;
1109
- }
1110
- toXml(_context) {
1111
- const p = [`<wsDr xmlns="${XDR_NS}" xmlns:a="${A_NS}" xmlns:r="${R_NS}">`];
1112
- let id = 1;
1113
- for (const img of this.images) {
1114
- 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>`);
1115
- id++;
1116
- }
1117
- for (const chart of this.charts) {
1118
- 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>`);
1119
- id++;
1120
- }
1121
- p.push("</wsDr>");
1122
- return p.join("");
1123
- }
1124
- };
1125
- //#endregion
1126
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
+ };
1127
2111
  /**
1128
2112
  * Extract unique values from source data for a given field index.
1129
2113
  */
@@ -1132,7 +2116,7 @@ function collectUniqueValues(records, fieldIdx) {
1132
2116
  const result = [];
1133
2117
  for (const row of records) {
1134
2118
  const val = row[fieldIdx];
1135
- const key = String(val);
2119
+ const key = val instanceof Date ? val.toISOString() : String(val);
1136
2120
  if (!seen.has(key)) {
1137
2121
  seen.add(key);
1138
2122
  result.push(val);
@@ -1194,17 +2178,75 @@ var PivotCacheDefinitionXml = class extends BaseXmlComponent {
1194
2178
  sourceSheet;
1195
2179
  sourceData;
1196
2180
  recordsRid;
1197
- constructor(_cacheIdx, sourceRef, sourceSheet, sourceData, recordsRid) {
2181
+ olapPr;
2182
+ cacheDefOpts;
2183
+ constructor(_cacheIdx, sourceRef, sourceSheet, sourceData, recordsRid, olapPr, cacheDefOpts) {
1198
2184
  super("pivotCacheDefinition");
1199
2185
  this.sourceRef = sourceRef;
1200
2186
  this.sourceSheet = sourceSheet;
1201
2187
  this.sourceData = sourceData;
1202
2188
  this.recordsRid = recordsRid;
2189
+ this.olapPr = olapPr;
2190
+ this.cacheDefOpts = cacheDefOpts;
1203
2191
  }
1204
2192
  toXml(_context) {
1205
2193
  const p = [];
1206
- 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">`);
1207
- 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>`);
1208
2250
  const fields = this.sourceData.fieldNames;
1209
2251
  p.push(`<cacheFields count="${fields.length}">`);
1210
2252
  for (let i = 0; i < fields.length; i++) {
@@ -1228,18 +2270,247 @@ var PivotCacheDefinitionXml = class extends BaseXmlComponent {
1228
2270
  const allInteger = this.sourceData.records.every((row) => typeof row[i] === "number" && Number.isInteger(row[i]));
1229
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>`);
1230
2272
  } else {
1231
- p.push(`<cacheField name="${escapeXml(fieldName)}" numFmtId="0"><sharedItems count="${uniqueVals.length}">`);
1232
- for (const v of uniqueVals) p.push(`<s v="${escapeXml(String(v))}"/>`);
1233
- 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>");
1234
2320
  }
1235
2321
  }
1236
2322
  p.push("</cacheFields>");
1237
- p.push("</pivotCacheDefinition>");
1238
- return p.join("");
1239
- }
1240
- };
1241
- //#endregion
1242
- //#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
1243
2514
  /**
1244
2515
  * PivotCacheRecords XML generator.
1245
2516
  *
@@ -1272,7 +2543,9 @@ var PivotCacheRecordsXml = class extends BaseXmlComponent {
1272
2543
  p.push("<r>");
1273
2544
  for (let i = 0; i < row.length; i++) {
1274
2545
  const val = row[i];
1275
- 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}"/>`);
1276
2549
  else {
1277
2550
  const idx = this.fieldIndexMaps[i].get(String(val)) ?? 0;
1278
2551
  p.push(`<x v="${idx}"/>`);
@@ -1316,7 +2589,9 @@ var PivotTableXml = class extends BaseXmlComponent {
1316
2589
  const rowFieldIndices = rowFieldNames.map((n) => fields.indexOf(n));
1317
2590
  const colFieldIndices = colFieldNames.map((n) => fields.indexOf(n));
1318
2591
  const dataFieldIndices = dataFields.map((df) => fields.indexOf(df.field));
1319
- 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);
1320
2595
  const rowFieldsXml = this.buildRowFields(rowFieldIndices);
1321
2596
  const rowItemsXml = this.buildRowItems(rowFieldIndices);
1322
2597
  const colFieldsXml = this.buildColFields(colFieldIndices);
@@ -1324,26 +2599,134 @@ var PivotTableXml = class extends BaseXmlComponent {
1324
2599
  const dataFieldsXml = this.buildDataFields(dataFields, dataFieldIndices);
1325
2600
  const locationRef = this.computeLocationRef(location, rowFieldIndices, colFieldIndices, dataFields);
1326
2601
  const p = [];
1327
- 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(" ")}>`);
1328
2667
  p.push(`<location ref="${escapeXml(locationRef)}" firstHeaderRow="1" firstDataRow="${colFieldIndices.length + 1}" firstDataCol="${rowFieldIndices.length}"/>`);
1329
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);
1330
2671
  p.push(rowFieldsXml);
1331
2672
  p.push(rowItemsXml);
1332
2673
  if (colFieldIndices.length > 0) p.push(colFieldsXml);
1333
2674
  p.push(colItemsXml);
1334
2675
  if (dataFields.length > 0) p.push(dataFieldsXml);
1335
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
+ }
1336
2701
  p.push("</pivotTableDefinition>");
1337
2702
  return p.join("");
1338
2703
  }
1339
- buildPivotFields(rowIndices, colIndices, dataIndices) {
2704
+ buildPivotFields(rowIndices, colIndices, dataIndices, pageIndices) {
1340
2705
  const fields = this.sourceData.fieldNames;
2706
+ const o = this.options;
1341
2707
  const parts = [`<pivotFields count="${fields.length}">`];
1342
2708
  for (let i = 0; i < fields.length; i++) {
1343
2709
  const isRow = rowIndices.includes(i);
1344
2710
  const isCol = colIndices.includes(i);
1345
- if (dataIndices.includes(i)) parts.push(`<pivotField dataField="1" showAll="0"/>`);
1346
- 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) {
1347
2730
  const uniqueVals = collectUniqueValues(this.sourceData.records, i);
1348
2731
  parts.push(`<pivotField axis="axisRow" showAll="0">`);
1349
2732
  parts.push(`<items count="${uniqueVals.length + 1}">`);
@@ -1357,11 +2740,25 @@ var PivotTableXml = class extends BaseXmlComponent {
1357
2740
  for (let j = 0; j < uniqueVals.length; j++) parts.push(`<item x="${j}"/>`);
1358
2741
  parts.push(`<item t="default"/>`);
1359
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>");
1360
2750
  } else parts.push(`<pivotField showAll="0"/>`);
1361
2751
  }
1362
2752
  parts.push("</pivotFields>");
1363
2753
  return parts.join("");
1364
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
+ }
1365
2762
  buildRowFields(rowIndices) {
1366
2763
  if (rowIndices.length === 0) return "<rowFields count=\"0\"/>";
1367
2764
  const parts = [`<rowFields count="${rowIndices.length}">`];
@@ -1428,8 +2825,15 @@ var PivotTableXml = class extends BaseXmlComponent {
1428
2825
  for (let i = 0; i < dataFields.length; i++) {
1429
2826
  const df = dataFields[i];
1430
2827
  const subtotal = df.summarize ?? "sum";
1431
- const name = df.name ?? `${subtotal === "sum" ? "Sum" : subtotal} of ${df.field}`;
1432
- 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(" ")}/>`);
1433
2837
  }
1434
2838
  parts.push("</dataFields>");
1435
2839
  return parts.join("");
@@ -1448,6 +2852,147 @@ var PivotTableXml = class extends BaseXmlComponent {
1448
2852
  colCount += 1;
1449
2853
  return `${startCol}${startRow}:${colIndexToLetter(letterToColIndex(startCol) + colCount - 1)}${startRow + rowCount - 1}`;
1450
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
+ }
1451
2996
  };
1452
2997
  function letterToColIndex(letters) {
1453
2998
  let col = 0;
@@ -1476,6 +3021,1158 @@ function cartesianOfCounts(counts) {
1476
3021
  return result;
1477
3022
  }
1478
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
1479
4176
  //#region src/file/vml-notes.ts
1480
4177
  var VmlNotes = class {
1481
4178
  comments;
@@ -1537,7 +4234,10 @@ var Compiler = class {
1537
4234
  let globalChartIdx = 0;
1538
4235
  let globalPivotIdx = 0;
1539
4236
  let globalPivotCacheIdx = 0;
4237
+ let globalTableIdx = 0;
1540
4238
  const pivotCacheDataMap = /* @__PURE__ */ new Map();
4239
+ const calcChain = new CalcChain();
4240
+ const allTableParts = [];
1541
4241
  for (let i = 0; i < worksheets.length; i++) {
1542
4242
  const ws = worksheets[i];
1543
4243
  const imgOpts = ws.imageOptions;
@@ -1545,15 +4245,35 @@ var Compiler = class {
1545
4245
  const hlOpts = ws.hyperlinkOptions;
1546
4246
  const sheetName = file.worksheetConfigs[i]?.name ?? `Sheet${i + 1}`;
1547
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
+ }
1548
4265
  const hasMedia = imgOpts.length > 0 || chartOpts.length > 0;
1549
4266
  const hasExternalHyperlinks = hlOpts.some((h) => h.target.type === "external");
1550
4267
  const commentOpts = ws.commentOptions;
1551
4268
  const hasComments = commentOpts.length > 0;
1552
4269
  const pivotOpts = ws.pivotTables;
1553
4270
  const hasPivots = pivotOpts.length > 0;
4271
+ const tableOpts = ws.tables;
4272
+ const hasTables = tableOpts.length > 0;
4273
+ const bgImg = ws.background;
1554
4274
  let wsRels;
1555
4275
  let nextRid = 0;
1556
- if (hasMedia || hasExternalHyperlinks || hasComments || hasPivots) wsRels = new Relationships();
4276
+ if (hasMedia || hasExternalHyperlinks || hasComments || hasPivots || hasTables || bgImg) wsRels = new Relationships();
1557
4277
  if (hasExternalHyperlinks) for (const hl of hlOpts) {
1558
4278
  if (hl.target.type !== "external") continue;
1559
4279
  const rid = ++nextRid;
@@ -1633,6 +4353,22 @@ var Compiler = class {
1633
4353
  file.contentTypes.addComments(commentsIdx);
1634
4354
  file.contentTypes.addVmlDrawing();
1635
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
+ }
1636
4372
  if (hasPivots) for (const pt of pivotOpts) {
1637
4373
  globalPivotIdx++;
1638
4374
  const pivotIdx = globalPivotIdx;
@@ -1693,6 +4429,24 @@ var Compiler = class {
1693
4429
  wsRels.addRelationship(ptRid, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable", `../pivotTables/pivotTable${pivotIdx}.xml`);
1694
4430
  file.contentTypes.addPivotTable(pivotIdx);
1695
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
+ }
1696
4450
  if (hasPivots) {
1697
4451
  const rendered = renderPivotSheetData(pivotOpts, worksheets, file.sharedStrings, file.worksheetConfigs, sheetName);
1698
4452
  if (rendered.sheetData.length > 0) {
@@ -1700,6 +4454,10 @@ var Compiler = class {
1700
4454
  if (!sheetXml.includes("<dimension")) sheetXml = sheetXml.replace("<sheetViews", `<dimension ref="${rendered.dimensionRef}"/><sheetViews`);
1701
4455
  }
1702
4456
  }
4457
+ if (wsTableParts.length > 0) {
4458
+ const tablePartsXml = WorkbookXml.buildTablePartsXml(wsTableParts);
4459
+ sheetXml = sheetXml.slice(0, -12) + tablePartsXml + "</worksheet>";
4460
+ }
1703
4461
  if (wsRels) mapping[`WorksheetRels${i}`] = {
1704
4462
  data: fmt(wsRels),
1705
4463
  path: `xl/worksheets/_rels/sheet${i + 1}.xml.rels`
@@ -1709,8 +4467,83 @@ var Compiler = class {
1709
4467
  path: `xl/worksheets/sheet${i + 1}.xml`
1710
4468
  };
1711
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-->", "");
1712
4545
  mapping["Workbook"] = {
1713
- data: fmt(file.workbookXml),
4546
+ data: workbookXml,
1714
4547
  path: "xl/workbook.xml"
1715
4548
  };
1716
4549
  mapping["WorkbookRelationships"] = {
@@ -1739,6 +4572,15 @@ var Compiler = class {
1739
4572
  };
1740
4573
  file.contentTypes.addChart(i + 1);
1741
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
+ }
1742
4584
  const imageExts = /* @__PURE__ */ new Set();
1743
4585
  for (const img of file.media.array) {
1744
4586
  const ext = img.fileName.endsWith(".png") ? "png" : "jpeg";
@@ -1777,7 +4619,10 @@ function extractPivotSourceData(rows, sourceRef) {
1777
4619
  const colCount = endCol - startCol + 1;
1778
4620
  const headerRow = rows[startRow];
1779
4621
  const fieldNames = [];
1780
- 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
+ }
1781
4626
  const records = [];
1782
4627
  for (let r = startRow + 1; r <= endRow; r++) {
1783
4628
  const row = rows[r];
@@ -1787,7 +4632,7 @@ function extractPivotSourceData(rows, sourceRef) {
1787
4632
  const val = row.cells[c]?.value;
1788
4633
  if (typeof val === "number") record.push(val);
1789
4634
  else if (val instanceof Date) record.push(val.getTime());
1790
- else record.push(String(val ?? ""));
4635
+ else record.push(typeof val === "string" ? val : typeof val === "boolean" ? String(val) : "");
1791
4636
  }
1792
4637
  if (record.length === colCount) records.push(record);
1793
4638
  }
@@ -1834,7 +4679,10 @@ function renderPivotSheetData(pivotOpts, worksheets, sharedStrings, worksheetCon
1834
4679
  let group = groupMap.get(groupKey);
1835
4680
  if (!group) {
1836
4681
  group = {
1837
- 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
+ }),
1838
4686
  values: dataFieldIndices.map(() => [])
1839
4687
  };
1840
4688
  groupMap.set(groupKey, group);
@@ -1927,6 +4775,16 @@ function colIndexToLetterCompiler(col) {
1927
4775
  }
1928
4776
  return result;
1929
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
+ }
1930
4788
  //#endregion
1931
4789
  //#region src/export/packer/packer.ts
1932
4790
  /**
@@ -2311,6 +5169,6 @@ function findLocalChild(parent, name) {
2311
5169
  return (parent.elements ?? []).find((el) => localName(el) === name);
2312
5170
  }
2313
5171
  //#endregion
2314
- 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 };
2315
5173
 
2316
5174
  //# sourceMappingURL=index.mjs.map