Display Chinese Character when Export as PDF with pdfkit

NodeJS|SEPTEMBER 16, 2024|8 VIEWS
To display Chinese characters when exporting a PDF with pdfkit, you need to ensure that you are using a font that supports Chinese characters. By default, pdfkit does not include fonts that support Chinese characters, so you will need to use a custom font.

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