如何为jsPDF从HTML生成的PDF设置自定义字体(不使用text方法)
解决jsPDF html方法自定义字体不生效问题
问题描述
已在jsPDF中通过自定义脚本添加Poppins字体,使用text()方法添加文本时字体正常生效,但通过html()方法将HTML元素转为PDF时字体不生效:HTML中显示的是Poppins字体样式,生成的PDF却显示为默认字体。当前使用最新版jsPDF。
原因分析
jsPDF的html()方法依赖浏览器渲染引擎(底层基于html2canvas),要让字体生效需满足三个条件:
- 字体已在浏览器环境中加载完成
- 目标HTML元素的样式明确指定了Poppins字体
- PDF能正确识别并嵌入该字体文件
解决方案
1. 在全局样式中加载Poppins字体
在项目全局样式文件(如styles.scss)中添加@font-face定义,确保浏览器能加载该字体:
@font-face { font-family: 'Poppins'; src: url('/assets/font/Poppins-Regular.ttf') format('truetype'); font-weight: normal; font-style: normal; }
如果使用Base64编码的字体,可替换src为:
src: url('data:font/truetype;base64,你的Base64字体内容') format('truetype');
2. 给目标HTML元素指定字体
在需要转为PDF的#print元素样式中,明确设置font-family:
方式1:内联样式(app.component.html)
<div #print style="font-family: 'Poppins', sans-serif;"> <!-- 你的PDF内容 --> </div>
方式2:组件样式(app.component.scss)
#print { font-family: 'Poppins', sans-serif; }
3. 优化jsPDF的html方法配置
调用html()时添加fontFaces选项,显式告知jsPDF要嵌入的字体,确保PDF中包含该字体文件:
generatePDF() { const doc = new jsPDF( 'portrait', 'pt', [595, 842], true ); const source = window.document.getElementById('print'); doc.html( this.el.nativeElement, { callback: (doc) => { doc.output('dataurlnewwindow'); }, width: 595, windowWidth: source!.offsetWidth, // 显式声明字体 fontFaces: [ { family: 'Poppins', src: 'url("/assets/font/Poppins-Regular.ttf") format("truetype")', weight: 'normal', style: 'normal' } ] } ); }
4. 确保字体加载完成后再生成PDF(可选)
若字体加载较慢,可监听字体加载状态,避免渲染时字体未就绪:
async generatePDF() { // 等待Poppins字体加载完成 await document.fonts.load('12px Poppins'); const doc = new jsPDF( 'portrait', 'pt', [595, 842], true ); const source = window.document.getElementById('print'); doc.html( this.el.nativeElement, { callback: (doc) => { doc.output('dataurlnewwindow'); }, width: 595, windowWidth: source!.offsetWidth } ); }
关键验证点
- 通过浏览器开发者工具的Network面板,确认Poppins字体文件已成功加载
- 执行
console.log(doc.getFontList()),确保输出结果中包含Poppins字体
内容的提问来源于stack exchange,提问作者Matoosh
相关产品推荐
相关产品推荐

