背景:公司之前的pdf实现是由后端实现的,后端生成pdf后返回前端链接,前端再做处理。因为由后端的实现会消耗性能,所以打算由前端来实现。
我在百度,掘金上看了很多方案,决定用了htmltocanvas和jsPdf来实现pdf。那么开始:
1.安装两个依赖:
npm i html2canvas -S
npm i jspdf -S
复制代码
实现思路:html转换成canvas后生成图片导出pdf
html2canvas是一款将HTML代码转换成Canvas的插件,而jsPDF就是将canvas生成pdf的
2.代码的实现:
// 做的时候页面比较长,出现了滚动条,然后截取不全,上面的部分截取不到,就需要设置页面初始位置,从最顶部开始截取
// 设置页面的初始化的位置
window.pageYOffset = 0;
document.documentElement.scrollTop = 0
document.body.scrollTop = 0
html2Canvas(document.querySelector(`#${targetDom}`), { // targetDom是目标dom,就是要生成canvas的元素
allowTaint: true, // 允许跨域(我也没试过,哈哈~)
useCORS: false,// 这个好像也是运行跨域,网上还说不能和allowTaint配合使用(我也没试过,哈哈~有点尴尬)
scale: 2, // 缩放倍数,网上说数值越大越清晰,我简单的尝试换成1.5确实模糊了一些
// dpi: window.devicePixelRatio * 2, // window.devicePixelRatio是设备像素比
}).then(canvas => {
let position = 0;
// 生成的画布元素宽高
let canvasWidth = canvas.width;
let canvasHeight = canvas.height;
// 页面等比例缩放后宽高
let pageWidth = a4Width;
let pageHeight = (a4Width / canvasWidth) * canvasHeight;
//返回图片dataURL,参数:图片格式和清晰度(0-1)
let jpeg = canvas.toDataURL('image/jpeg', 1.0);
// 第一个参数是纵横向,第二个参数是单位,第三个参数是生成pdf的大小,自定义pdf大小的话可以传入一个数组,eg:[164.14, 424.5]
//方向默认竖直,尺寸ponits,格式a4 [595.28,841.89]
let pdf = new JsPDF('', 'pt', 'a4');
//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
//当内容未超过pdf一页显示的范围,无需分页
if (canvasHeight < pageHeight) {
// 第三,四个参数是图片偏移位置,第五六个参数是生成的图片的宽高
pdf.addImage(jpeg, 'JPEG', 0, 0, pageWidth, pageHeight); // 从图片顶部开始打印
} else {
while (canvasHeight > 0) {
pdf.addImage(jpeg, 'JPEG', 0, position, pageWidth, pageHeight);
canvasHeight -= pageHeight;
position -= a4Height;
//避免添加空白页
if (canvasHeight > 0) {
pdf.addPage();
}
}
}
pdf.save(fileName + '.pdf'); // fileName文件名称,自定义
}
)
复制代码
3.效果截图:
生成的dom页面(页面布局等是从其他地方抄来的)
点击下方的确认可以生成预览图
复制代码
预览图生成不完全,如下图:
复制代码
这时候只要在确认的时候加上这几行代码就好了
window.pageYOffset = 0;
document.documentElement.scrollTop = 0
document.body.scrollTop = 0
再来看效果图:
复制代码
最后的下载:
// pdf是new JsPDF('', 'pt', 'a4')生成的实例对象
pdf.save(title + '.pdf')
复制代码
总结:大概的pdf实现就是这样子,但是最后要对生成的pdf进行打印,打印的又是那种类似于超市开的小票的规格大小,由于生成的pdf是由图片再转成pdf的,导致打印机打印出来会失真,就不再选择由前端去实现这个需求了。小的能力有限 有个打印的效果图可以给大家看下:
夸一下,我的手看起来还挺白的~~哈哈哈
复制代码
题外话:这是我第一次写掘金,然后很多代码也是借鉴了大佬们的,有觉得眼熟的多多担待。有些说法描述的不对的也请大佬们指正。也是对一些觉得好玩的事的一次记录吧。希望自己以后能继续保持下去!!!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END