From 4119e22ecd0e726e1ce58d7b7a813dce076ea5a7 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Thu, 6 Aug 2026 12:08:07 +0200 Subject: [PATCH] feat(xl-pdf-exporter): add custom font and fontFamily options for CJK support Fixes #2037 --- packages/xl-pdf-exporter/src/pdf/index.ts | 1 + .../xl-pdf-exporter/src/pdf/pdfExporter.tsx | 32 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/xl-pdf-exporter/src/pdf/index.ts b/packages/xl-pdf-exporter/src/pdf/index.ts index ea872e9feb..e4dffb6d25 100644 --- a/packages/xl-pdf-exporter/src/pdf/index.ts +++ b/packages/xl-pdf-exporter/src/pdf/index.ts @@ -1,2 +1,3 @@ export * from "./defaultSchema/index.js"; export * from "./pdfExporter.jsx"; +export { Font } from "@react-pdf/renderer"; diff --git a/packages/xl-pdf-exporter/src/pdf/pdfExporter.tsx b/packages/xl-pdf-exporter/src/pdf/pdfExporter.tsx index 6d8962eaaf..f91ec93a86 100644 --- a/packages/xl-pdf-exporter/src/pdf/pdfExporter.tsx +++ b/packages/xl-pdf-exporter/src/pdf/pdfExporter.tsx @@ -35,6 +35,26 @@ type Options = ExporterOptions & { * @default uses Twemoji images from jdecked/twemoji on jsDelivr CDN */ emojiSource: false | ReturnType; + /** + * Additional fonts to register for PDF rendering. + * Each entry is passed directly to react-pdf's `Font.register()`. + * + * Useful for adding support for non-Latin scripts (e.g., CJK characters). + * + * @example + * fonts: [ + * { + * family: "NotoSansSC", + * src: "https://fonts.gstatic.com/s/notosanssc/...", + * }, + * ], + */ + fonts?: Parameters[0][]; + /** + * Override the default font family for the PDF document. + * @default "Inter" + */ + fontFamily?: string; }; /** @@ -243,6 +263,12 @@ export class PDFExporter< src: font, }); + if (this.options.fonts) { + for (const f of this.options.fonts) { + Font.register(f); + } + } + this.fontsRegistered = true; } @@ -266,9 +292,13 @@ export class PDFExporter< ) { await this.registerFonts(); + const pageStyle = this.options.fontFamily + ? { ...this.styles.page, fontFamily: this.options.fontFamily } + : this.styles.page; + return ( - + {options.header && ( {options.header}