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 @@
-
+
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 9e2ddfd6b6..6a79d5c53d 100644
--- a/packages/xl-docx-exporter/src/docx/docxExporter.ts
+++ b/packages/xl-docx-exporter/src/docx/docxExporter.ts
@@ -187,10 +187,21 @@ 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";
+
+ 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 +258,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 +292,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: [
{
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 {