html2canvas+jspdf 踩坑之路
最近刚完成了项目中所有模块的详情页导出 PDF 功能. 本来开始后端接了这个活, 前端只要传过去单号就好, 可是做到最后一直实现不来, 页面总是显示一半, 于是, 后端把活让给了我
还好, 同组的其他伙伴项目中有用到过, 给了我些帮助.
具体实现思路是: html2canvas 截屏页面快照, 然后把照片插入到 PDF 页面内.
遇到的问题有:
1) 快照是空白的
首先页面 DOM 布局很重要, 如果布局比较乱, 很容易打印出空白页面. 我们要知道 html2canvas 截屏的元素是相对 body 元素定位的, 所以我这里把要截屏的 DOM 元素 copy 了一份, 放在 body 元素里.lettargetDom=document.querySelector('#pdfWrap');
letcopyDom=targetDom.cloneNode(true);
copyDom.classList.add("copydom");
document.body.appendChild(copyDom);
2)PDF 宽度很大, 在 a4 纸打印不够
打印出来的 PDF 是等比例的缩放字体大小, 如果宽度很宽, 字体就会变得很小很小. 这个时候就要和 PM 沟通协商, 看看想怎么解决.
3) 快照图片不显示
原因是跨域请求了图片资源, html2canvas 默认是不跨域的, 所以在这里要设置下可跨域.
html2canvas(copyDom, {
useCORS: true
})
4) 快照截屏是当前可视窗口大小, 没法滚动
我们页面比较长, 有滚动条, 所以会出现当前问题. 设置当前要截屏的 DOM 元素的宽度和高度都为目标元素的滚动高度.copyDom.style.height=targetDom.scrollHeight+"px";
copyDom.style.width=targetDom.scrollWidth+"px";
5) 页面表格内容超出用省略号显示的解决办法
和 PM 沟通, 需要把省略掉掉内容折行展示出来. html2canvas 的截图原则是所见即所得, 所以页面是什么样子, 打印出来是什么样子. 因此, 我需要在新的 copy DOM 元素下改变折行样式.(增加这行类名: export-mulit-line)letrecordDom=copyDom.getElementsByClassName('approval-records')[0];
letrecordTableDom=recordDom.getElementsByClassName('data-table')[0];
recordTableDom.classList.add("export-mulit-line");
: 这里涉及到了折行, 页面高度会有所改变, 所以要增加 copyDOM 元素的高度~(appendHeight 即为变化的高度)
copyDom.style.height = targetDom.scrollHeight + appendHeight + "px";
总体实现代码:// 判断是否多行
isMultiline(arr,num){
returnarr.some(e=>{
returne.remark&&e.remark.length>num;
});
},
getPdf(dom,title){
this.loading=true;
lettargetDom=document.querySelector('#pdfWrap');
letcopyDom=targetDom.cloneNode(true);
copyDom.classList.add("copydom");
// 多行展示预算信息
letappendHeight=0;// 折行增加的高度
copyDom.style.height=targetDom.scrollHeight+appendHeight+"px";
copyDom.style.width=targetDom.scrollWidth+"px";
document.body.appendChild(copyDom);
utils.exportPDF(copyDom,this.orgInfo.orgName).then(v=>{
this.loading=v;
});
}
}
utils.JS// 导出 PDF
asyncexportPDF(copyDom,activityName){
awaithtml2canvas(copyDom,{
useCORS:true
})
.then(canvas=>{
letcontentWidth=canvas.width;
letcontentHeight=canvas.height;
letpageHeight=contentWidth/592.28*841.89;
letleftHeight=contentHeight;
letposition=0;
letimgWidth=555.28;
letimgHeight=555.28/contentWidth*contentHeight;
console.log(contentHeight);
letpageData=canvas.toDataURL('image/jpeg',1.0);
letPDF=newJsPDF('','pt','a4');
if(leftHeight
PDF.addImage(pageData,'JPEG',20,0,imgWidth,imgHeight);
}else{
while(leftHeight>0){
PDF.addImage(pageData,'JPEG',20,position,imgWidth,imgHeight);
leftHeight-=pageHeight;
position-=841.89;
if(leftHeight>0){
PDF.addPage();
}
}
}
PDF.save(activityName+'.pdf');
});
returnfalse;
}
html2canvas 官网
来源: http://www.jianshu.com/p/bf3a4dc810b7