@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.
- package/dist/index.cjs +141 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +141 -22
- package/dist/index.js.map +1 -1
- package/dist/xlsx-worker.js +88 -20
- package/dist/xlsx-worker.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -3632,7 +3632,7 @@ function resolveWorkbookColor(color, themePalette) {
|
|
|
3632
3632
|
if (directHex) {
|
|
3633
3633
|
return normalizeHexColor2(directHex);
|
|
3634
3634
|
}
|
|
3635
|
-
const themeValue = color.theme;
|
|
3635
|
+
const themeValue = color.theme ?? color.themeIndex;
|
|
3636
3636
|
const numericTheme = typeof themeValue === "number" ? themeValue : typeof themeValue === "string" && themeValue.trim().length > 0 ? Number(themeValue) : Number.NaN;
|
|
3637
3637
|
const themeColor = Number.isFinite(numericTheme) ? themePalette?.colorsByIndex[numericTheme] ?? null : null;
|
|
3638
3638
|
if (!themeColor) {
|
|
@@ -4260,6 +4260,12 @@ function parseSpreadsheetFont(node) {
|
|
|
4260
4260
|
return void 0;
|
|
4261
4261
|
}
|
|
4262
4262
|
const font = {};
|
|
4263
|
+
for (const [tag, property] of [["b", "bold"], ["i", "italic"], ["strike", "strikethrough"]]) {
|
|
4264
|
+
const flag = getFirstChild(node, tag);
|
|
4265
|
+
if (flag) {
|
|
4266
|
+
font[property] = hasEnabledSpreadsheetFlag(flag);
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4263
4269
|
const size = getFirstChild(node, "sz")?.getAttribute("val");
|
|
4264
4270
|
const name = getFirstChild(node, "name")?.getAttribute("val");
|
|
4265
4271
|
const family = getFirstChild(node, "family")?.getAttribute("val");
|
|
@@ -4267,15 +4273,6 @@ function parseSpreadsheetFont(node) {
|
|
|
4267
4273
|
const charset = getFirstChild(node, "charset")?.getAttribute("val");
|
|
4268
4274
|
const verticalAlign = getFirstChild(node, "vertAlign")?.getAttribute("val");
|
|
4269
4275
|
const color = parseSpreadsheetColor(getFirstChild(node, "color"));
|
|
4270
|
-
if (hasEnabledSpreadsheetFlag(getFirstChild(node, "b"))) {
|
|
4271
|
-
font.bold = true;
|
|
4272
|
-
}
|
|
4273
|
-
if (hasEnabledSpreadsheetFlag(getFirstChild(node, "i"))) {
|
|
4274
|
-
font.italic = true;
|
|
4275
|
-
}
|
|
4276
|
-
if (hasEnabledSpreadsheetFlag(getFirstChild(node, "strike"))) {
|
|
4277
|
-
font.strikethrough = true;
|
|
4278
|
-
}
|
|
4279
4276
|
if (getFirstChild(node, "u")) {
|
|
4280
4277
|
font.underline = getFirstChild(node, "u")?.getAttribute("val") ?? "single";
|
|
4281
4278
|
}
|
|
@@ -4524,7 +4521,14 @@ function parseWorkbookStyles(archive) {
|
|
|
4524
4521
|
const styleById = {};
|
|
4525
4522
|
const tableStyleByName = {};
|
|
4526
4523
|
getChildElements(cellXfsNode, "xf").forEach((xfNode, index) => {
|
|
4527
|
-
|
|
4524
|
+
const style = parseResolvedXfStyle(xfNode, fonts, fills, borders, checkboxComplementIndices);
|
|
4525
|
+
const overrides = {};
|
|
4526
|
+
for (const component of ["font", "fill", "border"]) {
|
|
4527
|
+
if (Number(xfNode.getAttribute(`${component}Id`) ?? 0) > 0 && xfNode.getAttribute(`apply${component[0].toUpperCase()}${component.slice(1)}`) !== "0") {
|
|
4528
|
+
Object.assign(overrides, { [component]: style[component] });
|
|
4529
|
+
}
|
|
4530
|
+
}
|
|
4531
|
+
styleById[index] = { ...style, tableStyleOverrides: overrides };
|
|
4528
4532
|
});
|
|
4529
4533
|
getChildElements(cellStylesNode ?? document2.documentElement, "cellStyle").forEach((cellStyleNode) => {
|
|
4530
4534
|
const name = cellStyleNode.getAttribute("name");
|
|
@@ -4868,6 +4872,7 @@ function parseSheetState(archive, path, options) {
|
|
|
4868
4872
|
const rowHeightOverridesPx = {};
|
|
4869
4873
|
const colWidthOverridesPx = {};
|
|
4870
4874
|
const rowStyleIds = {};
|
|
4875
|
+
const cellStyleIds = {};
|
|
4871
4876
|
const colStyleIds = {};
|
|
4872
4877
|
let minContentCol = Number.POSITIVE_INFINITY;
|
|
4873
4878
|
let minContentRow = Number.POSITIVE_INFINITY;
|
|
@@ -4917,6 +4922,10 @@ function parseSheetState(archive, path, options) {
|
|
|
4917
4922
|
}
|
|
4918
4923
|
getChildElements(rowNode, "c").forEach((cellNode) => {
|
|
4919
4924
|
const cellRef = cellNode.getAttribute("r");
|
|
4925
|
+
const cellStyleId = Number(cellNode.getAttribute("s") ?? Number.NaN);
|
|
4926
|
+
if (cellRef && Number.isFinite(cellStyleId)) {
|
|
4927
|
+
cellStyleIds[cellRef] = cellStyleId;
|
|
4928
|
+
}
|
|
4920
4929
|
if (isMeaningfulCellNode(cellNode)) {
|
|
4921
4930
|
trackContentCell(cellRef);
|
|
4922
4931
|
}
|
|
@@ -4955,6 +4964,7 @@ function parseSheetState(archive, path, options) {
|
|
|
4955
4964
|
return {
|
|
4956
4965
|
autoFilterRanges,
|
|
4957
4966
|
cachedFormulaValues,
|
|
4967
|
+
cellStyleIds,
|
|
4958
4968
|
columnWidthCharacterWidthPx,
|
|
4959
4969
|
colWidthOverridesPx,
|
|
4960
4970
|
colStyleIds,
|
|
@@ -6697,13 +6707,52 @@ function hasUnresolvedSheetReferences(workbook) {
|
|
|
6697
6707
|
}
|
|
6698
6708
|
return false;
|
|
6699
6709
|
}
|
|
6710
|
+
function collectFormulaCellsWithSavedValues(workbook) {
|
|
6711
|
+
const positions = [];
|
|
6712
|
+
for (let sheetIdx = 0; sheetIdx < workbook.sheetCount; sheetIdx += 1) {
|
|
6713
|
+
let sheet;
|
|
6714
|
+
try {
|
|
6715
|
+
sheet = workbook.getSheet(sheetIdx);
|
|
6716
|
+
} catch {
|
|
6717
|
+
continue;
|
|
6718
|
+
}
|
|
6719
|
+
const cells = sheet.formulaCells;
|
|
6720
|
+
if (!Array.isArray(cells)) {
|
|
6721
|
+
continue;
|
|
6722
|
+
}
|
|
6723
|
+
for (const cell of cells) {
|
|
6724
|
+
if (typeof cell?.row !== "number" || typeof cell?.col !== "number") {
|
|
6725
|
+
continue;
|
|
6726
|
+
}
|
|
6727
|
+
let saved;
|
|
6728
|
+
try {
|
|
6729
|
+
saved = sheet.getCalculatedValueAt(cell.row, cell.col);
|
|
6730
|
+
} catch {
|
|
6731
|
+
continue;
|
|
6732
|
+
}
|
|
6733
|
+
if (!saved.is_empty && !saved.is_error) {
|
|
6734
|
+
positions.push({ sheetIdx, row: cell.row, col: cell.col });
|
|
6735
|
+
}
|
|
6736
|
+
}
|
|
6737
|
+
}
|
|
6738
|
+
return positions;
|
|
6739
|
+
}
|
|
6740
|
+
function anyBecameError(workbook, positions) {
|
|
6741
|
+
return positions.some(({ sheetIdx, row, col }) => {
|
|
6742
|
+
try {
|
|
6743
|
+
return workbook.getSheet(sheetIdx).getCalculatedValueAt(row, col).is_error;
|
|
6744
|
+
} catch {
|
|
6745
|
+
return false;
|
|
6746
|
+
}
|
|
6747
|
+
});
|
|
6748
|
+
}
|
|
6700
6749
|
function safeCalculate(workbook, options = {}) {
|
|
6701
6750
|
if (hasUnresolvedSheetReferences(workbook)) {
|
|
6702
6751
|
return { workbook, calculated: false, skipReason: "unresolved-sheet-refs" };
|
|
6703
6752
|
}
|
|
6753
|
+
const withSavedValues = options.reparse ? collectFormulaCellsWithSavedValues(workbook) : [];
|
|
6704
6754
|
try {
|
|
6705
6755
|
workbook.calculate();
|
|
6706
|
-
return { workbook, calculated: true, skipReason: null };
|
|
6707
6756
|
} catch (err) {
|
|
6708
6757
|
console.warn("[react-xlsx] workbook.calculate() trapped; falling back to cached formula values", err);
|
|
6709
6758
|
if (options.reparse) {
|
|
@@ -6715,6 +6764,14 @@ function safeCalculate(workbook, options = {}) {
|
|
|
6715
6764
|
}
|
|
6716
6765
|
return { workbook, calculated: false, skipReason: "calculate-trapped" };
|
|
6717
6766
|
}
|
|
6767
|
+
if (options.reparse && anyBecameError(workbook, withSavedValues)) {
|
|
6768
|
+
try {
|
|
6769
|
+
return { workbook: options.reparse(), calculated: false, skipReason: "calculate-regressed" };
|
|
6770
|
+
} catch (reparseErr) {
|
|
6771
|
+
console.warn("[react-xlsx] workbook reparse after calculate regression failed", reparseErr);
|
|
6772
|
+
}
|
|
6773
|
+
}
|
|
6774
|
+
return { workbook, calculated: true, skipReason: null };
|
|
6718
6775
|
}
|
|
6719
6776
|
function tryRecalculate(workbook) {
|
|
6720
6777
|
try {
|
|
@@ -7458,6 +7515,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7458
7515
|
colCount: 0,
|
|
7459
7516
|
rowHeightOverridesPx: sheetState?.rowHeightOverridesPx ?? {},
|
|
7460
7517
|
rowStyleIds: sheetState?.rowStyleIds ?? {},
|
|
7518
|
+
cellStyleIds: sheetState?.cellStyleIds ?? {},
|
|
7461
7519
|
styleById: styleById ?? {},
|
|
7462
7520
|
sparklines: sheetState?.sparklines ?? [],
|
|
7463
7521
|
tableStyleByName: tableStyleByName ?? {},
|
|
@@ -7544,6 +7602,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7544
7602
|
namedCellStyleByName: namedCellStyleByName ?? {},
|
|
7545
7603
|
rowHeightOverridesPx: sheetState?.rowHeightOverridesPx ?? {},
|
|
7546
7604
|
rowStyleIds: sheetState?.rowStyleIds ?? {},
|
|
7605
|
+
cellStyleIds: sheetState?.cellStyleIds ?? {},
|
|
7547
7606
|
showGridLines: sheetState?.showGridLines ?? true,
|
|
7548
7607
|
styleById: styleById ?? {},
|
|
7549
7608
|
sparklines: sheetState?.sparklines ?? [],
|
|
@@ -10007,7 +10066,7 @@ function useXlsxViewerController(options) {
|
|
|
10007
10066
|
return;
|
|
10008
10067
|
}
|
|
10009
10068
|
const dataStartRow = targetTable.start.row + Math.max(targetTable.headerRowCount, 1);
|
|
10010
|
-
const totalsRowOffset = targetTable.
|
|
10069
|
+
const totalsRowOffset = targetTable.totalsRowCount;
|
|
10011
10070
|
const dataEndRow = targetTable.end.row - totalsRowOffset;
|
|
10012
10071
|
const startCol = targetTable.start.col;
|
|
10013
10072
|
const endCol = targetTable.end.col;
|
|
@@ -19171,7 +19230,8 @@ function applyCanvasBorderDash(context, style, width) {
|
|
|
19171
19230
|
context.setLineDash([]);
|
|
19172
19231
|
}
|
|
19173
19232
|
function strokeCanvasBorderSide(context, side, rect, border) {
|
|
19174
|
-
const
|
|
19233
|
+
const strokeWidth = border.style === "double" ? border.width / 3 : border.width;
|
|
19234
|
+
const halfWidth = strokeWidth / 2;
|
|
19175
19235
|
const left = rect.left;
|
|
19176
19236
|
const right = rect.left + rect.width;
|
|
19177
19237
|
const top = rect.top;
|
|
@@ -19197,8 +19257,8 @@ function strokeCanvasBorderSide(context, side, rect, border) {
|
|
|
19197
19257
|
context.stroke();
|
|
19198
19258
|
};
|
|
19199
19259
|
if (border.style === "double") {
|
|
19200
|
-
const inset =
|
|
19201
|
-
context.lineWidth =
|
|
19260
|
+
const inset = border.width - strokeWidth;
|
|
19261
|
+
context.lineWidth = strokeWidth;
|
|
19202
19262
|
context.setLineDash([]);
|
|
19203
19263
|
strokeLine(0);
|
|
19204
19264
|
strokeLine(inset);
|
|
@@ -22111,6 +22171,43 @@ function mergeResolvedCellStyle(base, overlay, options) {
|
|
|
22111
22171
|
}
|
|
22112
22172
|
return nextStyle;
|
|
22113
22173
|
}
|
|
22174
|
+
function resolveCellTableOverrides(rawStyle, sheet, row, col) {
|
|
22175
|
+
const styleId = sheet?.cellStyleIds?.[cellAddressToA12({ row, col })] ?? sheet?.rowStyleIds[row] ?? sheet?.colStyleIds[col];
|
|
22176
|
+
const declared = styleId === void 0 ? void 0 : sheet?.styleById[styleId]?.tableStyleOverrides;
|
|
22177
|
+
const overrides = {};
|
|
22178
|
+
const font = asRecord(rawStyle?.font);
|
|
22179
|
+
if (font) {
|
|
22180
|
+
const explicitFont = {};
|
|
22181
|
+
const fontDefaults = {
|
|
22182
|
+
name: "Calibri",
|
|
22183
|
+
size: 11,
|
|
22184
|
+
bold: false,
|
|
22185
|
+
italic: false,
|
|
22186
|
+
underline: "none",
|
|
22187
|
+
strikethrough: false,
|
|
22188
|
+
verticalAlign: "baseline"
|
|
22189
|
+
};
|
|
22190
|
+
for (const [key, value] of Object.entries(font)) {
|
|
22191
|
+
const isExplicit = declared ? Object.hasOwn(declared.font ?? {}, key) : key === "color" ? asRecord(value)?.colorType !== "auto" : value !== fontDefaults[key];
|
|
22192
|
+
if (isExplicit) {
|
|
22193
|
+
explicitFont[key] = value;
|
|
22194
|
+
}
|
|
22195
|
+
}
|
|
22196
|
+
overrides.font = explicitFont;
|
|
22197
|
+
}
|
|
22198
|
+
const fill = asRecord(rawStyle?.fill);
|
|
22199
|
+
if (fill && fill.fillType !== "none") {
|
|
22200
|
+
overrides.fill = fill;
|
|
22201
|
+
}
|
|
22202
|
+
const border = asRecord(rawStyle?.border);
|
|
22203
|
+
if (border) {
|
|
22204
|
+
overrides.border = Object.fromEntries(Object.entries(border).filter(([, edge]) => {
|
|
22205
|
+
const style = asRecord(edge)?.style;
|
|
22206
|
+
return typeof style === "string" && style !== "none";
|
|
22207
|
+
}));
|
|
22208
|
+
}
|
|
22209
|
+
return overrides;
|
|
22210
|
+
}
|
|
22114
22211
|
function resolveBorderEdgePriority(edge) {
|
|
22115
22212
|
const style = typeof edge?.style === "string" ? edge.style : "none";
|
|
22116
22213
|
const stylePriority = {
|
|
@@ -22239,7 +22336,7 @@ function resolveTableCellStyle(table, row, col, activeSheet) {
|
|
|
22239
22336
|
return null;
|
|
22240
22337
|
}
|
|
22241
22338
|
const headerRowCount = Math.max(table.headerRowCount, 1);
|
|
22242
|
-
const totalsRowCount = table.
|
|
22339
|
+
const totalsRowCount = table.totalsRowCount;
|
|
22243
22340
|
const headerEndRow = table.start.row + headerRowCount - 1;
|
|
22244
22341
|
const totalsStartRow = table.end.row - totalsRowCount + 1;
|
|
22245
22342
|
const bodyStartRow = headerEndRow + 1;
|
|
@@ -26563,7 +26660,10 @@ function XlsxGrid({
|
|
|
26563
26660
|
});
|
|
26564
26661
|
const targetTable = getTableAtCell(effectiveTables, targetRow, targetCol);
|
|
26565
26662
|
const targetTableStyle = resolveTableCellStyle(targetTable, targetRow, targetCol, activeSheet);
|
|
26566
|
-
const resolvedStyle = mergeResolvedCellStyle(
|
|
26663
|
+
const resolvedStyle = targetTableStyle ? mergeResolvedCellStyle(
|
|
26664
|
+
mergeResolvedCellStyle(targetRawStyle, targetTableStyle),
|
|
26665
|
+
resolveCellTableOverrides(targetRawStyle, activeSheet, targetRow, targetCol)
|
|
26666
|
+
) : targetRawStyle;
|
|
26567
26667
|
cellBaseRawStyleCacheRef.current.set(targetCacheKey, resolvedStyle);
|
|
26568
26668
|
return resolvedStyle;
|
|
26569
26669
|
};
|
|
@@ -28934,6 +29034,14 @@ function XlsxGrid({
|
|
|
28934
29034
|
hasPendingGridlinePath = false;
|
|
28935
29035
|
};
|
|
28936
29036
|
const drawnMergedAnchorKeys = /* @__PURE__ */ new Set();
|
|
29037
|
+
const deferredDoubleBorders = [];
|
|
29038
|
+
const drawCellBorder = (side, rect, border) => {
|
|
29039
|
+
if (border.style === "double") {
|
|
29040
|
+
deferredDoubleBorders.push({ side, rect, border });
|
|
29041
|
+
} else {
|
|
29042
|
+
strokeCanvasBorderSide(paneContext, side, rect, border);
|
|
29043
|
+
}
|
|
29044
|
+
};
|
|
28937
29045
|
for (const rowItem of paneAxisItems.rows) {
|
|
28938
29046
|
for (const colItem of paneAxisItems.cols) {
|
|
28939
29047
|
const cell = { row: rowItem.actualRow, col: colItem.actualCol };
|
|
@@ -29080,16 +29188,24 @@ function XlsxGrid({
|
|
|
29080
29188
|
flushPendingGridlines();
|
|
29081
29189
|
}
|
|
29082
29190
|
if (topBorder && drawRowIndex === 0) {
|
|
29083
|
-
|
|
29191
|
+
drawCellBorder("top", localRect, topBorder);
|
|
29084
29192
|
}
|
|
29085
29193
|
if (resolvedRightBorder) {
|
|
29086
|
-
|
|
29194
|
+
if (resolvedRightBorder.style === "double" && resolvedRightBorder === rightNeighborLeftBorder) {
|
|
29195
|
+
drawCellBorder("left", { ...localRect, left: localRect.left + localRect.width }, resolvedRightBorder);
|
|
29196
|
+
} else {
|
|
29197
|
+
drawCellBorder("right", localRect, resolvedRightBorder);
|
|
29198
|
+
}
|
|
29087
29199
|
}
|
|
29088
29200
|
if (resolvedBottomBorder) {
|
|
29089
|
-
|
|
29201
|
+
if (resolvedBottomBorder.style === "double" && resolvedBottomBorder === bottomNeighborTopBorder) {
|
|
29202
|
+
drawCellBorder("top", { ...localRect, top: localRect.top + localRect.height }, resolvedBottomBorder);
|
|
29203
|
+
} else {
|
|
29204
|
+
drawCellBorder("bottom", localRect, resolvedBottomBorder);
|
|
29205
|
+
}
|
|
29090
29206
|
}
|
|
29091
29207
|
if (leftBorder && drawColIndex === 0) {
|
|
29092
|
-
|
|
29208
|
+
drawCellBorder("left", localRect, leftBorder);
|
|
29093
29209
|
}
|
|
29094
29210
|
if (cellData.chartHighlight) {
|
|
29095
29211
|
const highlightBorder = {
|
|
@@ -29362,6 +29478,9 @@ function XlsxGrid({
|
|
|
29362
29478
|
}
|
|
29363
29479
|
}
|
|
29364
29480
|
flushPendingGridlines();
|
|
29481
|
+
for (const { side, rect, border } of deferredDoubleBorders) {
|
|
29482
|
+
strokeCanvasBorderSide(paneContext, side, rect, border);
|
|
29483
|
+
}
|
|
29365
29484
|
}
|
|
29366
29485
|
for (const pane of cellPaneOrder) {
|
|
29367
29486
|
const paneContext = bodyContexts[pane];
|