@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.d.cts
CHANGED
|
@@ -17,6 +17,7 @@ interface XlsxResolvedCellStyle {
|
|
|
17
17
|
};
|
|
18
18
|
fill?: Record<string, unknown>;
|
|
19
19
|
font?: Record<string, unknown>;
|
|
20
|
+
tableStyleOverrides?: XlsxResolvedCellStyle;
|
|
20
21
|
}
|
|
21
22
|
interface XlsxTableStyleDefinition {
|
|
22
23
|
[elementType: string]: XlsxResolvedCellStyle;
|
|
@@ -99,6 +100,7 @@ interface XlsxFreezePanes {
|
|
|
99
100
|
}
|
|
100
101
|
type XlsxSheetVisibility = "hidden" | "veryHidden" | "visible";
|
|
101
102
|
interface XlsxSheetData {
|
|
103
|
+
cellStyleIds?: Record<string, number>;
|
|
102
104
|
autoFilterRanges: XlsxCellRange[];
|
|
103
105
|
cachedFormulaValues: Record<string, string>;
|
|
104
106
|
colWidthOverridesPx: Record<number, number>;
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ interface XlsxResolvedCellStyle {
|
|
|
17
17
|
};
|
|
18
18
|
fill?: Record<string, unknown>;
|
|
19
19
|
font?: Record<string, unknown>;
|
|
20
|
+
tableStyleOverrides?: XlsxResolvedCellStyle;
|
|
20
21
|
}
|
|
21
22
|
interface XlsxTableStyleDefinition {
|
|
22
23
|
[elementType: string]: XlsxResolvedCellStyle;
|
|
@@ -99,6 +100,7 @@ interface XlsxFreezePanes {
|
|
|
99
100
|
}
|
|
100
101
|
type XlsxSheetVisibility = "hidden" | "veryHidden" | "visible";
|
|
101
102
|
interface XlsxSheetData {
|
|
103
|
+
cellStyleIds?: Record<string, number>;
|
|
102
104
|
autoFilterRanges: XlsxCellRange[];
|
|
103
105
|
cachedFormulaValues: Record<string, string>;
|
|
104
106
|
colWidthOverridesPx: Record<number, number>;
|
package/dist/index.js
CHANGED
|
@@ -3581,7 +3581,7 @@ function resolveWorkbookColor(color, themePalette) {
|
|
|
3581
3581
|
if (directHex) {
|
|
3582
3582
|
return normalizeHexColor2(directHex);
|
|
3583
3583
|
}
|
|
3584
|
-
const themeValue = color.theme;
|
|
3584
|
+
const themeValue = color.theme ?? color.themeIndex;
|
|
3585
3585
|
const numericTheme = typeof themeValue === "number" ? themeValue : typeof themeValue === "string" && themeValue.trim().length > 0 ? Number(themeValue) : Number.NaN;
|
|
3586
3586
|
const themeColor = Number.isFinite(numericTheme) ? themePalette?.colorsByIndex[numericTheme] ?? null : null;
|
|
3587
3587
|
if (!themeColor) {
|
|
@@ -4209,6 +4209,12 @@ function parseSpreadsheetFont(node) {
|
|
|
4209
4209
|
return void 0;
|
|
4210
4210
|
}
|
|
4211
4211
|
const font = {};
|
|
4212
|
+
for (const [tag, property] of [["b", "bold"], ["i", "italic"], ["strike", "strikethrough"]]) {
|
|
4213
|
+
const flag = getFirstChild(node, tag);
|
|
4214
|
+
if (flag) {
|
|
4215
|
+
font[property] = hasEnabledSpreadsheetFlag(flag);
|
|
4216
|
+
}
|
|
4217
|
+
}
|
|
4212
4218
|
const size = getFirstChild(node, "sz")?.getAttribute("val");
|
|
4213
4219
|
const name = getFirstChild(node, "name")?.getAttribute("val");
|
|
4214
4220
|
const family = getFirstChild(node, "family")?.getAttribute("val");
|
|
@@ -4216,15 +4222,6 @@ function parseSpreadsheetFont(node) {
|
|
|
4216
4222
|
const charset = getFirstChild(node, "charset")?.getAttribute("val");
|
|
4217
4223
|
const verticalAlign = getFirstChild(node, "vertAlign")?.getAttribute("val");
|
|
4218
4224
|
const color = parseSpreadsheetColor(getFirstChild(node, "color"));
|
|
4219
|
-
if (hasEnabledSpreadsheetFlag(getFirstChild(node, "b"))) {
|
|
4220
|
-
font.bold = true;
|
|
4221
|
-
}
|
|
4222
|
-
if (hasEnabledSpreadsheetFlag(getFirstChild(node, "i"))) {
|
|
4223
|
-
font.italic = true;
|
|
4224
|
-
}
|
|
4225
|
-
if (hasEnabledSpreadsheetFlag(getFirstChild(node, "strike"))) {
|
|
4226
|
-
font.strikethrough = true;
|
|
4227
|
-
}
|
|
4228
4225
|
if (getFirstChild(node, "u")) {
|
|
4229
4226
|
font.underline = getFirstChild(node, "u")?.getAttribute("val") ?? "single";
|
|
4230
4227
|
}
|
|
@@ -4473,7 +4470,14 @@ function parseWorkbookStyles(archive) {
|
|
|
4473
4470
|
const styleById = {};
|
|
4474
4471
|
const tableStyleByName = {};
|
|
4475
4472
|
getChildElements(cellXfsNode, "xf").forEach((xfNode, index) => {
|
|
4476
|
-
|
|
4473
|
+
const style = parseResolvedXfStyle(xfNode, fonts, fills, borders, checkboxComplementIndices);
|
|
4474
|
+
const overrides = {};
|
|
4475
|
+
for (const component of ["font", "fill", "border"]) {
|
|
4476
|
+
if (Number(xfNode.getAttribute(`${component}Id`) ?? 0) > 0 && xfNode.getAttribute(`apply${component[0].toUpperCase()}${component.slice(1)}`) !== "0") {
|
|
4477
|
+
Object.assign(overrides, { [component]: style[component] });
|
|
4478
|
+
}
|
|
4479
|
+
}
|
|
4480
|
+
styleById[index] = { ...style, tableStyleOverrides: overrides };
|
|
4477
4481
|
});
|
|
4478
4482
|
getChildElements(cellStylesNode ?? document2.documentElement, "cellStyle").forEach((cellStyleNode) => {
|
|
4479
4483
|
const name = cellStyleNode.getAttribute("name");
|
|
@@ -4817,6 +4821,7 @@ function parseSheetState(archive, path, options) {
|
|
|
4817
4821
|
const rowHeightOverridesPx = {};
|
|
4818
4822
|
const colWidthOverridesPx = {};
|
|
4819
4823
|
const rowStyleIds = {};
|
|
4824
|
+
const cellStyleIds = {};
|
|
4820
4825
|
const colStyleIds = {};
|
|
4821
4826
|
let minContentCol = Number.POSITIVE_INFINITY;
|
|
4822
4827
|
let minContentRow = Number.POSITIVE_INFINITY;
|
|
@@ -4866,6 +4871,10 @@ function parseSheetState(archive, path, options) {
|
|
|
4866
4871
|
}
|
|
4867
4872
|
getChildElements(rowNode, "c").forEach((cellNode) => {
|
|
4868
4873
|
const cellRef = cellNode.getAttribute("r");
|
|
4874
|
+
const cellStyleId = Number(cellNode.getAttribute("s") ?? Number.NaN);
|
|
4875
|
+
if (cellRef && Number.isFinite(cellStyleId)) {
|
|
4876
|
+
cellStyleIds[cellRef] = cellStyleId;
|
|
4877
|
+
}
|
|
4869
4878
|
if (isMeaningfulCellNode(cellNode)) {
|
|
4870
4879
|
trackContentCell(cellRef);
|
|
4871
4880
|
}
|
|
@@ -4904,6 +4913,7 @@ function parseSheetState(archive, path, options) {
|
|
|
4904
4913
|
return {
|
|
4905
4914
|
autoFilterRanges,
|
|
4906
4915
|
cachedFormulaValues,
|
|
4916
|
+
cellStyleIds,
|
|
4907
4917
|
columnWidthCharacterWidthPx,
|
|
4908
4918
|
colWidthOverridesPx,
|
|
4909
4919
|
colStyleIds,
|
|
@@ -6646,13 +6656,52 @@ function hasUnresolvedSheetReferences(workbook) {
|
|
|
6646
6656
|
}
|
|
6647
6657
|
return false;
|
|
6648
6658
|
}
|
|
6659
|
+
function collectFormulaCellsWithSavedValues(workbook) {
|
|
6660
|
+
const positions = [];
|
|
6661
|
+
for (let sheetIdx = 0; sheetIdx < workbook.sheetCount; sheetIdx += 1) {
|
|
6662
|
+
let sheet;
|
|
6663
|
+
try {
|
|
6664
|
+
sheet = workbook.getSheet(sheetIdx);
|
|
6665
|
+
} catch {
|
|
6666
|
+
continue;
|
|
6667
|
+
}
|
|
6668
|
+
const cells = sheet.formulaCells;
|
|
6669
|
+
if (!Array.isArray(cells)) {
|
|
6670
|
+
continue;
|
|
6671
|
+
}
|
|
6672
|
+
for (const cell of cells) {
|
|
6673
|
+
if (typeof cell?.row !== "number" || typeof cell?.col !== "number") {
|
|
6674
|
+
continue;
|
|
6675
|
+
}
|
|
6676
|
+
let saved;
|
|
6677
|
+
try {
|
|
6678
|
+
saved = sheet.getCalculatedValueAt(cell.row, cell.col);
|
|
6679
|
+
} catch {
|
|
6680
|
+
continue;
|
|
6681
|
+
}
|
|
6682
|
+
if (!saved.is_empty && !saved.is_error) {
|
|
6683
|
+
positions.push({ sheetIdx, row: cell.row, col: cell.col });
|
|
6684
|
+
}
|
|
6685
|
+
}
|
|
6686
|
+
}
|
|
6687
|
+
return positions;
|
|
6688
|
+
}
|
|
6689
|
+
function anyBecameError(workbook, positions) {
|
|
6690
|
+
return positions.some(({ sheetIdx, row, col }) => {
|
|
6691
|
+
try {
|
|
6692
|
+
return workbook.getSheet(sheetIdx).getCalculatedValueAt(row, col).is_error;
|
|
6693
|
+
} catch {
|
|
6694
|
+
return false;
|
|
6695
|
+
}
|
|
6696
|
+
});
|
|
6697
|
+
}
|
|
6649
6698
|
function safeCalculate(workbook, options = {}) {
|
|
6650
6699
|
if (hasUnresolvedSheetReferences(workbook)) {
|
|
6651
6700
|
return { workbook, calculated: false, skipReason: "unresolved-sheet-refs" };
|
|
6652
6701
|
}
|
|
6702
|
+
const withSavedValues = options.reparse ? collectFormulaCellsWithSavedValues(workbook) : [];
|
|
6653
6703
|
try {
|
|
6654
6704
|
workbook.calculate();
|
|
6655
|
-
return { workbook, calculated: true, skipReason: null };
|
|
6656
6705
|
} catch (err) {
|
|
6657
6706
|
console.warn("[react-xlsx] workbook.calculate() trapped; falling back to cached formula values", err);
|
|
6658
6707
|
if (options.reparse) {
|
|
@@ -6664,6 +6713,14 @@ function safeCalculate(workbook, options = {}) {
|
|
|
6664
6713
|
}
|
|
6665
6714
|
return { workbook, calculated: false, skipReason: "calculate-trapped" };
|
|
6666
6715
|
}
|
|
6716
|
+
if (options.reparse && anyBecameError(workbook, withSavedValues)) {
|
|
6717
|
+
try {
|
|
6718
|
+
return { workbook: options.reparse(), calculated: false, skipReason: "calculate-regressed" };
|
|
6719
|
+
} catch (reparseErr) {
|
|
6720
|
+
console.warn("[react-xlsx] workbook reparse after calculate regression failed", reparseErr);
|
|
6721
|
+
}
|
|
6722
|
+
}
|
|
6723
|
+
return { workbook, calculated: true, skipReason: null };
|
|
6667
6724
|
}
|
|
6668
6725
|
function tryRecalculate(workbook) {
|
|
6669
6726
|
try {
|
|
@@ -7406,6 +7463,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7406
7463
|
colCount: 0,
|
|
7407
7464
|
rowHeightOverridesPx: sheetState?.rowHeightOverridesPx ?? {},
|
|
7408
7465
|
rowStyleIds: sheetState?.rowStyleIds ?? {},
|
|
7466
|
+
cellStyleIds: sheetState?.cellStyleIds ?? {},
|
|
7409
7467
|
styleById: styleById ?? {},
|
|
7410
7468
|
sparklines: sheetState?.sparklines ?? [],
|
|
7411
7469
|
tableStyleByName: tableStyleByName ?? {},
|
|
@@ -7492,6 +7550,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7492
7550
|
namedCellStyleByName: namedCellStyleByName ?? {},
|
|
7493
7551
|
rowHeightOverridesPx: sheetState?.rowHeightOverridesPx ?? {},
|
|
7494
7552
|
rowStyleIds: sheetState?.rowStyleIds ?? {},
|
|
7553
|
+
cellStyleIds: sheetState?.cellStyleIds ?? {},
|
|
7495
7554
|
showGridLines: sheetState?.showGridLines ?? true,
|
|
7496
7555
|
styleById: styleById ?? {},
|
|
7497
7556
|
sparklines: sheetState?.sparklines ?? [],
|
|
@@ -9955,7 +10014,7 @@ function useXlsxViewerController(options) {
|
|
|
9955
10014
|
return;
|
|
9956
10015
|
}
|
|
9957
10016
|
const dataStartRow = targetTable.start.row + Math.max(targetTable.headerRowCount, 1);
|
|
9958
|
-
const totalsRowOffset = targetTable.
|
|
10017
|
+
const totalsRowOffset = targetTable.totalsRowCount;
|
|
9959
10018
|
const dataEndRow = targetTable.end.row - totalsRowOffset;
|
|
9960
10019
|
const startCol = targetTable.start.col;
|
|
9961
10020
|
const endCol = targetTable.end.col;
|
|
@@ -19136,7 +19195,8 @@ function applyCanvasBorderDash(context, style, width) {
|
|
|
19136
19195
|
context.setLineDash([]);
|
|
19137
19196
|
}
|
|
19138
19197
|
function strokeCanvasBorderSide(context, side, rect, border) {
|
|
19139
|
-
const
|
|
19198
|
+
const strokeWidth = border.style === "double" ? border.width / 3 : border.width;
|
|
19199
|
+
const halfWidth = strokeWidth / 2;
|
|
19140
19200
|
const left = rect.left;
|
|
19141
19201
|
const right = rect.left + rect.width;
|
|
19142
19202
|
const top = rect.top;
|
|
@@ -19162,8 +19222,8 @@ function strokeCanvasBorderSide(context, side, rect, border) {
|
|
|
19162
19222
|
context.stroke();
|
|
19163
19223
|
};
|
|
19164
19224
|
if (border.style === "double") {
|
|
19165
|
-
const inset =
|
|
19166
|
-
context.lineWidth =
|
|
19225
|
+
const inset = border.width - strokeWidth;
|
|
19226
|
+
context.lineWidth = strokeWidth;
|
|
19167
19227
|
context.setLineDash([]);
|
|
19168
19228
|
strokeLine(0);
|
|
19169
19229
|
strokeLine(inset);
|
|
@@ -22076,6 +22136,43 @@ function mergeResolvedCellStyle(base, overlay, options) {
|
|
|
22076
22136
|
}
|
|
22077
22137
|
return nextStyle;
|
|
22078
22138
|
}
|
|
22139
|
+
function resolveCellTableOverrides(rawStyle, sheet, row, col) {
|
|
22140
|
+
const styleId = sheet?.cellStyleIds?.[cellAddressToA12({ row, col })] ?? sheet?.rowStyleIds[row] ?? sheet?.colStyleIds[col];
|
|
22141
|
+
const declared = styleId === void 0 ? void 0 : sheet?.styleById[styleId]?.tableStyleOverrides;
|
|
22142
|
+
const overrides = {};
|
|
22143
|
+
const font = asRecord(rawStyle?.font);
|
|
22144
|
+
if (font) {
|
|
22145
|
+
const explicitFont = {};
|
|
22146
|
+
const fontDefaults = {
|
|
22147
|
+
name: "Calibri",
|
|
22148
|
+
size: 11,
|
|
22149
|
+
bold: false,
|
|
22150
|
+
italic: false,
|
|
22151
|
+
underline: "none",
|
|
22152
|
+
strikethrough: false,
|
|
22153
|
+
verticalAlign: "baseline"
|
|
22154
|
+
};
|
|
22155
|
+
for (const [key, value] of Object.entries(font)) {
|
|
22156
|
+
const isExplicit = declared ? Object.hasOwn(declared.font ?? {}, key) : key === "color" ? asRecord(value)?.colorType !== "auto" : value !== fontDefaults[key];
|
|
22157
|
+
if (isExplicit) {
|
|
22158
|
+
explicitFont[key] = value;
|
|
22159
|
+
}
|
|
22160
|
+
}
|
|
22161
|
+
overrides.font = explicitFont;
|
|
22162
|
+
}
|
|
22163
|
+
const fill = asRecord(rawStyle?.fill);
|
|
22164
|
+
if (fill && fill.fillType !== "none") {
|
|
22165
|
+
overrides.fill = fill;
|
|
22166
|
+
}
|
|
22167
|
+
const border = asRecord(rawStyle?.border);
|
|
22168
|
+
if (border) {
|
|
22169
|
+
overrides.border = Object.fromEntries(Object.entries(border).filter(([, edge]) => {
|
|
22170
|
+
const style = asRecord(edge)?.style;
|
|
22171
|
+
return typeof style === "string" && style !== "none";
|
|
22172
|
+
}));
|
|
22173
|
+
}
|
|
22174
|
+
return overrides;
|
|
22175
|
+
}
|
|
22079
22176
|
function resolveBorderEdgePriority(edge) {
|
|
22080
22177
|
const style = typeof edge?.style === "string" ? edge.style : "none";
|
|
22081
22178
|
const stylePriority = {
|
|
@@ -22204,7 +22301,7 @@ function resolveTableCellStyle(table, row, col, activeSheet) {
|
|
|
22204
22301
|
return null;
|
|
22205
22302
|
}
|
|
22206
22303
|
const headerRowCount = Math.max(table.headerRowCount, 1);
|
|
22207
|
-
const totalsRowCount = table.
|
|
22304
|
+
const totalsRowCount = table.totalsRowCount;
|
|
22208
22305
|
const headerEndRow = table.start.row + headerRowCount - 1;
|
|
22209
22306
|
const totalsStartRow = table.end.row - totalsRowCount + 1;
|
|
22210
22307
|
const bodyStartRow = headerEndRow + 1;
|
|
@@ -26528,7 +26625,10 @@ function XlsxGrid({
|
|
|
26528
26625
|
});
|
|
26529
26626
|
const targetTable = getTableAtCell(effectiveTables, targetRow, targetCol);
|
|
26530
26627
|
const targetTableStyle = resolveTableCellStyle(targetTable, targetRow, targetCol, activeSheet);
|
|
26531
|
-
const resolvedStyle = mergeResolvedCellStyle(
|
|
26628
|
+
const resolvedStyle = targetTableStyle ? mergeResolvedCellStyle(
|
|
26629
|
+
mergeResolvedCellStyle(targetRawStyle, targetTableStyle),
|
|
26630
|
+
resolveCellTableOverrides(targetRawStyle, activeSheet, targetRow, targetCol)
|
|
26631
|
+
) : targetRawStyle;
|
|
26532
26632
|
cellBaseRawStyleCacheRef.current.set(targetCacheKey, resolvedStyle);
|
|
26533
26633
|
return resolvedStyle;
|
|
26534
26634
|
};
|
|
@@ -28899,6 +28999,14 @@ function XlsxGrid({
|
|
|
28899
28999
|
hasPendingGridlinePath = false;
|
|
28900
29000
|
};
|
|
28901
29001
|
const drawnMergedAnchorKeys = /* @__PURE__ */ new Set();
|
|
29002
|
+
const deferredDoubleBorders = [];
|
|
29003
|
+
const drawCellBorder = (side, rect, border) => {
|
|
29004
|
+
if (border.style === "double") {
|
|
29005
|
+
deferredDoubleBorders.push({ side, rect, border });
|
|
29006
|
+
} else {
|
|
29007
|
+
strokeCanvasBorderSide(paneContext, side, rect, border);
|
|
29008
|
+
}
|
|
29009
|
+
};
|
|
28902
29010
|
for (const rowItem of paneAxisItems.rows) {
|
|
28903
29011
|
for (const colItem of paneAxisItems.cols) {
|
|
28904
29012
|
const cell = { row: rowItem.actualRow, col: colItem.actualCol };
|
|
@@ -29045,16 +29153,24 @@ function XlsxGrid({
|
|
|
29045
29153
|
flushPendingGridlines();
|
|
29046
29154
|
}
|
|
29047
29155
|
if (topBorder && drawRowIndex === 0) {
|
|
29048
|
-
|
|
29156
|
+
drawCellBorder("top", localRect, topBorder);
|
|
29049
29157
|
}
|
|
29050
29158
|
if (resolvedRightBorder) {
|
|
29051
|
-
|
|
29159
|
+
if (resolvedRightBorder.style === "double" && resolvedRightBorder === rightNeighborLeftBorder) {
|
|
29160
|
+
drawCellBorder("left", { ...localRect, left: localRect.left + localRect.width }, resolvedRightBorder);
|
|
29161
|
+
} else {
|
|
29162
|
+
drawCellBorder("right", localRect, resolvedRightBorder);
|
|
29163
|
+
}
|
|
29052
29164
|
}
|
|
29053
29165
|
if (resolvedBottomBorder) {
|
|
29054
|
-
|
|
29166
|
+
if (resolvedBottomBorder.style === "double" && resolvedBottomBorder === bottomNeighborTopBorder) {
|
|
29167
|
+
drawCellBorder("top", { ...localRect, top: localRect.top + localRect.height }, resolvedBottomBorder);
|
|
29168
|
+
} else {
|
|
29169
|
+
drawCellBorder("bottom", localRect, resolvedBottomBorder);
|
|
29170
|
+
}
|
|
29055
29171
|
}
|
|
29056
29172
|
if (leftBorder && drawColIndex === 0) {
|
|
29057
|
-
|
|
29173
|
+
drawCellBorder("left", localRect, leftBorder);
|
|
29058
29174
|
}
|
|
29059
29175
|
if (cellData.chartHighlight) {
|
|
29060
29176
|
const highlightBorder = {
|
|
@@ -29327,6 +29443,9 @@ function XlsxGrid({
|
|
|
29327
29443
|
}
|
|
29328
29444
|
}
|
|
29329
29445
|
flushPendingGridlines();
|
|
29446
|
+
for (const { side, rect, border } of deferredDoubleBorders) {
|
|
29447
|
+
strokeCanvasBorderSide(paneContext, side, rect, border);
|
|
29448
|
+
}
|
|
29330
29449
|
}
|
|
29331
29450
|
for (const pane of cellPaneOrder) {
|
|
29332
29451
|
const paneContext = bodyContexts[pane];
|