背景:为了避免PDF生成占用服务器的计算资源,故需要前端方面生成PDF文件。
- 1.pdf生成工具介绍
- 2.配置pdfkit字体
- 3.绘制时使用字体
- 4.水印生成方式
- 5.生成目录大纲
1.pdf生成工具介绍
本文使用到的工具为pdfkit工具,优点是可以自动分页,生成pdf内容可定制性强(单独字体样式控制等);与使用html文档生成PDF的工具相比,pdfkit缺点是内容样式需要自己配置,但对于导出文本内容来说也是足够了。
pdfkit工具在线体验链接: pdfkit.org/demo/browse…
pdfkit文档链接: pdfkit.org/docs/gettin…
2.配置pdfkit字体
按照pdfkit的文档描述,可以通过以下方式来配置绘制时使用的字体。
1)使用URL引用字体,该方式会在绘制前下载网络字体,然后使用字体开始绘制。需要注意的是字体文件的内容必须为base64格式。
export class PdfMakerService {
// ...other code
private fontConfig = {
FZYTK: "<CDN地址>/FZYTK.data", // 注意数据必须是Base64串
} // 字体配置
}
2)在项目中配置静态文件,通过ESM引入该静态字体文件,同样字体也必须是base64的格式。
import staticFont from '...' // to do something...
3.绘制时使用字体
1)pdfkit提供了以Unit8Array,ArrayBuffer等方式的注册字体方式,本文使用的是ArrayBuffer的方式:
const base64ToArrayBuffer = (base64: string) =>{
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
const doc = new PDFDocument(this.pdfDocOptions);
const fontArrayBuffer = base64ToArrayBuffer(this.downloadFont('FZYTK'))
doc.registerFont(font, fontArrayBuffer) // 注册字体
doc.font('FZYTK') // 使用该字体
4.水印生成方式
使用Canvas绘制水印图片即可。
const generateWaterPrint = () => {
// generating waterwark using canvas...
return canvas.toDataURL("image/jpeg")
}
pdfkit提供了钩子函数给我们加水印提供了支持:
// 每次页面增加时添加水印
doc.on('pageAdded', () => {
doc.image(WATER_PRINT, 0, 0, { width: doc.page.width, height: doc.page.height });
});
5.生成目录大纲
目前pdfkit只支持页面级别的跳转,故在需要跳转到的页面加上大纲标记即可,pdfkit会收集标记对应的页面关系,生成大纲。
doc.addPage(options)
if(shouldAddOutlineItem) {
doc.outline.addItem('目录项...'); // 生成目录项,对应着上面新增的页面
}