JS生成带目录水印的PDF

216 阅读2分钟

背景:为了避免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('目录项...'); // 生成目录项,对应着上面新增的页面 
}

6.其他PDF生成工具