@extend-ai/react-xlsx 0.19.0 → 0.20.1
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/README.md +2 -1
- package/dist/{chart-renderer-LHXMRBGR.cjs → chart-renderer-K2VM257E.cjs} +44 -39
- package/dist/chart-renderer-K2VM257E.cjs.map +1 -0
- package/dist/{chart-renderer-HVOEAQXK.cjs → chart-renderer-K6GORT3R.cjs} +44 -39
- package/dist/chart-renderer-K6GORT3R.cjs.map +1 -0
- package/dist/{chart-renderer-R2B4I2HL.js → chart-renderer-KGLAI4DN.js} +25 -20
- package/dist/chart-renderer-KGLAI4DN.js.map +1 -0
- package/dist/{chart-renderer-3K2VKB5I.js → chart-renderer-RXO7WP4Q.js} +25 -20
- package/dist/chart-renderer-RXO7WP4Q.js.map +1 -0
- package/dist/{chunk-ZIO47YMT.cjs → chunk-2MVEKDY2.cjs} +4 -4
- package/dist/{chunk-ZIO47YMT.cjs.map → chunk-2MVEKDY2.cjs.map} +1 -1
- package/dist/{chunk-3O2QY6LA.js → chunk-3JTCYAUX.js} +3 -3
- package/dist/{chunk-4VX5HTCF.cjs → chunk-54YBFWL3.cjs} +4 -4
- package/dist/{chunk-4VX5HTCF.cjs.map → chunk-54YBFWL3.cjs.map} +1 -1
- package/dist/{chunk-T5WZHPIN.cjs → chunk-AD4CGQN2.cjs} +2 -2
- package/dist/{chunk-T5WZHPIN.cjs.map → chunk-AD4CGQN2.cjs.map} +1 -1
- package/dist/{chunk-Y737JKUG.js → chunk-GXJO6CK6.js} +136 -33
- package/dist/chunk-GXJO6CK6.js.map +1 -0
- package/dist/{chunk-TYJLNPNE.cjs → chunk-HAHCVXCU.cjs} +922 -819
- package/dist/chunk-HAHCVXCU.cjs.map +1 -0
- package/dist/{chunk-E2VSYCP2.cjs → chunk-O3V2MCOC.cjs} +18 -2
- package/dist/chunk-O3V2MCOC.cjs.map +1 -0
- package/dist/{chunk-BAAMDEDS.js → chunk-VXBNYHW5.js} +18 -2
- package/dist/{chunk-BAAMDEDS.js.map → chunk-VXBNYHW5.js.map} +1 -1
- package/dist/{chunk-O7S3Y6II.js → chunk-WSQDFXDW.js} +3 -3
- package/dist/index.cjs +617 -530
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +115 -28
- package/dist/index.js.map +1 -1
- package/dist/{internal-DSz8QMhK.d.cts → internal-trWFv9In.d.cts} +5 -0
- package/dist/{internal-DSz8QMhK.d.ts → internal-trWFv9In.d.ts} +5 -0
- package/dist/internal.cjs +4 -4
- package/dist/internal.d.cts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.js +2 -2
- package/dist/{region-map-geography-6TGXBY3V.cjs → region-map-geography-VEN5CPRS.cjs} +2 -2
- package/dist/{region-map-geography-6TGXBY3V.cjs.map → region-map-geography-VEN5CPRS.cjs.map} +1 -1
- package/dist/{spreadsheet-font-assets-4AHYDTAQ.cjs → spreadsheet-font-assets-6FKCVICP.cjs} +2 -2
- package/dist/{spreadsheet-font-assets-4AHYDTAQ.cjs.map → spreadsheet-font-assets-6FKCVICP.cjs.map} +1 -1
- package/dist/{surface-regl-MAPCPD7W.cjs → surface-regl-2NNG62KS.cjs} +18 -15
- package/dist/surface-regl-2NNG62KS.cjs.map +1 -0
- package/dist/{surface-regl-NWR5ZZ5D.js → surface-regl-7CDGGVDG.js} +10 -7
- package/dist/surface-regl-7CDGGVDG.js.map +1 -0
- package/dist/{surface-regl-PWTZWQQS.cjs → surface-regl-SUJ2TFZA.cjs} +18 -15
- package/dist/surface-regl-SUJ2TFZA.cjs.map +1 -0
- package/dist/{surface-regl-KW4JL325.js → surface-regl-TJUWTLAZ.js} +10 -7
- package/dist/surface-regl-TJUWTLAZ.js.map +1 -0
- package/dist/vanilla.cjs +4 -4
- package/dist/vanilla.d.cts +2 -2
- package/dist/vanilla.d.ts +2 -2
- package/dist/vanilla.js +2 -2
- package/dist/xlsx-worker.js +67 -1
- package/dist/xlsx-worker.js.map +1 -1
- package/package.json +1 -1
- package/dist/chart-renderer-3K2VKB5I.js.map +0 -1
- package/dist/chart-renderer-HVOEAQXK.cjs.map +0 -1
- package/dist/chart-renderer-LHXMRBGR.cjs.map +0 -1
- package/dist/chart-renderer-R2B4I2HL.js.map +0 -1
- package/dist/chunk-E2VSYCP2.cjs.map +0 -1
- package/dist/chunk-TYJLNPNE.cjs.map +0 -1
- package/dist/chunk-Y737JKUG.js.map +0 -1
- package/dist/surface-regl-KW4JL325.js.map +0 -1
- package/dist/surface-regl-MAPCPD7W.cjs.map +0 -1
- package/dist/surface-regl-NWR5ZZ5D.js.map +0 -1
- package/dist/surface-regl-PWTZWQQS.cjs.map +0 -1
- /package/dist/{chunk-3O2QY6LA.js.map → chunk-3JTCYAUX.js.map} +0 -0
- /package/dist/{chunk-O7S3Y6II.js.map → chunk-WSQDFXDW.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -961,6 +961,8 @@ interface XlsxScrollerRenderProps {
|
|
|
961
961
|
};
|
|
962
962
|
}
|
|
963
963
|
interface UseXlsxViewerControllerOptions {
|
|
964
|
+
/** BCP 47 locale for numeric decimal and grouping separators. Defaults to en-US. */
|
|
965
|
+
locale?: string;
|
|
964
966
|
/**
|
|
965
967
|
* Allows row and column resizing even while editing is disabled by `readOnly`.
|
|
966
968
|
*
|
|
@@ -1073,11 +1075,14 @@ interface XlsxViewerController {
|
|
|
1073
1075
|
deferredLoadFileSize: number | null;
|
|
1074
1076
|
defineNamedRange: (name: string, range?: XlsxCellRange | null) => void;
|
|
1075
1077
|
displayFileName: string;
|
|
1078
|
+
locale: string;
|
|
1076
1079
|
download: () => void;
|
|
1077
1080
|
charts: XlsxChart[];
|
|
1078
1081
|
chartsheets: XlsxChartsheet[];
|
|
1079
1082
|
exportCsv: () => void;
|
|
1080
1083
|
exportXlsx: () => void;
|
|
1084
|
+
/** The current workbook as XLSX bytes, the same bytes `exportXlsx()` downloads; `null` before a workbook loads. */
|
|
1085
|
+
getXlsxBytes: () => Uint8Array | null;
|
|
1081
1086
|
error: Error | null;
|
|
1082
1087
|
file?: ArrayBuffer;
|
|
1083
1088
|
fillSelection: (targetRange: XlsxCellRange) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -961,6 +961,8 @@ interface XlsxScrollerRenderProps {
|
|
|
961
961
|
};
|
|
962
962
|
}
|
|
963
963
|
interface UseXlsxViewerControllerOptions {
|
|
964
|
+
/** BCP 47 locale for numeric decimal and grouping separators. Defaults to en-US. */
|
|
965
|
+
locale?: string;
|
|
964
966
|
/**
|
|
965
967
|
* Allows row and column resizing even while editing is disabled by `readOnly`.
|
|
966
968
|
*
|
|
@@ -1073,11 +1075,14 @@ interface XlsxViewerController {
|
|
|
1073
1075
|
deferredLoadFileSize: number | null;
|
|
1074
1076
|
defineNamedRange: (name: string, range?: XlsxCellRange | null) => void;
|
|
1075
1077
|
displayFileName: string;
|
|
1078
|
+
locale: string;
|
|
1076
1079
|
download: () => void;
|
|
1077
1080
|
charts: XlsxChart[];
|
|
1078
1081
|
chartsheets: XlsxChartsheet[];
|
|
1079
1082
|
exportCsv: () => void;
|
|
1080
1083
|
exportXlsx: () => void;
|
|
1084
|
+
/** The current workbook as XLSX bytes, the same bytes `exportXlsx()` downloads; `null` before a workbook loads. */
|
|
1085
|
+
getXlsxBytes: () => Uint8Array | null;
|
|
1081
1086
|
error: Error | null;
|
|
1082
1087
|
file?: ArrayBuffer;
|
|
1083
1088
|
fillSelection: (targetRange: XlsxCellRange) => void;
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,73 @@
|
|
|
1
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-3JTCYAUX.js";
|
|
2
2
|
import {
|
|
3
3
|
getBuiltinChartColor,
|
|
4
4
|
getBuiltinChartSurfaceStyle,
|
|
5
5
|
resolveBuiltinChartColor
|
|
6
6
|
} from "./chunk-VWGKYABF.js";
|
|
7
7
|
|
|
8
|
+
// src/number-locale.ts
|
|
9
|
+
var separators = /* @__PURE__ */ new Map();
|
|
10
|
+
function parseLocaleNumber(text, locale) {
|
|
11
|
+
if (locale === "en-US") return void 0;
|
|
12
|
+
const parts = new Intl.NumberFormat(locale).formatToParts(12345.6);
|
|
13
|
+
const decimal = parts.find((part) => part.type === "decimal")?.value ?? ".";
|
|
14
|
+
const group = parts.find((part) => part.type === "group")?.value ?? ",";
|
|
15
|
+
let normalized = text.trim();
|
|
16
|
+
const percent = normalized.endsWith("%");
|
|
17
|
+
if (percent) normalized = normalized.slice(0, -1).trim();
|
|
18
|
+
normalized = group.trim() === "" ? normalized.replace(/[ \u00a0\u202f]/g, "") : normalized.split(group).join("");
|
|
19
|
+
normalized = normalized.replace(decimal, ".");
|
|
20
|
+
if (!/^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/.test(normalized)) return void 0;
|
|
21
|
+
const value = Number(normalized) / (percent ? 100 : 1);
|
|
22
|
+
return Number.isFinite(value) ? value : void 0;
|
|
23
|
+
}
|
|
24
|
+
function localizeCellNumber(worksheet, row, col, text, locale = "en-US") {
|
|
25
|
+
if (locale === "en-US" || !text) return text;
|
|
26
|
+
const value = worksheet.getCalculatedValueAt(row, col);
|
|
27
|
+
try {
|
|
28
|
+
if (!value.is_number) return text;
|
|
29
|
+
} finally {
|
|
30
|
+
value.free();
|
|
31
|
+
}
|
|
32
|
+
const style = worksheet.getCellStyleAt(row, col);
|
|
33
|
+
const format = style?.numberFormat;
|
|
34
|
+
if (format?.isDateFormat) return text;
|
|
35
|
+
let symbols = separators.get(locale);
|
|
36
|
+
if (!symbols) {
|
|
37
|
+
const parts = new Intl.NumberFormat(locale).formatToParts(12345.6);
|
|
38
|
+
symbols = {
|
|
39
|
+
decimal: parts.find((part) => part.type === "decimal")?.value ?? ".",
|
|
40
|
+
group: parts.find((part) => part.type === "group")?.value ?? ","
|
|
41
|
+
};
|
|
42
|
+
if (separators.size >= 100) separators.clear();
|
|
43
|
+
separators.set(locale, symbols);
|
|
44
|
+
}
|
|
45
|
+
if (symbols.decimal === "." && symbols.group === ",") return text;
|
|
46
|
+
const protectedPositions = /* @__PURE__ */ new Set();
|
|
47
|
+
const code = format?.formatString ?? "";
|
|
48
|
+
const literalPattern = /"[^"]*"|\\.|\[[^\]]*\]/g;
|
|
49
|
+
const firstPlaceholder = code.replace(literalPattern, (token) => " ".repeat(token.length)).search(/[0#?]/);
|
|
50
|
+
const literals = [...code.matchAll(literalPattern)];
|
|
51
|
+
let suffixEnd = text.length;
|
|
52
|
+
let prefixStart = 0;
|
|
53
|
+
const protect = (token, suffix) => {
|
|
54
|
+
const literal = token.startsWith('"') ? token.slice(1, -1) : token.startsWith("\\") ? token.slice(1) : token.startsWith("[$") ? token.slice(2, -1).split("-")[0] : "";
|
|
55
|
+
if (!literal) return;
|
|
56
|
+
const offset = suffix ? text.lastIndexOf(literal, suffixEnd - literal.length) : text.indexOf(literal, prefixStart);
|
|
57
|
+
if (offset >= 0) {
|
|
58
|
+
for (let i = offset; i < offset + literal.length; i++) protectedPositions.add(i);
|
|
59
|
+
if (suffix) suffixEnd = offset;
|
|
60
|
+
else prefixStart = offset + literal.length;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
for (const token of literals.filter((token2) => token2.index < firstPlaceholder)) protect(token[0], false);
|
|
64
|
+
for (const token of literals.filter((token2) => token2.index >= firstPlaceholder).reverse()) protect(token[0], true);
|
|
65
|
+
return text.replace(
|
|
66
|
+
/\d[\d,]*(?:\.\d*)?|\.\d+/g,
|
|
67
|
+
(number, offset) => number.replace(/[.,]/g, (separator, index) => protectedPositions.has(offset + index) ? separator : separator === "." ? symbols.decimal : symbols.group)
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
8
71
|
// src/spreadsheet-fonts.ts
|
|
9
72
|
var fontLoadPromise;
|
|
10
73
|
var SPREADSHEET_FALLBACK_FONT = "React XLSX Carlito";
|
|
@@ -6818,10 +6881,10 @@ var XlsxWorkerClient = class {
|
|
|
6818
6881
|
type: "load"
|
|
6819
6882
|
}, [workerBuffer]);
|
|
6820
6883
|
}
|
|
6821
|
-
getCellSnapshot(workbookSheetIndex, row, col) {
|
|
6884
|
+
getCellSnapshot(workbookSheetIndex, row, col, locale) {
|
|
6822
6885
|
return this.request({
|
|
6823
6886
|
id: 0,
|
|
6824
|
-
payload: { col, row, workbookSheetIndex },
|
|
6887
|
+
payload: { col, row, workbookSheetIndex, locale },
|
|
6825
6888
|
type: "getCellSnapshot"
|
|
6826
6889
|
});
|
|
6827
6890
|
}
|
|
@@ -6838,10 +6901,10 @@ var XlsxWorkerClient = class {
|
|
|
6838
6901
|
type: "parseCharts"
|
|
6839
6902
|
}, [workerBuffer]);
|
|
6840
6903
|
}
|
|
6841
|
-
getRowsBatch(workbookSheetIndex, startRow, rowCount) {
|
|
6904
|
+
getRowsBatch(workbookSheetIndex, startRow, rowCount, locale) {
|
|
6842
6905
|
return this.request({
|
|
6843
6906
|
id: 0,
|
|
6844
|
-
payload: { rowCount, startRow, workbookSheetIndex },
|
|
6907
|
+
payload: { rowCount, startRow, workbookSheetIndex, locale },
|
|
6845
6908
|
type: "getRowsBatch"
|
|
6846
6909
|
});
|
|
6847
6910
|
}
|
|
@@ -7965,7 +8028,7 @@ function cloneCellStyle(style) {
|
|
|
7965
8028
|
return style;
|
|
7966
8029
|
}
|
|
7967
8030
|
}
|
|
7968
|
-
function coerceUserEnteredValue(value) {
|
|
8031
|
+
function coerceUserEnteredValue(value, locale = "en-US") {
|
|
7969
8032
|
const trimmed = value.trim();
|
|
7970
8033
|
if (!trimmed) {
|
|
7971
8034
|
return "";
|
|
@@ -7976,6 +8039,8 @@ function coerceUserEnteredValue(value) {
|
|
|
7976
8039
|
if (/^(true|false)$/i.test(trimmed)) {
|
|
7977
8040
|
return trimmed.toLowerCase() === "true";
|
|
7978
8041
|
}
|
|
8042
|
+
const localizedNumber = parseLocaleNumber(trimmed, locale);
|
|
8043
|
+
if (localizedNumber !== void 0) return localizedNumber;
|
|
7979
8044
|
if (/^[+-]?(?:\d+\.?\d*|\.\d+)$/.test(trimmed)) {
|
|
7980
8045
|
const parsed = Number(trimmed);
|
|
7981
8046
|
if (Number.isFinite(parsed)) {
|
|
@@ -8395,6 +8460,7 @@ function useXlsxViewerController(options) {
|
|
|
8395
8460
|
deferLoadingAboveBytes = DEFAULT_DEFER_LOADING_ABOVE_BYTES,
|
|
8396
8461
|
file,
|
|
8397
8462
|
fileName,
|
|
8463
|
+
locale = "en-US",
|
|
8398
8464
|
maxFileSizeBytes = DEFAULT_MAX_FILE_SIZE_BYTES,
|
|
8399
8465
|
readOnly: requestedReadOnly = false,
|
|
8400
8466
|
readOnlyAboveBytes = 0,
|
|
@@ -9209,14 +9275,14 @@ function useXlsxViewerController(options) {
|
|
|
9209
9275
|
formula: ""
|
|
9210
9276
|
});
|
|
9211
9277
|
}
|
|
9212
|
-
return getWorkerClient().getCellSnapshot(workbookSheetIndex, row, col);
|
|
9213
|
-
}, [getWorkerClient, isWorkerBacked]);
|
|
9278
|
+
return getWorkerClient().getCellSnapshot(workbookSheetIndex, row, col, locale);
|
|
9279
|
+
}, [getWorkerClient, isWorkerBacked, locale]);
|
|
9214
9280
|
const getRowsBatchAsync = React.useCallback((workbookSheetIndex, startRow, rowCount) => {
|
|
9215
9281
|
if (!isWorkerBacked) {
|
|
9216
9282
|
return Promise.resolve(null);
|
|
9217
9283
|
}
|
|
9218
|
-
return getWorkerClient().getRowsBatch(workbookSheetIndex, startRow, rowCount);
|
|
9219
|
-
}, [getWorkerClient, isWorkerBacked]);
|
|
9284
|
+
return getWorkerClient().getRowsBatch(workbookSheetIndex, startRow, rowCount, locale);
|
|
9285
|
+
}, [getWorkerClient, isWorkerBacked, locale]);
|
|
9220
9286
|
const visibleSheetIndexByWorkbookSheetIndex = React.useMemo(
|
|
9221
9287
|
() => new Map(sheets.map((sheet, index) => [sheet.workbookSheetIndex, index])),
|
|
9222
9288
|
[sheets]
|
|
@@ -9429,7 +9495,7 @@ function useXlsxViewerController(options) {
|
|
|
9429
9495
|
}, [activeSheet?.showGridLines, activeSheet?.workbookSheetIndex]);
|
|
9430
9496
|
const getCellDisplayValue2 = React.useCallback((cell) => {
|
|
9431
9497
|
if (cell && activeSheet) {
|
|
9432
|
-
const workerSnapshot = workerCellSnapshotCacheRef.current.get(`${activeSheet.workbookSheetIndex}:${cell.row}:${cell.col}`);
|
|
9498
|
+
const workerSnapshot = workerCellSnapshotCacheRef.current.get(`${locale}:${activeSheet.workbookSheetIndex}:${cell.row}:${cell.col}`);
|
|
9433
9499
|
if (workerSnapshot) {
|
|
9434
9500
|
return workerSnapshot.displayValue;
|
|
9435
9501
|
}
|
|
@@ -9442,7 +9508,7 @@ function useXlsxViewerController(options) {
|
|
|
9442
9508
|
const cachedFormulaValue = formula ? activeSheet?.cachedFormulaValues?.[cellAddressToA1(cell)] : void 0;
|
|
9443
9509
|
const formatted = worksheet.getFormattedValueAt(cell.row, cell.col);
|
|
9444
9510
|
if (formatted && !(formula && cachedFormulaValue !== void 0 && formatted.startsWith("#"))) {
|
|
9445
|
-
return decodeHtmlEntities(formatted);
|
|
9511
|
+
return localizeCellNumber(worksheet, cell.row, cell.col, decodeHtmlEntities(formatted), locale);
|
|
9446
9512
|
}
|
|
9447
9513
|
const calculated = worksheet.getCalculatedValueAt(cell.row, cell.col);
|
|
9448
9514
|
if (formula && cachedFormulaValue !== void 0 && calculated.is_error) {
|
|
@@ -9455,10 +9521,10 @@ function useXlsxViewerController(options) {
|
|
|
9455
9521
|
return "";
|
|
9456
9522
|
}
|
|
9457
9523
|
return calculated.toString();
|
|
9458
|
-
}, [activeSheet, getActiveWorksheet]);
|
|
9524
|
+
}, [activeSheet, getActiveWorksheet, locale]);
|
|
9459
9525
|
const getCellFormula = React.useCallback((cell) => {
|
|
9460
9526
|
if (cell && activeSheet) {
|
|
9461
|
-
const workerSnapshot = workerCellSnapshotCacheRef.current.get(`${activeSheet.workbookSheetIndex}:${cell.row}:${cell.col}`);
|
|
9527
|
+
const workerSnapshot = workerCellSnapshotCacheRef.current.get(`${locale}:${activeSheet.workbookSheetIndex}:${cell.row}:${cell.col}`);
|
|
9462
9528
|
if (workerSnapshot) {
|
|
9463
9529
|
return workerSnapshot.formula;
|
|
9464
9530
|
}
|
|
@@ -9468,7 +9534,7 @@ function useXlsxViewerController(options) {
|
|
|
9468
9534
|
return "";
|
|
9469
9535
|
}
|
|
9470
9536
|
return worksheet.getFormulaAt(cell.row, cell.col) ?? "";
|
|
9471
|
-
}, [activeSheet, getActiveWorksheet]);
|
|
9537
|
+
}, [activeSheet, getActiveWorksheet, locale]);
|
|
9472
9538
|
const getClipboardData = React.useCallback(() => {
|
|
9473
9539
|
const worksheet = getActiveWorksheet();
|
|
9474
9540
|
const targetRange = selection ?? (activeCell ? { start: activeCell, end: activeCell } : null);
|
|
@@ -9588,7 +9654,7 @@ function useXlsxViewerController(options) {
|
|
|
9588
9654
|
if (!isWorkerBacked || !deferredMetadataSheet || !deferredMetadataCell) {
|
|
9589
9655
|
return;
|
|
9590
9656
|
}
|
|
9591
|
-
const cacheKey = `${deferredMetadataSheet.workbookSheetIndex}:${deferredMetadataCell.row}:${deferredMetadataCell.col}`;
|
|
9657
|
+
const cacheKey = `${locale}:${deferredMetadataSheet.workbookSheetIndex}:${deferredMetadataCell.row}:${deferredMetadataCell.col}`;
|
|
9592
9658
|
if (workerCellSnapshotCacheRef.current.has(cacheKey)) {
|
|
9593
9659
|
return;
|
|
9594
9660
|
}
|
|
@@ -9612,7 +9678,7 @@ function useXlsxViewerController(options) {
|
|
|
9612
9678
|
return () => {
|
|
9613
9679
|
isCurrent = false;
|
|
9614
9680
|
};
|
|
9615
|
-
}, [deferredMetadataCell, deferredMetadataSheet, getCellSnapshotAsync, isWorkerBacked]);
|
|
9681
|
+
}, [deferredMetadataCell, deferredMetadataSheet, getCellSnapshotAsync, isWorkerBacked, locale]);
|
|
9616
9682
|
const activeCellAddress = React.useMemo(() => activeCell ? cellAddressToA1(activeCell) : null, [activeCell]);
|
|
9617
9683
|
const selectedRangeAddress = React.useMemo(() => selection ? rangeToA1(selection) : null, [selection]);
|
|
9618
9684
|
const selectedValue = React.useMemo(
|
|
@@ -9994,12 +10060,19 @@ function useXlsxViewerController(options) {
|
|
|
9994
10060
|
downloadUrl(src, displayFileName);
|
|
9995
10061
|
}
|
|
9996
10062
|
}, [displayFileName, file, src]);
|
|
9997
|
-
const
|
|
10063
|
+
const getXlsxBytes = React.useCallback(() => {
|
|
9998
10064
|
if (!workbook) {
|
|
10065
|
+
return null;
|
|
10066
|
+
}
|
|
10067
|
+
return createSavedWorkbookBytes(workbook);
|
|
10068
|
+
}, [createSavedWorkbookBytes, workbook]);
|
|
10069
|
+
const exportXlsx = React.useCallback(() => {
|
|
10070
|
+
const bytes = getXlsxBytes();
|
|
10071
|
+
if (!bytes) {
|
|
9999
10072
|
return;
|
|
10000
10073
|
}
|
|
10001
|
-
downloadBytes(
|
|
10002
|
-
}, [
|
|
10074
|
+
downloadBytes(bytes, `${fileStem(displayFileName)}.xlsx`, XLSX_MIME_TYPE);
|
|
10075
|
+
}, [displayFileName, getXlsxBytes]);
|
|
10003
10076
|
const exportCsv = React.useCallback(() => {
|
|
10004
10077
|
if (!workbook) {
|
|
10005
10078
|
return;
|
|
@@ -10462,7 +10535,8 @@ function useXlsxViewerController(options) {
|
|
|
10462
10535
|
if (!before) {
|
|
10463
10536
|
return;
|
|
10464
10537
|
}
|
|
10465
|
-
|
|
10538
|
+
if (locale !== "en-US" && value === getCellDisplayValue2(cell)) return;
|
|
10539
|
+
const nextValue = coerceUserEnteredValue(value, locale);
|
|
10466
10540
|
worksheet.setCell(cellAddressToA1(cell), nextValue);
|
|
10467
10541
|
const after = captureCellMutationState(cell);
|
|
10468
10542
|
if (!after) {
|
|
@@ -10471,7 +10545,7 @@ function useXlsxViewerController(options) {
|
|
|
10471
10545
|
maybeRecalculateWorkbook(workbook);
|
|
10472
10546
|
refreshWorkbookState(workbook);
|
|
10473
10547
|
recordCellEditHistory(cell, before, after);
|
|
10474
|
-
}, [captureCellMutationState, getActiveWorksheet, maybeRecalculateWorkbook, readOnly, recordCellEditHistory, refreshWorkbookState, workbook]);
|
|
10548
|
+
}, [captureCellMutationState, getActiveWorksheet, getCellDisplayValue2, locale, maybeRecalculateWorkbook, readOnly, recordCellEditHistory, refreshWorkbookState, workbook]);
|
|
10475
10549
|
const setCellFormula = React.useCallback((cell, formula) => {
|
|
10476
10550
|
const worksheet = getActiveWorksheet();
|
|
10477
10551
|
if (readOnly || !worksheet || !workbook) {
|
|
@@ -10812,7 +10886,7 @@ function useXlsxViewerController(options) {
|
|
|
10812
10886
|
cell: nextCell
|
|
10813
10887
|
});
|
|
10814
10888
|
} else {
|
|
10815
|
-
const nextValue = coerceUserEnteredValue(rawValue);
|
|
10889
|
+
const nextValue = coerceUserEnteredValue(rawValue, locale);
|
|
10816
10890
|
worksheet.setCell(cellAddressToA1(nextCell), nextValue);
|
|
10817
10891
|
const after = captureCellMutationState(nextCell);
|
|
10818
10892
|
if (!after) {
|
|
@@ -10840,7 +10914,7 @@ function useXlsxViewerController(options) {
|
|
|
10840
10914
|
selectionAnchorRef.current = targetCell;
|
|
10841
10915
|
recordRangeEditHistory(mutations, nextRange, targetCell);
|
|
10842
10916
|
return true;
|
|
10843
|
-
}, [activeCell, captureCellMutationState, getActiveWorksheet, maybeRecalculateWorkbook, readOnly, recordRangeEditHistory, refreshWorkbookState, selection, workbook]);
|
|
10917
|
+
}, [activeCell, captureCellMutationState, getActiveWorksheet, locale, maybeRecalculateWorkbook, readOnly, recordRangeEditHistory, refreshWorkbookState, selection, workbook]);
|
|
10844
10918
|
const pasteStructuredClipboardData = React.useCallback((serializedPayload) => {
|
|
10845
10919
|
const worksheet = getActiveWorksheet();
|
|
10846
10920
|
const targetCell = activeCell ?? selection?.start ?? null;
|
|
@@ -11113,9 +11187,11 @@ function useXlsxViewerController(options) {
|
|
|
11113
11187
|
deferredLoadFileSize,
|
|
11114
11188
|
defineNamedRange,
|
|
11115
11189
|
displayFileName,
|
|
11190
|
+
locale,
|
|
11116
11191
|
download,
|
|
11117
11192
|
exportCsv,
|
|
11118
11193
|
exportXlsx,
|
|
11194
|
+
getXlsxBytes,
|
|
11119
11195
|
error,
|
|
11120
11196
|
fillSelection,
|
|
11121
11197
|
formControls,
|
|
@@ -11235,10 +11311,12 @@ function useXlsxViewerController(options) {
|
|
|
11235
11311
|
deferredLoadFileSize,
|
|
11236
11312
|
defineNamedRange,
|
|
11237
11313
|
displayFileName,
|
|
11314
|
+
locale,
|
|
11238
11315
|
download,
|
|
11239
11316
|
error,
|
|
11240
11317
|
exportCsv,
|
|
11241
11318
|
exportXlsx,
|
|
11319
|
+
getXlsxBytes,
|
|
11242
11320
|
file,
|
|
11243
11321
|
fillSelection,
|
|
11244
11322
|
formControls,
|
|
@@ -13566,12 +13644,12 @@ function measureTextWidth(value, style) {
|
|
|
13566
13644
|
context.font = buildCanvasFont(style);
|
|
13567
13645
|
return measureCanvasTextWidth(context, value);
|
|
13568
13646
|
}
|
|
13569
|
-
function getCellDisplayValue(worksheet, row, col, activeSheet) {
|
|
13647
|
+
function getCellDisplayValue(worksheet, row, col, activeSheet, locale = "en-US") {
|
|
13570
13648
|
const formula = worksheet.getFormulaAt(row, col);
|
|
13571
13649
|
const cachedFormulaValue = formula ? activeSheet?.cachedFormulaValues?.[cellAddressToA12({ row, col })] : void 0;
|
|
13572
13650
|
const formatted = worksheet.getFormattedValueAt(row, col);
|
|
13573
13651
|
if (formatted && !(formula && cachedFormulaValue !== void 0 && formatted.startsWith("#"))) {
|
|
13574
|
-
return decodeHtmlEntities2(formatted);
|
|
13652
|
+
return localizeCellNumber(worksheet, row, col, decodeHtmlEntities2(formatted), locale);
|
|
13575
13653
|
}
|
|
13576
13654
|
const cellValue = worksheet.getCalculatedValueAt(row, col);
|
|
13577
13655
|
if (formula && cachedFormulaValue !== void 0 && cellValue.is_error) {
|
|
@@ -13621,6 +13699,7 @@ function getBatchedCellNumericValue(cell) {
|
|
|
13621
13699
|
if (!cell) {
|
|
13622
13700
|
return null;
|
|
13623
13701
|
}
|
|
13702
|
+
if (cell.numericValue !== void 0) return cell.numericValue;
|
|
13624
13703
|
const text = cell.value.trim();
|
|
13625
13704
|
if (text.length === 0) {
|
|
13626
13705
|
return null;
|
|
@@ -13836,6 +13915,7 @@ function buildWorksheetBatchWindow(rows, activeSheet, startRow, endRow) {
|
|
|
13836
13915
|
const formula = typeof cellEntry.formula === "string" ? cellEntry.formula : null;
|
|
13837
13916
|
cells.set(`${row}:${col}`, {
|
|
13838
13917
|
formula,
|
|
13918
|
+
numericValue: typeof cellEntry.numericValue === "number" ? cellEntry.numericValue : cellEntry.numericValue === null ? null : void 0,
|
|
13839
13919
|
generalAlignment: cellEntry.generalAlignment === "right" || cellEntry.generalAlignment === "center" ? cellEntry.generalAlignment : "left",
|
|
13840
13920
|
hyperlink: normalizeBatchedHyperlink(cellEntry.hyperlink),
|
|
13841
13921
|
isMergedSecondary: cellEntry.isMergedSecondary === true,
|
|
@@ -15721,6 +15801,7 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
15721
15801
|
getSheetFormControls,
|
|
15722
15802
|
getSheetImages,
|
|
15723
15803
|
getSheetShapes,
|
|
15804
|
+
locale,
|
|
15724
15805
|
workbook,
|
|
15725
15806
|
sheets
|
|
15726
15807
|
} = useXlsxViewer();
|
|
@@ -15742,6 +15823,11 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
15742
15823
|
isMountedRef.current = false;
|
|
15743
15824
|
};
|
|
15744
15825
|
}, []);
|
|
15826
|
+
React4.useEffect(() => {
|
|
15827
|
+
workerThumbnailRowBatchCacheRef.current.clear();
|
|
15828
|
+
workerThumbnailRowBatchRequestRef.current.clear();
|
|
15829
|
+
setWorkerThumbnailRowBatchVersion((version) => version + 1);
|
|
15830
|
+
}, [locale]);
|
|
15745
15831
|
React4.useEffect(() => {
|
|
15746
15832
|
const currentSheets = new Set(sheets);
|
|
15747
15833
|
for (const sheet of workerThumbnailRowBatchCacheRef.current.keys()) {
|
|
@@ -16090,7 +16176,7 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
16090
16176
|
col,
|
|
16091
16177
|
sheet,
|
|
16092
16178
|
() => worksheet ? getCellNumericValue(worksheet, row, col) : getBatchedCellNumericValue(batchedCell),
|
|
16093
|
-
() => worksheet ? getCellDisplayValue(worksheet, row, col, sheet) : batchedCell?.value ?? "",
|
|
16179
|
+
() => worksheet ? getCellDisplayValue(worksheet, row, col, sheet, locale) : batchedCell?.value ?? "",
|
|
16094
16180
|
worksheet,
|
|
16095
16181
|
workerRowBatch?.cells
|
|
16096
16182
|
);
|
|
@@ -16127,7 +16213,7 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
16127
16213
|
showGridLines
|
|
16128
16214
|
}),
|
|
16129
16215
|
textRotationDeg: resolveSpreadsheetTextRotation(alignment?.rotation ?? alignment?.textRotation),
|
|
16130
|
-
value: sparkline ? "" : checkboxState !== null ? "" : worksheet ? getCellDisplayValue(worksheet, row, col, sheet) : batchedCell?.value ?? ""
|
|
16216
|
+
value: sparkline ? "" : checkboxState !== null ? "" : worksheet ? getCellDisplayValue(worksheet, row, col, sheet, locale) : batchedCell?.value ?? ""
|
|
16131
16217
|
};
|
|
16132
16218
|
nextData.canvas = buildCanvasCellStyleCache(nextData.style);
|
|
16133
16219
|
cellRenderCache.set(cacheKey, nextData);
|
|
@@ -16399,6 +16485,7 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
16399
16485
|
sheets,
|
|
16400
16486
|
thumbnailImageLoadVersion,
|
|
16401
16487
|
workerThumbnailRowBatchVersion,
|
|
16488
|
+
locale,
|
|
16402
16489
|
workbook
|
|
16403
16490
|
]);
|
|
16404
16491
|
const paintThumbnail = React4.useCallback(
|