Angular 7中如何遍历PDF页面并通过jsPDF插入页码
Angular 7 基于jsPDF为现有PDF插入页码解决方案
前置依赖说明
原生jsPDF不支持直接编辑已存在的PDF文件,需要配合PDF.js(pdfjs-dist包)解析原始PDF的每页内容,逐页写入新jsPDF实例后追加页码。
步骤1:安装依赖
执行npm安装对应包,推荐使用兼容Angular7的版本:
npm install jspdf@2.5.1 pdfjs-dist@2.16.105
然后在angular.json的build.options.assets中增加PDF.js worker的资源配置:
{ "glob": "**/*.worker.min.js", "input": "node_modules/pdfjs-dist/build/", "output": "/assets/pdfjs/" }
步骤2:完整业务代码实现
在你的组件中引入依赖,修改原HTTP请求后的处理逻辑:
import * as jsPDF from 'jspdf'; import * as pdfjsLib from 'pdfjs-dist'; // 配置PDF.js worker路径 pdfjsLib.GlobalWorkerOptions.workerSrc = '/assets/pdfjs/pdf.worker.min.js'; // 原有PDF获取逻辑 let headers = new HttpHeaders(); headers = headers.set('Accept', 'application/pdf'); this.http.get('/assets/pdf/myTest.pdf', { headers: headers, responseType: 'blob' }).subscribe(async data => { // 1. 把Blob转成ArrayBuffer供PDF.js解析 const arrayBuffer = await data.arrayBuffer(); const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise; const totalPages = pdf.numPages; // 2. 初始化jsPDF实例 const doc = new jsPDF.jsPDF(); doc.page = 1; // 页码插入方法 const addFooter = () => { // 适配当前页尺寸的右下角位置,可根据需求调整坐标 const pageWidth = doc.internal.pageSize.getWidth(); const pageHeight = doc.internal.pageSize.getHeight(); doc.text(pageWidth - 20, pageHeight - 10, `page ${doc.page} / ${totalPages}`); doc.page++; } // 3. 遍历每一页处理 for (let i = 1; i <= totalPages; i++) { const page = await pdf.getPage(i); const viewport = page.getViewport({ scale: 2 }); // 缩放系数控制清晰度 // 创建canvas渲染PDF页 const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; // 渲染页到canvas await page.render({ canvasContext: context, viewport: viewport }).promise; // 把canvas转成图片插入jsPDF const imgData = canvas.toDataURL('image/png'); const imgWidth = doc.internal.pageSize.getWidth(); const imgHeight = (viewport.height * imgWidth) / viewport.width; // 第一页不需要addPage,从第二页开始新增 if (i > 1) { doc.addPage([imgWidth, imgHeight]); } else { doc.setPageSize([imgWidth, imgHeight]); } doc.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight); // 插入当前页页码 addFooter(); } // 4. 导出结果,可根据需求替换为上传等逻辑 doc.save('加页码后的文件.pdf'); });
备选无失真方案
如果可以接受额外依赖,推荐使用pdf-lib直接操作PDF原始内容,不需要转图片渲染,性能和画质都更好,核心逻辑是加载原始PDF后,在每一页的画布上直接绘制页码文字,最终导出新的PDF即可。
常见踩坑点
- 如果出现PDF.js worker加载失败,检查angular.json的资源配置路径是否正确
- 原始PDF如果是非标准尺寸,可通过调整
addFooter方法中的坐标适配页码位置 - 渲染清晰度可以通过调整
getViewport的scale参数控制,数值越大越清晰但文件体积也会越大
内容的提问来源于stack exchange,提问作者Iswar
相关产品推荐
相关产品推荐

