From b4f23cc16f38607a169879638ef5c9a3c1f88fca Mon Sep 17 00:00:00 2001 From: Cyril Date: Tue, 12 Aug 2025 09:42:15 +0200 Subject: [PATCH 1/3] add locale configuration for docx export allows setting the default language in generated .docx files --- .../xl-docx-exporter/src/docx/docxExporter.ts | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/xl-docx-exporter/src/docx/docxExporter.ts b/packages/xl-docx-exporter/src/docx/docxExporter.ts index 9e2ddfd6b6..9684ac1f45 100644 --- a/packages/xl-docx-exporter/src/docx/docxExporter.ts +++ b/packages/xl-docx-exporter/src/docx/docxExporter.ts @@ -187,10 +187,22 @@ export class DOCXExporter< ]; } - protected async createDefaultDocumentOptions(): Promise { - const externalStyles = (await import("./template/word/styles.xml?raw")) + protected async createDefaultDocumentOptions( + locale?: string, + ): Promise { + let externalStyles = (await import("./template/word/styles.xml?raw")) .default; + // Replace the default language in styles.xml with the provided locale. + // If not provided, default to en-US. + const resolvedLocale = (locale && locale.trim()) || "en-US"; + // Replace w:lang w:val="..." with the desired locale, leaving other attributes intact + // This targets the run default language defined in styles.xml + externalStyles = externalStyles.replace( + /(]*\bw:val=")([^"]+)("[^>]*\/>)/g, + `$1${resolvedLocale}$3`, + ); + const bullets = ["•"]; //, "◦", "▪"]; (these don't look great, just use solid bullet for now) return { numbering: { @@ -247,6 +259,11 @@ export class DOCXExporter< options: { sectionOptions: Omit; documentOptions: DocumentOptions; + /** + * The document locale in OOXML format (e.g. en-US, fr-FR, de-DE). + * If omitted, defaults to en-US. + */ + locale?: string; } = { sectionOptions: {}, documentOptions: {}, @@ -276,13 +293,18 @@ export class DOCXExporter< options: { sectionOptions: Omit; documentOptions: DocumentOptions; + /** + * The document locale in OOXML format (e.g. en-US, fr-FR, de-DE). + * If omitted, defaults to en-US. + */ + locale?: string; } = { sectionOptions: {}, documentOptions: {}, }, ) { const doc = new Document({ - ...(await this.createDefaultDocumentOptions()), + ...(await this.createDefaultDocumentOptions(options.locale)), ...options.documentOptions, sections: [ { From 831cd8091af41904959e4749fcedf25741d9a1aa Mon Sep 17 00:00:00 2001 From: Cyril Date: Tue, 12 Aug 2025 10:09:45 +0200 Subject: [PATCH 2/3] update tests for configurable docx export locale add test cases to ensure the locale option correctly updates default language in generated .docx files and defaults to en-US when omitted --- packages/xl-docx-exporter/src/docx/docxExporter.test.ts | 8 +++++++- packages/xl-docx-exporter/src/docx/docxExporter.ts | 3 +-- shared/util/fileUtil.ts | 6 ++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/xl-docx-exporter/src/docx/docxExporter.test.ts b/packages/xl-docx-exporter/src/docx/docxExporter.test.ts index d9d3adeb2b..a7bf9edbb4 100644 --- a/packages/xl-docx-exporter/src/docx/docxExporter.test.ts +++ b/packages/xl-docx-exporter/src/docx/docxExporter.test.ts @@ -28,7 +28,11 @@ describe("exporter", () => { }), docxDefaultSchemaMappings, ); - const doc = await exporter.toDocxJsDocument(testDocument); + const doc = await exporter.toDocxJsDocument(testDocument, { + sectionOptions: {}, + documentOptions: {}, + locale: "en-US", + }); const blob = await Packer.toBlob(doc); const zip = new ZipReader(new BlobReader(blob)); @@ -56,6 +60,7 @@ describe("exporter", () => { ); const doc = await exporter.toDocxJsDocument(testDocument, { + locale: "en-US", documentOptions: { creator: "John Doe", }, @@ -181,6 +186,7 @@ describe("exporter", () => { ], }, ]), + { sectionOptions: {}, documentOptions: {}, locale: "en-US" }, ); const blob = await Packer.toBlob(doc); diff --git a/packages/xl-docx-exporter/src/docx/docxExporter.ts b/packages/xl-docx-exporter/src/docx/docxExporter.ts index 9684ac1f45..6a79d5c53d 100644 --- a/packages/xl-docx-exporter/src/docx/docxExporter.ts +++ b/packages/xl-docx-exporter/src/docx/docxExporter.ts @@ -196,8 +196,7 @@ export class DOCXExporter< // Replace the default language in styles.xml with the provided locale. // If not provided, default to en-US. const resolvedLocale = (locale && locale.trim()) || "en-US"; - // Replace w:lang w:val="..." with the desired locale, leaving other attributes intact - // This targets the run default language defined in styles.xml + externalStyles = externalStyles.replace( /(]*\bw:val=")([^"]+)("[^>]*\/>)/g, `$1${resolvedLocale}$3`, diff --git a/shared/util/fileUtil.ts b/shared/util/fileUtil.ts index 0a8c3d8ed4..6f77bf3a7a 100644 --- a/shared/util/fileUtil.ts +++ b/shared/util/fileUtil.ts @@ -36,6 +36,12 @@ export async function loadFileBuffer(requireUrl: { if (url.startsWith("/@fs/")) { url = url.substring("/@fs".length); } + // On Windows, vite/vitest may yield paths like "/C:/..." after removing /@fs + // Node on Windows treats paths starting with "/" as relative to current drive, + // which would produce "C:\C:\...". Strip leading slash when followed by a drive letter. + if (/^\/[A-Za-z]:/.test(url)) { + url = url.slice(1); + } const buffer = fs.readFileSync(url); return buffer; } else { From 6858ed853ecb04358b096fe5cd7790ac0632be1f Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Thu, 21 Aug 2025 15:42:19 +0200 Subject: [PATCH 3/3] test: update snapshots --- .../xl-docx-exporter/src/docx/__snapshots__/basic/styles.xml | 2 +- .../src/docx/__snapshots__/withMultiColumn/styles.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/xl-docx-exporter/src/docx/__snapshots__/basic/styles.xml b/packages/xl-docx-exporter/src/docx/__snapshots__/basic/styles.xml index d23b5bb2ff..fa0a655a69 100644 --- a/packages/xl-docx-exporter/src/docx/__snapshots__/basic/styles.xml +++ b/packages/xl-docx-exporter/src/docx/__snapshots__/basic/styles.xml @@ -7,7 +7,7 @@ - + diff --git a/packages/xl-docx-exporter/src/docx/__snapshots__/withMultiColumn/styles.xml b/packages/xl-docx-exporter/src/docx/__snapshots__/withMultiColumn/styles.xml index d23b5bb2ff..fa0a655a69 100644 --- a/packages/xl-docx-exporter/src/docx/__snapshots__/withMultiColumn/styles.xml +++ b/packages/xl-docx-exporter/src/docx/__snapshots__/withMultiColumn/styles.xml @@ -7,7 +7,7 @@ - +