Skip to content

Commit 8fcd63b

Browse files
committed
[FIX] xlsx: preserve leading whitespace at export
If a shared string has leading/trailing whitespace, it should have the attribute `xml:space="preserve"` otherwise the whitespace is trimmed in Excel. closes #5408 Task: 4044862 Signed-off-by: Rémi Rahir (rar) <[email protected]> Signed-off-by: Adrien Minne (adrm) <[email protected]>
1 parent 207b1c4 commit 8fcd63b

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

src/xlsx/xlsx_writer.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,12 @@ function createSharedStrings(strings: string[]): XLSXExportFile {
285285
["uniqueCount", strings.length],
286286
];
287287

288-
const stringNodes = strings.map((string) => escapeXml/*xml*/ `<si><t>${string}</t></si>`);
288+
const stringNodes = strings.map((string) => {
289+
if (string.trim() !== string) {
290+
return escapeXml/*xml*/ `<si><t xml:space="preserve">${string}</t></si>`;
291+
}
292+
return escapeXml/*xml*/ `<si><t>${string}</t></si>`;
293+
});
289294

290295
const xml = escapeXml/*xml*/ `
291296
<sst ${formatAttributes(namespaces)}>

tests/xlsx/xlsx_export.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,20 @@ describe("Test XLSX export", () => {
852852
expect(styles[1].querySelector("alignment")!.getAttribute("wrapText")).toBe("1");
853853
});
854854

855+
test("Leading and trailing whitespace in strings are preserved", async () => {
856+
const model = new Model();
857+
setCellContent(model, "A1", " Multiline with\n leading and trailing spaces\n ");
858+
859+
const exportedXlsx = await exportPrettifiedXlsx(model);
860+
const sharedStrings = parseXML(
861+
exportedXlsx.files.find((f) => f["contentType"] === "sharedStrings")!["content"]
862+
);
863+
864+
const string = sharedStrings.querySelector("si t")!;
865+
expect(string.getAttribute("xml:space")).toBe("preserve");
866+
expect(string.textContent).toBe(" Multiline with\n leading and trailing spaces\n ");
867+
});
868+
855869
describe("formulas", () => {
856870
beforeAll(() => {
857871
functionRegistry.add("NOW", {

0 commit comments

Comments
 (0)