Skip to content

Commit 4711c08

Browse files
authored
feat(docx): add locale configuration for docx export (#1937)
1 parent 763a604 commit 4711c08

File tree

5 files changed

+39
-6
lines changed

5 files changed

+39
-6
lines changed

packages/xl-docx-exporter/src/docx/__snapshots__/basic/styles.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<w:kern w:val="2"/>
88
<w:sz w:val="24"/>
99
<w:szCs w:val="24"/>
10-
<w:lang w:val="en-NL" w:eastAsia="en-GB" w:bidi="ar-SA"/>
10+
<w:lang w:val="en-US" w:eastAsia="en-GB" w:bidi="ar-SA"/>
1111
<w14:ligatures w14:val="standardContextual"/>
1212
</w:rPr>
1313
</w:rPrDefault>

packages/xl-docx-exporter/src/docx/__snapshots__/withMultiColumn/styles.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<w:kern w:val="2"/>
88
<w:sz w:val="24"/>
99
<w:szCs w:val="24"/>
10-
<w:lang w:val="en-NL" w:eastAsia="en-GB" w:bidi="ar-SA"/>
10+
<w:lang w:val="en-US" w:eastAsia="en-GB" w:bidi="ar-SA"/>
1111
<w14:ligatures w14:val="standardContextual"/>
1212
</w:rPr>
1313
</w:rPrDefault>

packages/xl-docx-exporter/src/docx/docxExporter.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ describe("exporter", () => {
2828
}),
2929
docxDefaultSchemaMappings,
3030
);
31-
const doc = await exporter.toDocxJsDocument(testDocument);
31+
const doc = await exporter.toDocxJsDocument(testDocument, {
32+
sectionOptions: {},
33+
documentOptions: {},
34+
locale: "en-US",
35+
});
3236

3337
const blob = await Packer.toBlob(doc);
3438
const zip = new ZipReader(new BlobReader(blob));
@@ -56,6 +60,7 @@ describe("exporter", () => {
5660
);
5761

5862
const doc = await exporter.toDocxJsDocument(testDocument, {
63+
locale: "en-US",
5964
documentOptions: {
6065
creator: "John Doe",
6166
},
@@ -181,6 +186,7 @@ describe("exporter", () => {
181186
],
182187
},
183188
]),
189+
{ sectionOptions: {}, documentOptions: {}, locale: "en-US" },
184190
);
185191

186192
const blob = await Packer.toBlob(doc);

packages/xl-docx-exporter/src/docx/docxExporter.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,21 @@ export class DOCXExporter<
187187
];
188188
}
189189

190-
protected async createDefaultDocumentOptions(): Promise<DocumentOptions> {
191-
const externalStyles = (await import("./template/word/styles.xml?raw"))
190+
protected async createDefaultDocumentOptions(
191+
locale?: string,
192+
): Promise<DocumentOptions> {
193+
let externalStyles = (await import("./template/word/styles.xml?raw"))
192194
.default;
193195

196+
// Replace the default language in styles.xml with the provided locale.
197+
// If not provided, default to en-US.
198+
const resolvedLocale = (locale && locale.trim()) || "en-US";
199+
200+
externalStyles = externalStyles.replace(
201+
/(<w:lang\b[^>]*\bw:val=")([^"]+)("[^>]*\/>)/g,
202+
`$1${resolvedLocale}$3`,
203+
);
204+
194205
const bullets = ["•"]; //, "◦", "▪"]; (these don't look great, just use solid bullet for now)
195206
return {
196207
numbering: {
@@ -247,6 +258,11 @@ export class DOCXExporter<
247258
options: {
248259
sectionOptions: Omit<ISectionOptions, "children">;
249260
documentOptions: DocumentOptions;
261+
/**
262+
* The document locale in OOXML format (e.g. en-US, fr-FR, de-DE).
263+
* If omitted, defaults to en-US.
264+
*/
265+
locale?: string;
250266
} = {
251267
sectionOptions: {},
252268
documentOptions: {},
@@ -276,13 +292,18 @@ export class DOCXExporter<
276292
options: {
277293
sectionOptions: Omit<ISectionOptions, "children">;
278294
documentOptions: DocumentOptions;
295+
/**
296+
* The document locale in OOXML format (e.g. en-US, fr-FR, de-DE).
297+
* If omitted, defaults to en-US.
298+
*/
299+
locale?: string;
279300
} = {
280301
sectionOptions: {},
281302
documentOptions: {},
282303
},
283304
) {
284305
const doc = new Document({
285-
...(await this.createDefaultDocumentOptions()),
306+
...(await this.createDefaultDocumentOptions(options.locale)),
286307
...options.documentOptions,
287308
sections: [
288309
{

shared/util/fileUtil.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ export async function loadFileBuffer(requireUrl: {
3636
if (url.startsWith("/@fs/")) {
3737
url = url.substring("/@fs".length);
3838
}
39+
// On Windows, vite/vitest may yield paths like "/C:/..." after removing /@fs
40+
// Node on Windows treats paths starting with "/" as relative to current drive,
41+
// which would produce "C:\C:\...". Strip leading slash when followed by a drive letter.
42+
if (/^\/[A-Za-z]:/.test(url)) {
43+
url = url.slice(1);
44+
}
3945
const buffer = fs.readFileSync(url);
4046
return buffer;
4147
} else {

0 commit comments

Comments
 (0)