如何在React中使用@react-pdf/pdfkit添加自定义字体并解决相关报错
React.js 中 @react-pdf/pdfkit 添加自定义字体解决方案
报错根因
Unhandled Rejection (Error): fontkit.openSync unavailable for browser build 报错是因为@react-pdf/pdfkit的浏览器构建版本剔除了Node.js专属的文件系统同步读取能力,浏览器本身也不支持直接访问本地文件路径,所以你调用doc.registerFont(path, font_family)传文件路径的方式在浏览器环境下无法生效。
解决步骤
前置依赖安装
你需要额外安装blob-stream用于处理PDF流转换,方便后续下载:
npm install blob-stream # 或 yarn add blob-stream
核心实现逻辑
浏览器环境下只能传入二进制格式或Base64格式的字体数据注册字体,不能传本地文件路径,示例代码如下:
import PDFDocument from '@react-pdf/pdfkit' import blobStream from 'blob-stream' const generatePdfWithCustomFont = async () => { // 1. 初始化PDF实例 const doc = new PDFDocument() const stream = doc.pipe(blobStream()) // 2. 加载字体文件为二进制数据 // 字体文件放在public/fonts目录下,可直接通过fetch请求获取 const fontResponse = await fetch('/fonts/AlibabaPuHuiTi-Regular.ttf') const fontBuffer = await fontResponse.arrayBuffer() const fontUint8 = new Uint8Array(fontBuffer) // 3. 注册自定义字体,第一个参数传二进制数据而非文件路径 doc.registerFont(fontUint8, '阿里普惠体') // 4. 正常使用自定义字体生成PDF内容 doc.font('阿里普惠体') .fontSize(16) .text('测试自定义中文字体', 50, 50) doc.end() // 5. 导出下载PDF stream.on('finish', () => { const pdfBlob = stream.toBlob('application/pdf') const downloadUrl = URL.createObjectURL(pdfBlob) const aTag = document.createElement('a') aTag.href = downloadUrl aTag.download = '自定义字体测试.pdf' aTag.click() URL.revokeObjectURL(downloadUrl) }) } // 组件中调用即可触发生成下载 // <button onClick={generatePdfWithCustomFont}>下载PDF</button>
注意事项
- 如果你的项目是Vite构建,也可以直接将字体文件放在
src/assets目录下,通过导入时加?arraybuffer后缀直接获取二进制数据,不需要fetch:import customFont from '../assets/AlibabaPuHuiTi-Regular.ttf?arraybuffer' // 直接使用customFont作为registerFont的第一个参数即可 - 若不想在运行时请求字体文件,也可以提前将字体文件转成Base64字符串,直接传入
registerFont的第一个参数:doc.registerFont('data:font/ttf;base64,你提前转换好的字体Base64字符串', '自定义字体名') - 使用非拉丁字体(比如中文、日文)时,要确保字体文件包含对应字符集,避免PDF出现缺字乱码问题。
内容的提问来源于stack exchange,提问作者Ajil Paul
相关产品推荐
相关产品推荐

