@office-open/xlsx 0.12.0 → 0.12.2

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
@@ -2,7 +2,7 @@ import { ChartCollection, IMAGE_MEDIA_CONTENT_TYPES, Media, OoxmlMimeType, Relat
2
2
  import { OOXML_XML_DECLARATION, attr, attrMeasure, attrNum, attrs, children, escapeXml, findChild, selfCloseElement, stringify, stringifyElement, textOf, unescapeXml } from "@office-open/xml";
3
3
  import { blipDesc, buildHyperlinkElement, connectorLockingDesc, createSourceRectangle, graphicFrameLockingDesc, groupShapePropertiesDesc, parseEndpointConnection, parseNonVisualDrawingProperties, pictureLockingDesc, readHyperlink, registerHyperlink, shapeLockingDesc, shapePropertiesDesc, sourceRectangleDesc, stringifyBlipEffects, stringifyEndpointConnection, stringifyNonVisualDrawingProperties, textBodyDesc } from "@office-open/core/drawing";
4
4
  import { buildThemeXml, createThemeXml, createThemeXml as createThemeXml$1, parseShapeStyle, stringifyShapeStyle, themeDesc } from "@office-open/core/theme";
5
- import { chartSpaceDesc } from "@office-open/core/chart";
5
+ import { buildUserShapesData, chartSpaceDesc, userShapesDesc } from "@office-open/core/chart";
6
6
  //#region src/parts/styles/parse.ts
7
7
  /**
8
8
  * Styles — parse helpers for xl/styles.xml sub-elements.
@@ -2917,6 +2917,18 @@ function letterToColumn(letters) {
2917
2917
  for (let i = 0; i < letters.length; i++) col = col * 26 + (letters.charCodeAt(i) - 64);
2918
2918
  return col;
2919
2919
  }
2920
+ const A1_CELL = /^([A-Z]+)(\d+)$/;
2921
+ /**
2922
+ * Parse a single A1 cell reference ("B12") into 1-based column/row numbers.
2923
+ * Returns undefined when the reference is not letters-then-digits.
2924
+ */
2925
+ function parseA1Cell(ref) {
2926
+ const m = ref.match(A1_CELL);
2927
+ return m ? {
2928
+ col: letterToColumn(m[1]),
2929
+ row: parseInt(m[2], 10)
2930
+ } : void 0;
2931
+ }
2920
2932
  /**
2921
2933
  * Convert a JavaScript Date to an Excel serial number.
2922
2934
  * Excel epoch: January 1, 1900 = 1 (with the 1900 leap year bug).
@@ -3049,31 +3061,44 @@ function parseOlapPr(el) {
3049
3061
  if (String(attr(el, "serverFontColor")) === "0") ol.serverFontColor = false;
3050
3062
  return Object.keys(ol).length > 0 ? ol : void 0;
3051
3063
  }
3064
+ const profileCache = /* @__PURE__ */ new WeakMap();
3052
3065
  /**
3053
- * Extract unique values from source data for a given field index.
3066
+ * Profile every field of the source records in one pass numericity, unique
3067
+ * values, and numeric min/max/integer flags together. Memoized per source
3068
+ * object so the cache-definition and cache-records stringifiers share a
3069
+ * single scan instead of each re-walking the records per field.
3054
3070
  */
3055
- function collectUniqueValues(records, fieldIdx) {
3056
- const seen = /* @__PURE__ */ new Set();
3057
- const result = [];
3058
- for (const row of records) {
3059
- const val = row[fieldIdx];
3071
+ function profilePivotFields(sourceData) {
3072
+ const cached = profileCache.get(sourceData);
3073
+ if (cached !== void 0) return cached;
3074
+ const cols = sourceData.fieldNames.map(() => ({
3075
+ profile: {
3076
+ numeric: true,
3077
+ unique: [],
3078
+ min: Infinity,
3079
+ max: -Infinity,
3080
+ allInteger: true
3081
+ },
3082
+ seen: /* @__PURE__ */ new Set()
3083
+ }));
3084
+ for (const row of sourceData.records) for (let i = 0; i < cols.length; i++) {
3085
+ const col = cols[i];
3086
+ const val = row[i];
3087
+ if (typeof val === "string" && val !== "") col.profile.numeric = false;
3060
3088
  const key = val instanceof Date ? val.toISOString() : String(val);
3061
- if (!seen.has(key)) {
3062
- seen.add(key);
3063
- result.push(val ?? null);
3089
+ if (!col.seen.has(key)) {
3090
+ col.seen.add(key);
3091
+ col.profile.unique.push(val ?? null);
3064
3092
  }
3093
+ if (typeof val === "number") {
3094
+ if (val < col.profile.min) col.profile.min = val;
3095
+ if (val > col.profile.max) col.profile.max = val;
3096
+ if (!Number.isInteger(val)) col.profile.allInteger = false;
3097
+ } else col.profile.allInteger = false;
3065
3098
  }
3066
- return result;
3067
- }
3068
- /**
3069
- * Check if a field is numeric (all non-empty values are numbers).
3070
- */
3071
- function isNumericField(records, fieldIdx) {
3072
- for (const row of records) {
3073
- const val = row[fieldIdx];
3074
- if (typeof val === "string" && val !== "") return false;
3075
- }
3076
- return true;
3099
+ const profiles = cols.map((c) => c.profile);
3100
+ profileCache.set(sourceData, profiles);
3101
+ return profiles;
3077
3102
  }
3078
3103
  /**
3079
3104
  * Aggregate values using the specified function.
@@ -3326,6 +3351,7 @@ function buildFieldOverrideAttrs(fo) {
3326
3351
  }
3327
3352
  function buildPivotFields(o, sd, rowIndices, colIndices, dataIndices, pageIndices) {
3328
3353
  const fieldNames = sd.fieldNames;
3354
+ const profiles = profilePivotFields(sd);
3329
3355
  const parts = [`<pivotFields count="${fieldNames.length}">`];
3330
3356
  for (let i = 0; i < fieldNames.length; i++) {
3331
3357
  const isRow = rowIndices.includes(i);
@@ -3345,7 +3371,7 @@ function buildPivotFields(o, sd, rowIndices, colIndices, dataIndices, pageIndice
3345
3371
  if (o.autoSortScope) parts.push(`<pivotField ${dfAttrs.join(" ")}><autoSortScope>${buildPivotAreaXml(o.autoSortScope)}</autoSortScope></pivotField>`);
3346
3372
  else parts.push(`<pivotField ${dfAttrs.join(" ")}/>`);
3347
3373
  } else if (isRow) {
3348
- const uniqueVals = collectUniqueValues(sd.records, i);
3374
+ const uniqueVals = profiles[i].unique;
3349
3375
  const rAttrs = extraAttrs ? ` axis="axisRow" showAll="0" ${extraAttrs}` : " axis=\"axisRow\" showAll=\"0\"";
3350
3376
  parts.push(`<pivotField${rAttrs}>`);
3351
3377
  parts.push(`<items count="${uniqueVals.length + 1}">`);
@@ -3353,7 +3379,7 @@ function buildPivotFields(o, sd, rowIndices, colIndices, dataIndices, pageIndice
3353
3379
  parts.push(`<item t="default"${override?.defaultItemSd === false ? " sd=\"0\"" : ""}/>`);
3354
3380
  parts.push("</items></pivotField>");
3355
3381
  } else if (isCol) {
3356
- const uniqueVals = collectUniqueValues(sd.records, i);
3382
+ const uniqueVals = profiles[i].unique;
3357
3383
  const cAttrs = extraAttrs ? ` axis="axisCol" showAll="0" ${extraAttrs}` : " axis=\"axisCol\" showAll=\"0\"";
3358
3384
  parts.push(`<pivotField${cAttrs}>`);
3359
3385
  parts.push(`<items count="${uniqueVals.length + 1}">`);
@@ -3361,7 +3387,7 @@ function buildPivotFields(o, sd, rowIndices, colIndices, dataIndices, pageIndice
3361
3387
  parts.push(`<item t="default"${override?.defaultItemSd === false ? " sd=\"0\"" : ""}/>`);
3362
3388
  parts.push("</items></pivotField>");
3363
3389
  } else if (isPage) {
3364
- const uniqueVals = collectUniqueValues(sd.records, i);
3390
+ const uniqueVals = profiles[i].unique;
3365
3391
  const pAttrs = extraAttrs ? ` axis="axisPage" showAll="0" ${extraAttrs}` : " axis=\"axisPage\" showAll=\"0\"";
3366
3392
  parts.push(`<pivotField${pAttrs}>`);
3367
3393
  parts.push(`<items count="${uniqueVals.length + 1}">`);
@@ -3397,10 +3423,16 @@ function buildRowFields(rowIndices) {
3397
3423
  parts.push("</rowFields>");
3398
3424
  return parts.join("");
3399
3425
  }
3426
+ /** Unique-value count of field `idx`; an out-of-range index (an indexOf miss,
3427
+ * -1) keeps collectUniqueValues' behavior of a single null value. */
3428
+ function uniqueCount(profiles, idx) {
3429
+ return profiles[idx]?.unique.length ?? 1;
3430
+ }
3400
3431
  function buildRowItems(sd, rowIndices) {
3401
3432
  if (rowIndices.length === 0) return "<rowItems count=\"1\"><i/></rowItems>";
3433
+ const profiles = profilePivotFields(sd);
3402
3434
  const allUniqueCounts = [];
3403
- for (const idx of rowIndices) allUniqueCounts.push(collectUniqueValues(sd.records, idx).length);
3435
+ for (const idx of rowIndices) allUniqueCounts.push(uniqueCount(profiles, idx));
3404
3436
  if (rowIndices.length === 1) {
3405
3437
  const count = allUniqueCounts[0] ?? 0;
3406
3438
  const parts = [`<rowItems count="${count + 1}">`];
@@ -3424,8 +3456,9 @@ function buildColFields(colIndices) {
3424
3456
  }
3425
3457
  function buildColItems(sd, colIndices, dataFields) {
3426
3458
  if (colIndices.length > 0) {
3459
+ const profiles = profilePivotFields(sd);
3427
3460
  const allUniqueCounts = [];
3428
- for (const idx of colIndices) allUniqueCounts.push(collectUniqueValues(sd.records, idx).length);
3461
+ for (const idx of colIndices) allUniqueCounts.push(uniqueCount(profiles, idx));
3429
3462
  const combos = cartesianOfCounts(allUniqueCounts);
3430
3463
  const items = [];
3431
3464
  for (const combo of combos) items.push(`<i>${combo.map((v) => `<x v="${v}"/>`).join("")}</i>`);
@@ -3458,20 +3491,20 @@ function buildDataFields(dataFields, dataFieldIndices) {
3458
3491
  return parts.join("");
3459
3492
  }
3460
3493
  function computeLocationRef(sd, location, rowFieldIndices, colFieldIndices, dataFields) {
3461
- const match = (location.split(":")[0] ?? location).match(/^([A-Z]+)(\d+)$/);
3462
- if (!match) return location;
3463
- const startCol = match[1] ?? "";
3464
- const startRow = parseInt(match[2] ?? "0", 10);
3494
+ const startCell = location.split(":")[0] ?? location;
3495
+ const start = parseA1Cell(startCell);
3496
+ if (!start) return location;
3497
+ const profiles = profilePivotFields(sd);
3465
3498
  let rowCount = 1;
3466
3499
  const rowFieldIndex0 = rowFieldIndices[0];
3467
- if (rowFieldIndex0 !== void 0) rowCount += collectUniqueValues(sd.records, rowFieldIndex0).length;
3500
+ if (rowFieldIndex0 !== void 0) rowCount += uniqueCount(profiles, rowFieldIndex0);
3468
3501
  rowCount += 1;
3469
3502
  let colCount = Math.max(rowFieldIndices.length, 1);
3470
3503
  const colFieldIndex0 = colFieldIndices[0];
3471
- if (colFieldIndex0 !== void 0) colCount += collectUniqueValues(sd.records, colFieldIndex0).length;
3504
+ if (colFieldIndex0 !== void 0) colCount += uniqueCount(profiles, colFieldIndex0);
3472
3505
  else if (dataFields.length > 1) colCount += dataFields.length - 1;
3473
3506
  colCount += 1;
3474
- return `${startCol}${startRow}:${columnToLetter(letterToColumn(startCol) + colCount - 1)}${startRow + rowCount - 1}`;
3507
+ return `${startCell}:${columnToLetter(start.col + colCount - 1)}${start.row + rowCount - 1}`;
3475
3508
  }
3476
3509
  function buildPivotHierarchies(hierarchies) {
3477
3510
  const parts = [`<pivotHierarchies count="${hierarchies.length}">`];
@@ -3565,6 +3598,22 @@ function cartesianOfCounts(counts) {
3565
3598
  *
3566
3599
  * @module
3567
3600
  */
3601
+ /** CT_Break list under rowBreaks/colBreaks — identical shape, only the tag differs. */
3602
+ function breaksXml(tag, list) {
3603
+ let manualCount = 0;
3604
+ const brkParts = list.map((b) => {
3605
+ const bAttrs = { id: b.id };
3606
+ if (b.min !== void 0) bAttrs.min = b.min;
3607
+ if (b.max !== void 0) bAttrs.max = b.max;
3608
+ if (b.manual) {
3609
+ bAttrs.man = 1;
3610
+ manualCount++;
3611
+ }
3612
+ if (b.pivot) bAttrs.pt = 1;
3613
+ return `<brk${attrs(bAttrs)}/>`;
3614
+ });
3615
+ return `<${tag} count="${list.length}" manualBreakCount="${manualCount}">${brkParts.join("")}</${tag}>`;
3616
+ }
3568
3617
  /**
3569
3618
  * Build the complete worksheet XML string.
3570
3619
  *
@@ -3718,9 +3767,10 @@ function stringifyWorksheet(opts, ctx) {
3718
3767
  prAttrs.saltValue = pr.saltValue ?? prDerived?.saltValue;
3719
3768
  if (pr.spinCount !== void 0) prAttrs.spinCount = pr.spinCount;
3720
3769
  else if (prDerived) prAttrs.spinCount = prDerived.spinCount;
3721
- if (pr.securityDescriptor) prAttrs.securityDescriptor = pr.securityDescriptor;
3722
- if (!!pr.securityDescriptor) prParts.push(`<protectedRange${attrs(prAttrs)}><securityDescriptor>${escapeXml(pr.securityDescriptor)}</securityDescriptor></protectedRange>`);
3723
- else prParts.push(selfCloseElement("protectedRange", attrs(prAttrs)));
3770
+ if (pr.securityDescriptor) {
3771
+ prAttrs.securityDescriptor = pr.securityDescriptor;
3772
+ prParts.push(`<protectedRange${attrs(prAttrs)}><securityDescriptor>${escapeXml(pr.securityDescriptor)}</securityDescriptor></protectedRange>`);
3773
+ } else prParts.push(selfCloseElement("protectedRange", attrs(prAttrs)));
3724
3774
  }
3725
3775
  prParts.push("</protectedRanges>");
3726
3776
  p.push(prParts.join(""));
@@ -3919,36 +3969,8 @@ function stringifyWorksheet(opts, ctx) {
3919
3969
  const hfXml = stringifyHeaderFooterXml(opts.headerFooter);
3920
3970
  if (hfXml) p.push(hfXml);
3921
3971
  }
3922
- if (rowBreaks.length > 0) {
3923
- let manualCount = 0;
3924
- const brkParts = rowBreaks.map((b) => {
3925
- const bAttrs = { id: b.id };
3926
- if (b.min !== void 0) bAttrs.min = b.min;
3927
- if (b.max !== void 0) bAttrs.max = b.max;
3928
- if (b.manual) {
3929
- bAttrs.man = 1;
3930
- manualCount++;
3931
- }
3932
- if (b.pivot) bAttrs.pt = 1;
3933
- return `<brk${attrs(bAttrs)}/>`;
3934
- });
3935
- p.push(`<rowBreaks count="${rowBreaks.length}" manualBreakCount="${manualCount}">${brkParts.join("")}</rowBreaks>`);
3936
- }
3937
- if (colBreaks.length > 0) {
3938
- let manualCount = 0;
3939
- const brkParts = colBreaks.map((b) => {
3940
- const bAttrs = { id: b.id };
3941
- if (b.min !== void 0) bAttrs.min = b.min;
3942
- if (b.max !== void 0) bAttrs.max = b.max;
3943
- if (b.manual) {
3944
- bAttrs.man = 1;
3945
- manualCount++;
3946
- }
3947
- if (b.pivot) bAttrs.pt = 1;
3948
- return `<brk${attrs(bAttrs)}/>`;
3949
- });
3950
- p.push(`<colBreaks count="${colBreaks.length}" manualBreakCount="${manualCount}">${brkParts.join("")}</colBreaks>`);
3951
- }
3972
+ if (rowBreaks.length > 0) p.push(breaksXml("rowBreaks", rowBreaks));
3973
+ if (colBreaks.length > 0) p.push(breaksXml("colBreaks", colBreaks));
3952
3974
  if (customProperties.length > 0) {
3953
3975
  const cpParts = ["<customProperties>"];
3954
3976
  for (const cp of customProperties) cpParts.push(`<customPr name="${escapeXml(cp.name)}" r:id="${escapeXml(cp.rId)}"/>`);
@@ -3999,25 +4021,27 @@ function stringifyWorksheet(opts, ctx) {
3999
4021
  if (opts.legacyDrawingHF) p.push(`<legacyDrawingHF r:id="${escapeXml(opts.legacyDrawingHF)}"/>`);
4000
4022
  if (opts.drawingHF) {
4001
4023
  const dhf = opts.drawingHF;
4002
- const dhfAttrs = { "r:id": dhf.rId };
4003
- if (dhf.lho !== void 0) dhfAttrs.lho = dhf.lho;
4004
- if (dhf.lhe !== void 0) dhfAttrs.lhe = dhf.lhe;
4005
- if (dhf.lhf !== void 0) dhfAttrs.lhf = dhf.lhf;
4006
- if (dhf.cho !== void 0) dhfAttrs.cho = dhf.cho;
4007
- if (dhf.che !== void 0) dhfAttrs.che = dhf.che;
4008
- if (dhf.chf !== void 0) dhfAttrs.chf = dhf.chf;
4009
- if (dhf.rho !== void 0) dhfAttrs.rho = dhf.rho;
4010
- if (dhf.rhe !== void 0) dhfAttrs.rhe = dhf.rhe;
4011
- if (dhf.rhf !== void 0) dhfAttrs.rhf = dhf.rhf;
4012
- if (dhf.lfo !== void 0) dhfAttrs.lfo = dhf.lfo;
4013
- if (dhf.lfe !== void 0) dhfAttrs.lfe = dhf.lfe;
4014
- if (dhf.lff !== void 0) dhfAttrs.lff = dhf.lff;
4015
- if (dhf.cfo !== void 0) dhfAttrs.cfo = dhf.cfo;
4016
- if (dhf.cfe !== void 0) dhfAttrs.cfe = dhf.cfe;
4017
- if (dhf.cff !== void 0) dhfAttrs.cff = dhf.cff;
4018
- if (dhf.rfo !== void 0) dhfAttrs.rfo = dhf.rfo;
4019
- if (dhf.rfe !== void 0) dhfAttrs.rfe = dhf.rfe;
4020
- if (dhf.rff !== void 0) dhfAttrs.rff = dhf.rff;
4024
+ const dhfAttrs = {
4025
+ "r:id": dhf.rId,
4026
+ lho: dhf.lho,
4027
+ lhe: dhf.lhe,
4028
+ lhf: dhf.lhf,
4029
+ cho: dhf.cho,
4030
+ che: dhf.che,
4031
+ chf: dhf.chf,
4032
+ rho: dhf.rho,
4033
+ rhe: dhf.rhe,
4034
+ rhf: dhf.rhf,
4035
+ lfo: dhf.lfo,
4036
+ lfe: dhf.lfe,
4037
+ lff: dhf.lff,
4038
+ cfo: dhf.cfo,
4039
+ cfe: dhf.cfe,
4040
+ cff: dhf.cff,
4041
+ rfo: dhf.rfo,
4042
+ rfe: dhf.rfe,
4043
+ rff: dhf.rff
4044
+ };
4021
4045
  p.push(selfCloseElement("drawingHF", attrs(dhfAttrs)));
4022
4046
  }
4023
4047
  if (opts.backgroundImage) p.push("<!--BACKGROUND_PICTURE-->");
@@ -4904,11 +4928,10 @@ function parseMarker(el) {
4904
4928
  };
4905
4929
  }
4906
4930
  function cellRefToVmlCoords(ref) {
4907
- let i = 0;
4908
- while (i < ref.length && ref.charCodeAt(i) >= 65 && ref.charCodeAt(i) <= 90) i++;
4931
+ const cell = parseA1Cell(ref);
4909
4932
  return {
4910
- col: letterToColumn(ref.slice(0, i)) - 1,
4911
- row: parseInt(ref.slice(i), 10) - 1
4933
+ col: (cell?.col ?? 1) - 1,
4934
+ row: (cell?.row ?? 1) - 1
4912
4935
  };
4913
4936
  }
4914
4937
  /** Parse rich text element into a plain string or rich runs. */
@@ -6940,25 +6963,18 @@ function stringifyPivotCacheDef(sourceRef, sourceSheet, sourceData, recordsRid,
6940
6963
  p.push(conParts.join(""));
6941
6964
  } else p.push(`<cacheSource type="worksheet"><worksheetSource ref="${escapeXml(sourceRef)}" sheet="${escapeXml(sourceSheet)}"/></cacheSource>`);
6942
6965
  const fieldNames = sourceData.fieldNames;
6966
+ const profiles = profilePivotFields(sourceData);
6943
6967
  p.push(`<cacheFields count="${fieldNames.length}">`);
6944
6968
  for (let i = 0; i < fieldNames.length; i++) {
6945
6969
  const fieldName = fieldNames[i] ?? "";
6946
- const numeric = isNumericField(sourceData.records, i);
6947
- const uniqueVals = collectUniqueValues(sourceData.records, i);
6970
+ const { numeric, unique: uniqueVals } = profiles[i];
6948
6971
  if (numeric) {
6949
- let min = Infinity, max = -Infinity;
6950
- for (const row of sourceData.records) {
6951
- const v = row[i];
6952
- if (typeof v === "number") {
6953
- if (v < min) min = v;
6954
- if (v > max) max = v;
6955
- }
6956
- }
6972
+ let min = profiles[i].min, max = profiles[i].max;
6957
6973
  if (!isFinite(min)) {
6958
6974
  min = 0;
6959
6975
  max = 0;
6960
6976
  }
6961
- const allInteger = sourceData.records.every((row) => typeof row[i] === "number" && Number.isInteger(row[i]));
6977
+ const allInteger = profiles[i].allInteger;
6962
6978
  const cfOverride = cacheDefOpts?.cacheFieldOverrides?.get(i);
6963
6979
  const cfExtraAttrs = [];
6964
6980
  const siExtraAttrs = [];
@@ -7233,12 +7249,11 @@ function stringifyPivotCacheDef(sourceRef, sourceSheet, sourceData, recordsRid,
7233
7249
  return p.join("");
7234
7250
  }
7235
7251
  function stringifyPivotCacheRecords(sourceData) {
7236
- const numericFields = sourceData.fieldNames.map((_, i) => isNumericField(sourceData.records, i));
7237
- const fieldIndexMaps = sourceData.fieldNames.map((_, i) => {
7238
- if (numericFields[i]) return /* @__PURE__ */ new Map();
7239
- const unique = collectUniqueValues(sourceData.records, i);
7252
+ const profiles = profilePivotFields(sourceData);
7253
+ const fieldIndexMaps = profiles.map((f) => {
7254
+ if (f.numeric) return /* @__PURE__ */ new Map();
7240
7255
  const map = /* @__PURE__ */ new Map();
7241
- for (let j = 0; j < unique.length; j++) map.set(String(unique[j]), j);
7256
+ for (let j = 0; j < f.unique.length; j++) map.set(String(f.unique[j]), j);
7242
7257
  return map;
7243
7258
  });
7244
7259
  const p = [];
@@ -7249,7 +7264,7 @@ function stringifyPivotCacheRecords(sourceData) {
7249
7264
  const val = row[i];
7250
7265
  if (val === null) p.push("<m/>");
7251
7266
  else if (val instanceof Date) p.push(`<d v="${val.toISOString().replace(/\.\d{3}Z$/, "Z")}"/>`);
7252
- else if (numericFields[i]) p.push(`<n v="${val}"/>`);
7267
+ else if (profiles[i].numeric) p.push(`<n v="${val}"/>`);
7253
7268
  else p.push(`<x v="${fieldIndexMaps[i]?.get(String(val)) ?? 0}"/>`);
7254
7269
  }
7255
7270
  p.push("</r>");
@@ -7266,6 +7281,16 @@ function stringifyPivotCacheRecords(sourceData) {
7266
7281
  *
7267
7282
  * @module
7268
7283
  */
7284
+ function tableRefWidth(ref) {
7285
+ const sep = ref.indexOf(":");
7286
+ const first = (sep === -1 ? ref : ref.slice(0, sep)).trim().toUpperCase();
7287
+ const last = sep === -1 ? first : ref.slice(sep + 1).trim().toUpperCase();
7288
+ const startCol = parseA1Cell(first)?.col;
7289
+ const endCol = parseA1Cell(last)?.col;
7290
+ if (startCol === void 0 || endCol === void 0) return void 0;
7291
+ const width = endCol - startCol + 1;
7292
+ return width >= 1 ? width : void 0;
7293
+ }
7269
7294
  const TotalsRowFunction = {
7270
7295
  NONE: "none",
7271
7296
  SUM: "sum",
@@ -7313,8 +7338,10 @@ const tableDesc = {
7313
7338
  if (o.totalsRowCellStyle) rootAttrs.totalsRowCellStyle = o.totalsRowCellStyle;
7314
7339
  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"${attrs(rootAttrs)}>`);
7315
7340
  if (o.autoFilter !== void 0) p.push(stringifyAutoFilter(o.autoFilter));
7316
- p.push(`<tableColumns count="${o.columns.length}">`);
7317
- for (const [i, col] of o.columns.entries()) {
7341
+ const width = tableRefWidth(o.ref);
7342
+ const columns = width !== void 0 && o.columns.length !== width ? o.columns.slice(0, width).concat(Array.from({ length: width - o.columns.length }, (_, i) => ({ name: `Column${o.columns.length + i + 1}` }))) : o.columns;
7343
+ p.push(`<tableColumns count="${columns.length}">`);
7344
+ for (const [i, col] of columns.entries()) {
7318
7345
  const colAttrs = {
7319
7346
  id: i + 1,
7320
7347
  name: col.name
@@ -9274,10 +9301,29 @@ var XlsxReadContext = class {
9274
9301
  *
9275
9302
  * @module
9276
9303
  */
9304
+ const LEADING_PATH_NUMBER = /(\d+)/;
9277
9305
  function sortByNumber(paths) {
9278
- return paths.sort((a, b) => {
9279
- return parseInt(a.match(/(\d+)/)?.[1] ?? "0", 10) - parseInt(b.match(/(\d+)/)?.[1] ?? "0", 10);
9280
- });
9306
+ return paths.map((p) => ({
9307
+ p,
9308
+ n: parseInt(p.match(LEADING_PATH_NUMBER)?.[1] ?? "0", 10)
9309
+ })).sort((a, b) => a.n - b.n).map(({ p }) => p);
9310
+ }
9311
+ /**
9312
+ * Fill a parsed chart's userShapes anchors from the companion part body —
9313
+ * chartSpaceDesc reads only the c:userShapes r:id; the body hangs off the
9314
+ * chart part's own rels (chartUserShapes relationship).
9315
+ */
9316
+ function readChartUserShapes(chartPath, chart, readContext, doc) {
9317
+ const rid = chart.userShapes?.relationshipId;
9318
+ if (rid === void 0 || chartPath === void 0) return;
9319
+ const rel = readContext.getWorksheetRelsByType(chartPath, "/chartUserShapes").find((r) => r.rId === rid);
9320
+ const bodyEl = rel ? doc.get(rel.target) : void 0;
9321
+ if (!bodyEl) return;
9322
+ const body = userShapesDesc.parse(bodyEl, readContext);
9323
+ chart.userShapes = {
9324
+ ...chart.userShapes,
9325
+ anchors: body.anchors
9326
+ };
9281
9327
  }
9282
9328
  /**
9283
9329
  * Worksheet parts read with sheetData deferred — the XML parser captures the
@@ -9309,7 +9355,7 @@ function parseXlsx(data) {
9309
9355
  }
9310
9356
  sortByNumber(worksheets);
9311
9357
  drawings.push(...doc.keys("xl/drawings/").filter((k) => k.endsWith(".xml")));
9312
- charts.push(...doc.keys("xl/charts/").filter((k) => k.endsWith(".xml")));
9358
+ charts.push(...doc.keys("xl/charts/").filter((k) => k.endsWith(".xml") && !/userShapes\d+\.xml$/.test(k)));
9313
9359
  media.push(...doc.keys("xl/media/"));
9314
9360
  sortByNumber(drawings);
9315
9361
  sortByNumber(charts);
@@ -9563,6 +9609,7 @@ function parseWorkbook(data) {
9563
9609
  const chartEl = chartPath ? xlsx.doc.get(chartPath) : void 0;
9564
9610
  if (!chartEl) continue;
9565
9611
  const chartSpace = chartSpaceDesc.parse(chartEl, readContext);
9612
+ readChartUserShapes(chartPath, chartSpace, readContext, xlsx.doc);
9566
9613
  const chartCnvPr = pickNonVisualDrawingProperties(anchor);
9567
9614
  delete chartCnvPr.title;
9568
9615
  charts.push({
@@ -9679,6 +9726,7 @@ function parseWorkbook(data) {
9679
9726
  const chartEl = chartPath ? xlsx.doc.get(chartPath) : void 0;
9680
9727
  if (!chartEl) continue;
9681
9728
  csData.chart = chartSpaceDesc.parse(chartEl, readContext);
9729
+ readChartUserShapes(chartPath, csData.chart, readContext, xlsx.doc);
9682
9730
  if (anchor.macro !== void 0) csData.macro = anchor.macro;
9683
9731
  if (anchor.frameLocks) csData.frameLocks = anchor.frameLocks;
9684
9732
  if (anchor.absoluteX !== void 0) csData.absoluteX = convertToEmu(anchor.absoluteX);
@@ -10132,7 +10180,7 @@ function rebuildSharedStrings(xmlMap) {
10132
10180
  /** Re-serialize the shared-strings part (called after worksheets are built). */
10133
10181
  function rewriteSharedStrings(xmlMap, ss) {
10134
10182
  if (ss.count === 0) return;
10135
- xmlMap.set("xl/sharedStrings.xml", toJson(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>${ss.serialize()}`));
10183
+ xmlMap.set("xl/sharedStrings.xml", toJson(OOXML_XML_DECLARATION + ss.serialize()));
10136
10184
  }
10137
10185
  /**
10138
10186
  * Append a worksheet: serialize it (registering strings into the shared-strings
@@ -10310,9 +10358,9 @@ function appendCommentsToMap(xmlMap, vmlFiles, sheetName, commentOpts) {
10310
10358
  let merged = commentOpts;
10311
10359
  if (existingPart) merged = [...commentsDesc.parse(existingPart, STUB_READ_CTX).comments, ...commentOpts];
10312
10360
  const commentsXml = commentsDesc.stringify({ comments: merged }, STUB_WRITE_CTX);
10313
- if (commentsXml) xmlMap.set(commentsPath, toJson(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>${commentsXml}`));
10361
+ if (commentsXml) xmlMap.set(commentsPath, toJson(OOXML_XML_DECLARATION + commentsXml));
10314
10362
  const vmlXml = vmlNotesDesc.stringify({ comments: merged }, STUB_WRITE_CTX);
10315
- if (vmlXml) vmlFiles.set(vmlPath, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>${vmlXml}`);
10363
+ if (vmlXml) vmlFiles.set(vmlPath, OOXML_XML_DECLARATION + vmlXml);
10316
10364
  if (!existingComments) {
10317
10365
  const n = getNextRelationshipIndex(wsRels);
10318
10366
  appendRelationship(wsRels, n, COMMENTS_REL_TYPE, `../comments${commentsN}.xml`);
@@ -10375,6 +10423,9 @@ function bindMediaPlaceholders(xml, media, rels) {
10375
10423
  /** XLSX part path → content type, derived from the part registry. Matches
10376
10424
  * actual file paths, so the dense/sequential xlsx part naming is handled. */
10377
10425
  const XLSX_CONTENT_TYPE_RESOLVER$1 = resolverFromRegistry(XLSX_PARTS);
10426
+ /** Chart part → user-shapes part relationship (c:userShapes bridge). */
10427
+ const CHART_USER_SHAPES_REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUserShapes";
10428
+ const PKG_REL_NS = "http://schemas.openxmlformats.org/package/2006/relationships";
10378
10429
  /** Extension → MIME for image and VML Default entries. Declared only for
10379
10430
  * extensions actually present in the package. VML backs legacy comment
10380
10431
  * anchors (xl/drawings/vmlDrawing${i}.vml). */
@@ -10571,18 +10622,20 @@ function compileWorkbook(options, overrides = [], mediaLevel = 0) {
10571
10622
  wbXml = wbXml.replace("<!--EXTERNAL_REFS-->", extRefsXml);
10572
10623
  } else wbXml = wbXml.replace("<!--EXTERNAL_REFS-->", "");
10573
10624
  mapping["Workbook"] = {
10574
- data: `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>${wbXml}`,
10625
+ data: XML_DECL + wbXml,
10575
10626
  path: "xl/workbook.xml"
10576
10627
  };
10577
10628
  if (ctx.sharedStrings.count > 0) {
10578
10629
  ctx.workbookRels.addRelationship(ctx.workbookRels.nextRelationshipId, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", "sharedStrings.xml");
10630
+ const ssXml = sharedStringsDesc.stringify(ctx.sharedStrings.toDescriptorOptions(), ctx);
10579
10631
  mapping["SharedStrings"] = {
10580
- data: `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>${sharedStringsDesc.stringify(ctx.sharedStrings.toDescriptorOptions(), ctx)}`,
10632
+ data: XML_DECL + ssXml,
10581
10633
  path: "xl/sharedStrings.xml"
10582
10634
  };
10583
10635
  }
10636
+ const stylesXml = stylesDesc.stringify({ styles: ctx.styles }, ctx);
10584
10637
  mapping["Styles"] = {
10585
- data: `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>${stylesDesc.stringify({ styles: ctx.styles }, ctx)}`,
10638
+ data: XML_DECL + stylesXml,
10586
10639
  path: "xl/styles.xml"
10587
10640
  };
10588
10641
  const themeRels = new Relationships();
@@ -10595,10 +10648,23 @@ function compileWorkbook(options, overrides = [], mediaLevel = 0) {
10595
10648
  data: XML_DECL + themeRels.serialize(),
10596
10649
  path: "xl/theme/_rels/theme1.xml.rels"
10597
10650
  };
10598
- for (const [i, chartData] of ctx.charts.array.entries()) mapping[`Chart${i}`] = {
10599
- data: XML_DECL + chartData.chartSpaceXml,
10600
- path: `xl/charts/chart${i + 1}.xml`
10601
- };
10651
+ for (const [i, chartData] of ctx.charts.array.entries()) {
10652
+ mapping[`Chart${i}`] = {
10653
+ data: XML_DECL + chartData.chartSpaceXml,
10654
+ path: `xl/charts/chart${i + 1}.xml`
10655
+ };
10656
+ if (chartData.userShapes) {
10657
+ const rid = chartData.userShapes.relationshipId;
10658
+ mapping[`ChartUserShapes${i}`] = {
10659
+ data: XML_DECL + chartData.userShapes.xml,
10660
+ path: `xl/charts/userShapes${i + 1}.xml`
10661
+ };
10662
+ mapping[`ChartRels${i}`] = {
10663
+ data: XML_DECL + `<Relationships xmlns="${PKG_REL_NS}"><Relationship Id="${escapeXml(rid)}" Type="${CHART_USER_SHAPES_REL}" Target="userShapes${i + 1}.xml"/></Relationships>`,
10664
+ path: `xl/charts/_rels/chart${i + 1}.xml.rels`
10665
+ };
10666
+ }
10667
+ }
10602
10668
  const calcChainCells = options.calcChain ?? state.calcCells;
10603
10669
  const srcReferencesCalcChain = (options.passthroughRelationships ?? []).some((r) => r.source === "xl/workbook.xml" && r.relationshipType.endsWith("/calcChain"));
10604
10670
  if (calcChainCells.length > 0 && !(srcReferencesCalcChain && options.calcChain === void 0)) {
@@ -10760,9 +10826,11 @@ function compileWorksheetPart(wsOpts, i, worksheetConfigs, ctx, mapping, wsConte
10760
10826
  }
10761
10827
  for (const chart of chartOpts) {
10762
10828
  const chartKey = `chart_${state.globalChartIdx}`;
10829
+ const userShapes = chart.userShapes ? buildUserShapesData(chart.userShapes) : void 0;
10763
10830
  ctx.charts.addChart(chartKey, {
10764
10831
  key: chartKey,
10765
- chartSpaceXml: chartSpaceDesc.stringify(chart, ctx) ?? ""
10832
+ chartSpaceXml: chartSpaceDesc.stringify(chart, ctx) ?? "",
10833
+ ...userShapes ? { userShapes } : {}
10766
10834
  });
10767
10835
  drawingRels.addRelationship(rid, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", `../charts/chart${state.globalChartIdx + 1}.xml`);
10768
10836
  const chartCnvPr = pickNonVisualDrawingProperties({
@@ -10829,7 +10897,7 @@ function compileWorksheetPart(wsOpts, i, worksheetConfigs, ctx, mapping, wsConte
10829
10897
  resolvedDrawingXml = bindMediaPlaceholders(resolvedDrawingXml, ctx.media, drawingRels);
10830
10898
  const drawingIdx = i + 1;
10831
10899
  mapping[`Drawing${i}`] = {
10832
- data: `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>${resolvedDrawingXml}`,
10900
+ data: XML_DECL + resolvedDrawingXml,
10833
10901
  path: `xl/drawings/drawing${drawingIdx}.xml`
10834
10902
  };
10835
10903
  mapping[`DrawingRels${i}`] = {
@@ -10844,12 +10912,12 @@ function compileWorksheetPart(wsOpts, i, worksheetConfigs, ctx, mapping, wsConte
10844
10912
  const commentsIdx = i + 1;
10845
10913
  const commentsXml = commentsDesc.stringify({ comments: commentOpts }, ctx);
10846
10914
  mapping[`Comments${i}`] = {
10847
- data: `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>${commentsXml}`,
10915
+ data: XML_DECL + commentsXml,
10848
10916
  path: `xl/comments${commentsIdx}.xml`
10849
10917
  };
10850
10918
  const vmlXml = vmlNotesDesc.stringify({ comments: commentOpts }, ctx);
10851
10919
  mapping[`VmlDrawing${i}`] = {
10852
- data: `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>${vmlXml}`,
10920
+ data: XML_DECL + vmlXml,
10853
10921
  path: `xl/drawings/vmlDrawing${commentsIdx}.vml`
10854
10922
  };
10855
10923
  const commentsRid = ++nextRid;
@@ -10922,7 +10990,7 @@ function compileWorksheetPart(wsOpts, i, worksheetConfigs, ctx, mapping, wsConte
10922
10990
  });
10923
10991
  const cacheDefRels = new Relationships();
10924
10992
  cacheDefRels.addRelationship(1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheRecords", "pivotCacheRecords1.xml");
10925
- const cacheDefXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + pivotCacheDefDesc.stringify({
10993
+ const cacheDefXml = XML_DECL + pivotCacheDefDesc.stringify({
10926
10994
  sourceRef: pt.source.split(":")[0] ? pt.source : "A1",
10927
10995
  sourceSheet,
10928
10996
  sourceData,
@@ -10936,7 +11004,7 @@ function compileWorksheetPart(wsOpts, i, worksheetConfigs, ctx, mapping, wsConte
10936
11004
  data: XML_DECL + cacheDefRels.serialize(),
10937
11005
  path: `xl/pivotCache/_rels/pivotCacheDefinition${cacheIdx}.xml.rels`
10938
11006
  };
10939
- const cacheRecordsXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + pivotCacheRecordsDesc.stringify({ sourceData }, ctx);
11007
+ const cacheRecordsXml = XML_DECL + pivotCacheRecordsDesc.stringify({ sourceData }, ctx);
10940
11008
  mapping[`PivotCacheRecords${cacheIdx}`] = {
10941
11009
  data: cacheRecordsXml,
10942
11010
  path: `xl/pivotCache/pivotCacheRecords${cacheIdx}.xml`
@@ -10971,7 +11039,7 @@ function compileWorksheetPart(wsOpts, i, worksheetConfigs, ctx, mapping, wsConte
10971
11039
  state.globalTableIdx++;
10972
11040
  const tableIdx = state.globalTableIdx;
10973
11041
  if (!tbl.columns?.length) continue;
10974
- const tableXmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + tableDesc.stringify({
11042
+ const tableXmlStr = XML_DECL + tableDesc.stringify({
10975
11043
  ...tbl,
10976
11044
  id: tbl.id ?? tableIdx
10977
11045
  }, ctx);
@@ -11048,9 +11116,11 @@ function compileChartsheets(chartsheetConfigs, ctx, mapping, passthroughRelation
11048
11116
  if (!chartDef) continue;
11049
11117
  const csChartGlobalIdx = ctx.charts.array.length;
11050
11118
  const csChartKey = `cs_chart_${csChartGlobalIdx}`;
11119
+ const csUserShapes = chartDef.userShapes ? buildUserShapesData(chartDef.userShapes) : void 0;
11051
11120
  ctx.charts.addChart(csChartKey, {
11052
11121
  key: csChartKey,
11053
- chartSpaceXml: chartSpaceDesc.stringify(chartDef, ctx) ?? ""
11122
+ chartSpaceXml: chartSpaceDesc.stringify(chartDef, ctx) ?? "",
11123
+ ...csUserShapes ? { userShapes: csUserShapes } : {}
11054
11124
  });
11055
11125
  const csRels = new Relationships();
11056
11126
  const csDrawingIdx = i + 1;
@@ -11166,16 +11236,16 @@ function hasMetadataContent(metadata) {
11166
11236
  }
11167
11237
  function extractPivotSourceData(rows, sourceRef) {
11168
11238
  const parts = sourceRef.split(":");
11169
- const startMatch = parts[0]?.match(/^([A-Z]+)(\d+)$/);
11170
- const endMatch = parts[1]?.match(/^([A-Z]+)(\d+)$/);
11171
- if (!startMatch) return {
11239
+ const start = parseA1Cell(parts[0] ?? "");
11240
+ if (!start) return {
11172
11241
  fieldNames: [],
11173
11242
  records: []
11174
11243
  };
11175
- const startRow = parseInt(startMatch[2] ?? "1", 10) - 1;
11176
- const endRow = endMatch ? parseInt(endMatch[2] ?? "1", 10) - 1 : startRow;
11177
- const startCol = letterToColumn(startMatch[1] ?? "A") - 1;
11178
- const endCol = endMatch ? letterToColumn(endMatch[1] ?? "A") - 1 : startCol;
11244
+ const end = parts[1] !== void 0 ? parseA1Cell(parts[1]) : void 0;
11245
+ const startRow = start.row - 1;
11246
+ const endRow = (end?.row ?? start.row) - 1;
11247
+ const startCol = start.col - 1;
11248
+ const endCol = (end?.col ?? start.col) - 1;
11179
11249
  const colCount = endCol - startCol + 1;
11180
11250
  const headerRow = rows[startRow];
11181
11251
  const fieldNames = [];
@@ -11213,10 +11283,10 @@ function renderPivotSheetData(pivotOpts, worksheetConfigs, sharedStrings, curren
11213
11283
  let minRow = Infinity;
11214
11284
  let minCol = Infinity;
11215
11285
  for (const pt of pivotOpts) {
11216
- const locMatch = (pt.location ?? "A3").match(/^([A-Z]+)(\d+)$/);
11217
- if (!locMatch) continue;
11218
- const startCol = letterToColumn(locMatch[1] ?? "A") - 1;
11219
- const startRow = parseInt(locMatch[2] ?? "1", 10);
11286
+ const loc = parseA1Cell(pt.location ?? "A3");
11287
+ if (!loc) continue;
11288
+ const startCol = loc.col - 1;
11289
+ const startRow = loc.row;
11220
11290
  const rowFieldNames = pt.rows;
11221
11291
  const dataFields = pt.data;
11222
11292
  const sourceWsIdx = findWorksheetIndex(worksheetConfigs, pt.sourceSheet ?? currentSheetName);
@@ -11259,7 +11329,7 @@ function renderPivotSheetData(pivotOpts, worksheetConfigs, sharedStrings, curren
11259
11329
  maxRow = Math.max(maxRow, rowIdx);
11260
11330
  };
11261
11331
  if (colFieldIndices.length > 0 && !colFieldIndices.some((idx) => idx === -1)) {
11262
- const colUniqueVals = collectUniqueValues(sourceData.records, colFieldIndices[0] ?? 0).map((v) => typeof v === "string" || typeof v === "number" ? String(v) : String(v ?? ""));
11332
+ const colUniqueVals = profilePivotFields(sourceData)[colFieldIndices[0] ?? 0].unique.map((v) => typeof v === "string" || typeof v === "number" ? String(v) : String(v ?? ""));
11263
11333
  const crossTabMap = /* @__PURE__ */ new Map();
11264
11334
  for (const record of sourceData.records) {
11265
11335
  const rowKey = rowFieldIndices.map((fi) => String(record[fi])).join("|");
@@ -11671,6 +11741,6 @@ function generateWorkbookStream(options, packerOptions) {
11671
11741
  } });
11672
11742
  }
11673
11743
  //#endregion
11674
- export { Media, PivotFilterType as PivotFilterTypeValue, SharedStrings, Styles, TableType, TotalsRowFunction, XlsxReadContext, XlsxWriteContext, buildExternalReferencesXml, buildTablePartsXml, stringifyWorksheet as buildWorksheetXml, stringifyWorksheet, calcChainDesc, chartsheetDesc, columnToLetter, commentsDesc, compileWorkbook, connectionsDesc, createThemeXml, dateToSerialNumber, dialogsheetDesc, drawingDesc, externalLinkDesc, generateWorkbook, generateWorkbookStream, generateWorkbookSync, hashPassword, letterToColumn, lintWorkbookFormulas, mapInfoDesc, metadataDesc, parseWorkbook, parseXlsx, patchWorkbook, pickAnchorOptions, pivotCacheDefDesc, pivotCacheRecordsDesc, pivotTableDesc, queryTableDesc, sharedStringsDesc, singleXmlCellsDesc, stylesDesc, tableDesc, vmlNotesDesc, workbookDesc, worksheetDesc };
11744
+ export { Media, PivotFilterType as PivotFilterTypeValue, SharedStrings, Styles, TableType, TotalsRowFunction, XlsxReadContext, XlsxWriteContext, buildExternalReferencesXml, buildTablePartsXml, stringifyWorksheet as buildWorksheetXml, stringifyWorksheet, calcChainDesc, chartsheetDesc, columnToLetter, commentsDesc, compileWorkbook, connectionsDesc, createThemeXml, dateToSerialNumber, dialogsheetDesc, drawingDesc, externalLinkDesc, generateWorkbook, generateWorkbookStream, generateWorkbookSync, hashPassword, letterToColumn, lintWorkbookFormulas, mapInfoDesc, metadataDesc, parseA1Cell, parseWorkbook, parseXlsx, patchWorkbook, pickAnchorOptions, pivotCacheDefDesc, pivotCacheRecordsDesc, pivotTableDesc, queryTableDesc, sharedStringsDesc, singleXmlCellsDesc, stylesDesc, tableDesc, vmlNotesDesc, workbookDesc, worksheetDesc };
11675
11745
 
11676
11746
  //# sourceMappingURL=index.mjs.map