使用jsPDF+html2canvas导出PDF文件分页--可添加上下页边距
创始人
2024-11-10 11:38:18
0

一、常规思路

想要将html页面通过pdf文件导出,一般我们使用html2canvas+jsPDDF导出。
单纯使用jsPDF的html()方法要求导入全部字体,于是转换思路,先转成canvas,在通过贴图,贴到pdf中,代码如下:

安装:

npm html2canvas npm jspdf 

引入:

import html2canvas from 'html2canvas'; import jsPDF from 'jsPDF';  

具体代码:

// 生成pdf文件流 const elem =document.getElementById('reportContent'); const canvas = await html2canvas(elem!);     //以下是分页 // pdf的尺寸 const pdfWidth = canvas.width; //a4页面尺寸高比宽为1.414 const pdfHeight = pdfWidth * 1.414; let pageHeight = canvas.height; let position: number = 0; //贴图的宽高 const imgWidth = canvas.width; const imgHeight = imgWidth / canvas.width * canvas.height; //将canvas标签转化为base64码 const pageData = canvas.toDataURL('image/jpeg', 2.0); //创建pdf对象 const pdf = new jsPDF('p', 'pt', [pdfWidth, pdfHeight]); if(pageHeight < pageHeight) {     pdf.addImage(pageData, 'JPEG', 0, 0,imgWidth,imgHeight); } else {     while(pageHeight > 0) {         pdf.addImage(pageData, 'JPEG', 0, position,imgWidth,imgHeight);         position -= pdfHeight ;         pageHeight -= pdfHeight;         if(pageHeight > 0) {             //如果图片还没有贴完,继续添加pdf页             pdf.addPage();         }     } } //如果不需要直接下载,需要pdf的blob文件流,使用output const pdfBlob = pdf.output('blob'); //直接下载为pdf文件 pdf.save() 

参考:https://www.zhangxinxu.com/wordpress/2023/06/js-canvas-jspdf-export-pdf/

但是以上的方案,导出来的pdf页,每页是直接顶满,上下没有页边距,如下图:
在这里插入图片描述

想要添加上下页边距怎么弄呢?

二、通过裁剪canvas贴图

思路:将canvas进行裁剪,每页裁剪的高度,比pdf的页小一点,剩下的留为页边距
上代码:

//创绘制切割后绘制canvas用的canvas标签以及对应的context对象 const perCanvas = document.createElement('canvas'); perCanvas.style.backgroundColor = '#fff' const context  = perCanvas.getContext('2d');   // 将需要下载的html标签转成canvas标签,并获取对应的base64码 const elem =document.getElementById('reportContent'); const canvas = await html2canvas(elem!); const canvasData = canvas.toDataURL('image/jpeg', 1.0);   // pdf的尺寸 const pdfWidth = canvas.width; const pdfHeight = pdfWidth * 1.414;   //切割后的canvas图片的宽高,就等于每页pdf的宽高 perCanvas.width = canvas.width; perCanvas.height = pdfHeight;   // 每张图片的高度:适当减少100,上下各留50页边距 const perHeight = pdfHeight - 100;   // 计算切割次数 let splitCount = Math.ceil(canvas.height / perHeight); if(splitCount * perHeight < canvas.height) splitCount++;   //创建img对象,加载完整的canvas图片 const img = new Image(); img.src = canvasData;   //创建pdf对象 const pdf = new jsPDF('p', 'pt', [pdfWidth, pdfHeight]); //待图片加载完成 await setTimeout(() => {}, 5000)   //切割canvas图片,贴到每一页pdf中 for (let i = 0; i < splitCount; i++) {     const startY = i * perHeight; // 起始y坐标       // 清空画布     context!.clearRect(0, 0, perCanvas.width, pdfHeight);     context!.fillStyle = '#fff';     context!.fillRect(0, 0, perCanvas.width, pdfHeight);     // 绘制当前切割区域的图片     context!.drawImage(img, 0, startY, perCanvas.width, perHeight, 0, 0, perCanvas.width, perHeight);     const perCanvasData = perCanvas.toDataURL('image/jpeg', 1.0);     pdf.addImage( perCanvasData , 'JPEG', 0, 50,perCanvas.width,perCanvas.height);     if(i < splitCount - 1) pdf.addPage(); };   pdf.save(); 

这样导出的每一页pdf都留有上下页边距,如图:
在这里插入图片描述

三、遗留问题

不过这两种方式都存在一个问题:内容截断的问题:
有时候刚好分页裁剪时刚好在一行字的正中间,暂时没有解决办法,有待思考,等找到解决方案再来更新。

相关内容

热门资讯

欢乐棋牌!wepower有辅助... 欢乐棋牌!wepower有辅助器(透视挂)苹果版本教程-都是真的有挂(百度贴吧)1、许多玩家不知道欢...
WPk!wepoke透明真的(... WPk!wepoke透明真的(透视辅助)插件挂教程-原来真的有挂(微博热搜)1、操作简单,无需注册,...
aapOKER!wepoke辅... aapOKER!wepoke辅助透视教程(透视辅助)输赢教程-好像真的有挂(头条)1、aapOKER...
AaPOKER!wepoke挂... AaPOKER!wepoke挂(辅助挂)智能教程-原来真的有挂(抖音);1、AaPOKER机器人多个...
wpk有透视辅助!wepoke... wpk有透视辅助!wepoke辅助是真的,AApoker的确真的有挂,详细教程(有挂教程);该软件可...
AApOKER!wepoke中... AApOKER!wepoke中牌率(透视挂)系统教程-果真真的有挂(微博热搜)1、AApOKER!w...
微扑克辅助挂!wepoke里面... 微扑克辅助挂!wepoke里面有ai,We辅poker助原来真的有挂,揭秘攻略(有挂攻略);1、让任...
wepoke有挂!来玩app德... wepoke有挂!来玩app德州辅助器,poker master安卓版的确是有挂的,技巧教程(有挂规...
轰趴十三水!wepoke游戏数... 轰趴十三水!wepoke游戏数据有说法(透视挂)开挂教程-果然真的有挂(知乎)轰趴十三水辅助器中分为...
AaPOKER!wopoker... AaPOKER!wopoker游戏辅助器(透视辅助)黑科技教程-果然真的有挂(哔哩哔哩)1)AaPO...