Display Chinese Character when Export as PDF with pdfkit
My project currently need support for Chinese characters when export PDF, so I will share a bit how to easily to archive that using pdfkit
First of all, you need to install pdfkit
npm install pdfkit
Download a Font that Supports Chinese Characters:
Download a font that supports Chinese characters, such as Noto Sans CJK. You can download it from Google Fonts.
Create a PDF with Chinese Characters:
Example Code:
const PDFDocument = require("pdfkit");
const fs = require("fs");
// Create a document
const doc = new PDFDocument();
// Pipe its output somewhere, like to a file or HTTP response
// See below for browser usage
doc.pipe(fs.createWriteStream("output.pdf"));
// Register a font that supports Chinese characters
doc.registerFont("NotoSansCJK", "path/to/NotoSansCJK-Regular.ttc");
// Use the registered font
doc.font("NotoSansCJK");
// Add some text with Chinese characters
doc.fontSize(25).text("你好,世界!", 100, 100);
// Finalize the PDF and end the stream
doc.end();
Running the Code:
Save the code to a file, for example, create-pdf.js, and run it using Node.js:
node create-pdf.js
If you want to use another font for normal text, and only use Chinese font for Chinese characters only, you can custom PDFDocument
Create CustomPDFDocument.ts file with following code snippet:
import PDFDocument from "pdfkit";
import {
NotoSansSC,
registerGTWalsheimFonts,
registerNotoSansSCFonts,
} from "./fonts";
class CustomPDFDocument extends PDFDocument {
constructor(options?: PDFKit.PDFDocumentOptions) {
super(options);
this.registerFont("GTWalsheim", "path/to/GT-Walsheim-Regular.ttc");
this.registerFont("NotoSansCJK", "path/to/NotoSansCJK-Regular.ttc");
}
containsChinese(text: string): boolean {
return /[\u3400-\u9FBF]/.test(text);
}
text(
text: string,
x?: number,
y?: number,
options?: PDFKit.Mixins.TextOptions
): this;
text(text: string, options?: PDFKit.Mixins.TextOptions): this;
text(
text: string,
xOrOptions?: number | PDFKit.Mixins.TextOptions,
y?: number,
options?: PDFKit.Mixins.TextOptions
): this {
let x: number | undefined;
if (typeof xOrOptions === "number") {
x = xOrOptions;
} else {
options = xOrOptions;
}
this.font("GTWalsheim");
if (this.containsChinese(text)) {
this.font("NotoSansCJK");
}
if (x !== undefined && y !== undefined) {
return super.text(text, x, y, options);
} else {
return super.text(text, options);
}
}
}
export default CustomPDFDocument;
Instead import PDFDocument from pdfkit, now we import from CustomPDFDocument
import PDFDocument from "path/to/CustomPDFDocument"
That's all