@extend-ai/react-xlsx 0.17.0 → 0.17.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.
@@ -3003,9 +3003,6 @@ function loadWorkbookChartAssets(workbook2, imageAssets, visibleSheetIndexByWork
3003
3003
  };
3004
3004
  }
3005
3005
 
3006
- // src/images.ts
3007
- import { strFromU8 as strFromU82, strToU8 as strToU82, unzipSync, zipSync } from "fflate";
3008
-
3009
3006
  // src/colors.ts
3010
3007
  function normalizeHexColor2(value) {
3011
3008
  const hex = value.replace(/^#/, "");
@@ -3101,6 +3098,16 @@ function applyExcelTint(baseColor, tint) {
3101
3098
  const [nextRed, nextGreen, nextBlue] = hslToRgb2(hue, saturation, Math.max(0, Math.min(1, nextLightness)));
3102
3099
  return rgbToHex2(nextRed, nextGreen, nextBlue);
3103
3100
  }
3101
+ function buildThemePaletteFromHex(hexColors) {
3102
+ const colorsByIndex = {};
3103
+ hexColors.forEach((hex, index) => {
3104
+ const color = normalizeHexColor2(hex);
3105
+ if (color) {
3106
+ colorsByIndex[index] = color;
3107
+ }
3108
+ });
3109
+ return { colorsByIndex };
3110
+ }
3104
3111
  function resolveWorkbookColor(color, themePalette) {
3105
3112
  if (!color) {
3106
3113
  return null;
@@ -3109,7 +3116,7 @@ function resolveWorkbookColor(color, themePalette) {
3109
3116
  if (directHex) {
3110
3117
  return normalizeHexColor2(directHex);
3111
3118
  }
3112
- const themeValue = color.theme;
3119
+ const themeValue = color.theme ?? color.themeIndex;
3113
3120
  const numericTheme = typeof themeValue === "number" ? themeValue : typeof themeValue === "string" && themeValue.trim().length > 0 ? Number(themeValue) : Number.NaN;
3114
3121
  const themeColor = Number.isFinite(numericTheme) ? themePalette?.colorsByIndex[numericTheme] ?? null : null;
3115
3122
  if (!themeColor) {
@@ -3121,6 +3128,7 @@ function resolveWorkbookColor(color, themePalette) {
3121
3128
  }
3122
3129
 
3123
3130
  // src/images.ts
3131
+ import { strFromU8 as strFromU82, strToU8 as strToU82, unzipSync, zipSync } from "fflate";
3124
3132
  var REL_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
3125
3133
  var SPREADSHEET_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
3126
3134
  var DRAWING_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing";
@@ -3596,6 +3604,12 @@ function parseSpreadsheetFont(node) {
3596
3604
  return void 0;
3597
3605
  }
3598
3606
  const font = {};
3607
+ for (const [tag, property] of [["b", "bold"], ["i", "italic"], ["strike", "strikethrough"]]) {
3608
+ const flag = getFirstChild(node, tag);
3609
+ if (flag) {
3610
+ font[property] = hasEnabledSpreadsheetFlag(flag);
3611
+ }
3612
+ }
3599
3613
  const size = getFirstChild(node, "sz")?.getAttribute("val");
3600
3614
  const name = getFirstChild(node, "name")?.getAttribute("val");
3601
3615
  const family = getFirstChild(node, "family")?.getAttribute("val");
@@ -3603,15 +3617,6 @@ function parseSpreadsheetFont(node) {
3603
3617
  const charset = getFirstChild(node, "charset")?.getAttribute("val");
3604
3618
  const verticalAlign = getFirstChild(node, "vertAlign")?.getAttribute("val");
3605
3619
  const color = parseSpreadsheetColor(getFirstChild(node, "color"));
3606
- if (hasEnabledSpreadsheetFlag(getFirstChild(node, "b"))) {
3607
- font.bold = true;
3608
- }
3609
- if (hasEnabledSpreadsheetFlag(getFirstChild(node, "i"))) {
3610
- font.italic = true;
3611
- }
3612
- if (hasEnabledSpreadsheetFlag(getFirstChild(node, "strike"))) {
3613
- font.strikethrough = true;
3614
- }
3615
3620
  if (getFirstChild(node, "u")) {
3616
3621
  font.underline = getFirstChild(node, "u")?.getAttribute("val") ?? "single";
3617
3622
  }
@@ -3860,7 +3865,14 @@ function parseWorkbookStyles(archive) {
3860
3865
  const styleById = {};
3861
3866
  const tableStyleByName = {};
3862
3867
  getChildElements(cellXfsNode, "xf").forEach((xfNode, index) => {
3863
- styleById[index] = parseResolvedXfStyle(xfNode, fonts, fills, borders, checkboxComplementIndices);
3868
+ const style = parseResolvedXfStyle(xfNode, fonts, fills, borders, checkboxComplementIndices);
3869
+ const overrides = {};
3870
+ for (const component of ["font", "fill", "border"]) {
3871
+ if (Number(xfNode.getAttribute(`${component}Id`) ?? 0) > 0 && xfNode.getAttribute(`apply${component[0].toUpperCase()}${component.slice(1)}`) !== "0") {
3872
+ Object.assign(overrides, { [component]: style[component] });
3873
+ }
3874
+ }
3875
+ styleById[index] = { ...style, tableStyleOverrides: overrides };
3864
3876
  });
3865
3877
  getChildElements(cellStylesNode ?? document2.documentElement, "cellStyle").forEach((cellStyleNode) => {
3866
3878
  const name = cellStyleNode.getAttribute("name");
@@ -4204,6 +4216,7 @@ function parseSheetState(archive, path, options) {
4204
4216
  const rowHeightOverridesPx = {};
4205
4217
  const colWidthOverridesPx = {};
4206
4218
  const rowStyleIds = {};
4219
+ const cellStyleIds = {};
4207
4220
  const colStyleIds = {};
4208
4221
  let minContentCol = Number.POSITIVE_INFINITY;
4209
4222
  let minContentRow = Number.POSITIVE_INFINITY;
@@ -4253,6 +4266,10 @@ function parseSheetState(archive, path, options) {
4253
4266
  }
4254
4267
  getChildElements(rowNode, "c").forEach((cellNode) => {
4255
4268
  const cellRef = cellNode.getAttribute("r");
4269
+ const cellStyleId = Number(cellNode.getAttribute("s") ?? Number.NaN);
4270
+ if (cellRef && Number.isFinite(cellStyleId)) {
4271
+ cellStyleIds[cellRef] = cellStyleId;
4272
+ }
4256
4273
  if (isMeaningfulCellNode(cellNode)) {
4257
4274
  trackContentCell(cellRef);
4258
4275
  }
@@ -4291,6 +4308,7 @@ function parseSheetState(archive, path, options) {
4291
4308
  return {
4292
4309
  autoFilterRanges,
4293
4310
  cachedFormulaValues,
4311
+ cellStyleIds,
4294
4312
  columnWidthCharacterWidthPx,
4295
4313
  colWidthOverridesPx,
4296
4314
  colStyleIds,
@@ -4672,13 +4690,52 @@ function hasUnresolvedSheetReferences(workbook2) {
4672
4690
  }
4673
4691
  return false;
4674
4692
  }
4693
+ function collectFormulaCellsWithSavedValues(workbook2) {
4694
+ const positions = [];
4695
+ for (let sheetIdx = 0; sheetIdx < workbook2.sheetCount; sheetIdx += 1) {
4696
+ let sheet;
4697
+ try {
4698
+ sheet = workbook2.getSheet(sheetIdx);
4699
+ } catch {
4700
+ continue;
4701
+ }
4702
+ const cells = sheet.formulaCells;
4703
+ if (!Array.isArray(cells)) {
4704
+ continue;
4705
+ }
4706
+ for (const cell of cells) {
4707
+ if (typeof cell?.row !== "number" || typeof cell?.col !== "number") {
4708
+ continue;
4709
+ }
4710
+ let saved;
4711
+ try {
4712
+ saved = sheet.getCalculatedValueAt(cell.row, cell.col);
4713
+ } catch {
4714
+ continue;
4715
+ }
4716
+ if (!saved.is_empty && !saved.is_error) {
4717
+ positions.push({ sheetIdx, row: cell.row, col: cell.col });
4718
+ }
4719
+ }
4720
+ }
4721
+ return positions;
4722
+ }
4723
+ function anyBecameError(workbook2, positions) {
4724
+ return positions.some(({ sheetIdx, row, col }) => {
4725
+ try {
4726
+ return workbook2.getSheet(sheetIdx).getCalculatedValueAt(row, col).is_error;
4727
+ } catch {
4728
+ return false;
4729
+ }
4730
+ });
4731
+ }
4675
4732
  function safeCalculate(workbook2, options = {}) {
4676
4733
  if (hasUnresolvedSheetReferences(workbook2)) {
4677
4734
  return { workbook: workbook2, calculated: false, skipReason: "unresolved-sheet-refs" };
4678
4735
  }
4736
+ const withSavedValues = options.reparse ? collectFormulaCellsWithSavedValues(workbook2) : [];
4679
4737
  try {
4680
4738
  workbook2.calculate();
4681
- return { workbook: workbook2, calculated: true, skipReason: null };
4682
4739
  } catch (err) {
4683
4740
  console.warn("[react-xlsx] workbook.calculate() trapped; falling back to cached formula values", err);
4684
4741
  if (options.reparse) {
@@ -4690,6 +4747,14 @@ function safeCalculate(workbook2, options = {}) {
4690
4747
  }
4691
4748
  return { workbook: workbook2, calculated: false, skipReason: "calculate-trapped" };
4692
4749
  }
4750
+ if (options.reparse && anyBecameError(workbook2, withSavedValues)) {
4751
+ try {
4752
+ return { workbook: options.reparse(), calculated: false, skipReason: "calculate-regressed" };
4753
+ } catch (reparseErr) {
4754
+ console.warn("[react-xlsx] workbook reparse after calculate regression failed", reparseErr);
4755
+ }
4756
+ }
4757
+ return { workbook: workbook2, calculated: true, skipReason: null };
4693
4758
  }
4694
4759
 
4695
4760
  // src/wasm.ts
@@ -5012,7 +5077,7 @@ function resolveSheetDisplayUsedRange(usedRange, sheetState) {
5012
5077
  maxMeaningfulCol >= 0 ? maxContentCol >= 0 ? Math.min(maxCol, maxMeaningfulCol) : Math.max(maxCol, maxMeaningfulCol) : maxCol
5013
5078
  ];
5014
5079
  }
5015
- function buildSheetList(nextWorkbook, structureAssets, sheetLayoutStates, showHiddenSheets = false) {
5080
+ function buildSheetList(nextWorkbook, themePalette, structureAssets, sheetLayoutStates, showHiddenSheets = false) {
5016
5081
  const sheetsByWorkbookSheetIndex = [];
5017
5082
  for (let index = 0; index < nextWorkbook.sheetCount; index += 1) {
5018
5083
  const worksheet = nextWorkbook.getSheet(index);
@@ -5082,11 +5147,12 @@ function buildSheetList(nextWorkbook, structureAssets, sheetLayoutStates, showHi
5082
5147
  rowHeightOverridesPx: sheetState?.rowHeightOverridesPx ?? {},
5083
5148
  rowHeights: [],
5084
5149
  rowStyleIds: sheetState?.rowStyleIds ?? {},
5150
+ cellStyleIds: sheetState?.cellStyleIds ?? {},
5085
5151
  showGridLines: sheetState?.showGridLines ?? true,
5086
5152
  sparklines: sheetState?.sparklines ?? [],
5087
5153
  styleById: structureAssets?.styleById ?? {},
5088
5154
  tableStyleByName: structureAssets?.tableStyleByName ?? {},
5089
- themePalette: structureAssets?.themePalette ?? { colorsByIndex: {} },
5155
+ themePalette,
5090
5156
  visibleCols: [],
5091
5157
  visibleRows: [],
5092
5158
  workbookSheetIndex: index,
@@ -5144,11 +5210,12 @@ function buildSheetList(nextWorkbook, structureAssets, sheetLayoutStates, showHi
5144
5210
  rowHeightOverridesPx: sheetState?.rowHeightOverridesPx ?? {},
5145
5211
  rowHeights: visibleRows.map(resolveRowHeightPx),
5146
5212
  rowStyleIds: sheetState?.rowStyleIds ?? {},
5213
+ cellStyleIds: sheetState?.cellStyleIds ?? {},
5147
5214
  showGridLines: sheetState?.showGridLines ?? true,
5148
5215
  sparklines: sheetState?.sparklines ?? [],
5149
5216
  styleById: structureAssets?.styleById ?? {},
5150
5217
  tableStyleByName: structureAssets?.tableStyleByName ?? {},
5151
- themePalette: structureAssets?.themePalette ?? { colorsByIndex: {} },
5218
+ themePalette,
5152
5219
  visibleCols,
5153
5220
  visibleRows,
5154
5221
  workbookSheetIndex: index,
@@ -5298,9 +5365,10 @@ async function loadWorkbook(buffer, skipXmlParsing = false, showHiddenSheets = f
5298
5365
  const structureAssets = effectiveSkipXmlParsing || shouldUseFastStructureParse || !canParseXmlInWorker() ? null : parseWorkbookStructureAssets(bytes, {
5299
5366
  includeCachedFormulaValues: true
5300
5367
  });
5368
+ const themePalette = structureAssets?.themePalette ?? buildThemePaletteFromHex(nextWorkbook.themePalette);
5301
5369
  formControlsByWorkbookSheetIndex = collectWorkbookFormControls(
5302
5370
  nextWorkbook,
5303
- structureAssets?.themePalette
5371
+ themePalette
5304
5372
  ).map(
5305
5373
  (controls, workbookSheetIndex) => controls.map((control) => ({
5306
5374
  ...control,
@@ -5309,7 +5377,7 @@ async function loadWorkbook(buffer, skipXmlParsing = false, showHiddenSheets = f
5309
5377
  );
5310
5378
  const sheetLayoutStates = structureAssets ? void 0 : parseWorkerSheetLayoutAssets(bytes, nextWorkbook.sheetCount);
5311
5379
  workbook = nextWorkbook;
5312
- sheets = buildSheetList(nextWorkbook, structureAssets, sheetLayoutStates, showHiddenSheets);
5380
+ sheets = buildSheetList(nextWorkbook, themePalette, structureAssets, sheetLayoutStates, showHiddenSheets);
5313
5381
  tablesByWorkbookSheetIndex = Array.from(
5314
5382
  { length: nextWorkbook.sheetCount },
5315
5383
  (_, workbookSheetIndex) => mapWorksheetTables(