pc项目中有下载pdf的需求,内容是动态变化的,要求分页,加水印效果,各方面综合考虑以后要求前端实现
技术要点:jspdf+html2canvas
**原理:**利用html2canvas将html转成canvas,再利用canvas.toDataURL生成网路图片,然后用jspdf.addImage将图片画到pdf中
**难点:**图片的高度>一页pdf高度时,利用图片的偏移量来实现分页效果,详见代码
下面分别描述一下水印、分页等是如何实现的
function downPdf(html){
//初始化jspdf实例
const doc=new jsPDF()//a4 [552.28,841.89]
doc.setFont('simhei')//设置中文字体,避免乱码
//每页pdf宽高
let pageWidth = doc.internal.pageSize.width
let pageHeight = doc.internal.pageSize.height
//html容器的宽高
let contentWidth = html.clientWidth
let contentHeight = html.clientHeight
//图片的宽高
let imgWidth=pageWidth
let imgHeight=imgWidth*contentHeight/contentWidth
//html-canvas-img
let canvas=await html2canvas(html,{scale:2,backgroundColor:null})//设置null,背景是透明的,会跟水印有叠加的效果
let pageData=canvas.toDataURL('image/png', 1.0)//1.0保证图片的清晰度
let position=10
if(imgHeight<pageHeight){
doc.addImage(pageData, 'PNG', 0, 10, imgWidth, imgHeight)
}else{
let height=imgHeight//剩余图片高度
while(height>0){
//设置每页的上下间距
doc.setFillColor(255,255,255);
doc.rect(0,0,pageWidth,10,'F')//头部白条
doc.rect(0,pageHeight-10,pageWidth,10,'F')//尾部白条
//画图
doc.addImage(pageData, 'PNG', 0, position, imgWidth, imgHeight)
height=height-(pageHeight-20)
position=position-(pageHeight-20)
if(height>0){//剩余图片高度大于每页pdf高度时,添加新页面(并添加水印)
doc.addPage()
this.addWaterMark(doc)
}else{
//每页26条链接
doc.setTextColor('#E02020')
let pos=10+(height+(pageHeight-20))+1//第一个文字链接距离顶部的距离(10头部白条高度,1距离图片下边缘的距离)
//计算剩余高度可容纳文字链接的个数
let sheng=pageHeight-pos
let num=Math.floor(sheng/14)
//开始画超链接
let newPos=15//新页面中第一个文字链接的位置
let currentPge=1
//循环文字类链接列表
txts.forEach((item,index) => {
if(index<num){
doc.textWithLink((index+1)+'、'+item.name,15,pos,{url:item.url})
pos+=10
}else if(index%26===num){
currentPge++
doc.addPage()
this.addWaterMark(doc)
doc.textWithLink('txt',15,newPos,{url:''})
newPos=25
}
else{
doc.textWithLink('txt',15,newPos,{url:''})
newPos+=10
}
})
//保存下载
doc.save('test.pdf')
}
}
}
}