Normalize QExcell sheet names for XLSX export

This commit is contained in:
Курнат Андрей
2026-06-02 19:13:50 +03:00
parent e857beabd0
commit 6251c70ddc
2 changed files with 81 additions and 7 deletions
+33
View File
@@ -37,6 +37,7 @@ import {
worksheetXmlToZoomScale,
xlsxStylesXmlToCellFormatTable,
xlsxThemeXmlToColors,
xlsxSafeSheetNames,
xlsxCellToText
} from "./excellOffice";
@@ -633,6 +634,38 @@ describe("excellOffice OOXML helpers", () => {
expect(imported.activeSheet).toBe("sheet-2");
});
it("normalizes XLSX sheet names to Excel-safe unique names on export", async () => {
expect(
xlsxSafeSheetNames([
{ name: "Sales/2026:Q1*?" },
{ name: "'Very long worksheet name that exceeds thirty one characters'" },
{ name: "Sales 2026 Q1" },
{ name: "'[]:*?/\\'" },
{ name: "History" }
])
).toEqual(["Sales 2026 Q1", "Very long worksheet name that e", "Sales 2026 Q1 (2)", "Лист 4", "History 1"]);
const blob = await exportXlsxBlob({
id: "book-1",
title: "Safe sheet names.xlsx",
updatedAt: "2026-06-01T00:00:00.000Z",
activeSheet: "sheet-1",
sheets: [
{ id: "sheet-1", name: "Sales/2026:Q1*?", printArea: "A1:B2", cells: { A1: "Sales" } },
{ id: "sheet-2", name: "Sales 2026 Q1", cells: { A1: "Duplicate" } }
]
});
const zip = await JSZip.loadAsync(await blob.arrayBuffer());
const workbookXml = await zip.file("xl/workbook.xml")?.async("string");
const imported = await importXlsxFile(new File([blob], "Safe sheet names.xlsx", { type: blob.type }));
expect(workbookXml).toContain('<sheet name="Sales 2026 Q1" sheetId="1" r:id="rId1"/>');
expect(workbookXml).toContain('<sheet name="Sales 2026 Q1 (2)" sheetId="2" r:id="rId2"/>');
expect(workbookXml).toContain('<definedName name="_xlnm.Print_Area" localSheetId="0">\'Sales 2026 Q1\'!$A$1:$B$2</definedName>');
expect(imported.sheets.map((sheet) => sheet.name)).toEqual(["Sales 2026 Q1", "Sales 2026 Q1 (2)"]);
expect(imported.sheets[0].printArea).toBe("A1:B2");
});
it("сохраняет и импортирует область печати XLSX через definedName _xlnm.Print_Area", async () => {
expect(
workbookPrintAreas(