欢迎关注我的公众号
《人生代码》
我有一个大胆的想法,我要一直写到死,那一天我不写了,可能就死了。哈哈。
哈喽,大家好,我是你们的攻城狮,人贱人爱的 Ken,一个永远充满激情的人。
最近接收到一个优化需求:就是对之前的行程文档的图文介绍添加打印生成 pdf 的功能
当然,我们需要依赖 html2canvas 和 jspdf.min.js 这两个库,html2canvas 是用于生成 canvas,jspdf.min.js 是用于生成 pdf 的。
首先我们需要引入 html2canvas, jspdf
importhtml2canvasfrom'html2canvas'
import'./jspdf.min.js'
如果有滚动条,先把滚动条置顶
document.body.scrollTop=document.documentElement.scrollTop=0
if(!selector){
thrownewError('缺少selector')
}
letel=document.querySelector(selector)
if(!el){
thrownewError('未找到'+selector+'对应的dom节点')
}
设置背景色为白色,然后转成图片后,获取截断处图片像素点,从截断处往上一行行扫描像素点颜色,碰到这一行颜色都是全白的,代表是从这里开始截断,将这个高度开始将往下的内容都放到下一页
html2canvas(el,{
allowTaint:true,
useCORS:true,
dpi:120,//图片清晰度问题
background:'#FFFFFF',//如果指定的div没有设置背景色会默认成黑色,这里是个坑
}).then(canvas=>{
//未生成pdf的html页面高度
varleftHeight=canvas.height
vara4Width=595.28
vara4Height=841.89//A4大小,210mmx297mm,四边各保留10mm的边距,显示区域190x277
//一页pdf显示html页面生成的canvas高度;
vara4HeightRef=Math.floor((canvas.width/a4Width)*a4Height)
//pdf页面偏移
varposition=0
varpageData=canvas.toDataURL('image/jpeg',1.0)
varpdf=newjsPDF('p','pt','a4')//A4纸,纵向
varindex=1,
canvas1=document.createElement('canvas'),
height
pdf.setDisplayMode('fullwidth','continuous','FullScreen')
varpdfName=title
functioncreateImpl(canvas){
console.log(leftHeight,a4HeightRef)
if(leftHeight>0){
index++
varcheckCount=0
if(leftHeight>a4HeightRef){
vari=position+a4HeightRef
for(i=position+a4HeightRef;i>=position;i--){
varisWrite=true
for(varj=0;j
varc=canvas.getContext('2d').getImageData(j,i,1,1).data
if(c[0]!=0xff||c[1]!=0xff||c[2]!=0xff){
isWrite=false
break
}
}
if(isWrite){
checkCount++
if(checkCount>=10){
break
}
}else{
checkCount=0
}
}
height=Math.round(i-position)||Math.min(leftHeight,a4HeightRef)
if(height<=0){
height=a4HeightRef
}
}else{
height=leftHeight
}
canvas1.width=canvas.width
canvas1.height=height
console.log(index,'height:',height,'pos',position)
varctx=canvas1.getContext('2d')
ctx.drawImage(
canvas,
0,
position,
canvas.width,
height,
0,
0,
canvas.width,
height,
)
varpageHeight=Math.round((a4Width/canvas.width)*height)
//pdf.setPageSize(null,pageHeight)
if(position!=0){
pdf.addPage()
}
pdf.addImage(
canvas1.toDataURL('image/jpeg',1.0),
'JPEG',
10,
10,
a4Width,
(a4Width/canvas1.width)*height,
)
leftHeight-=height
position+=height
if(leftHeight>0){
setTimeout(createImpl,500,canvas)
}else{
pdf.save(pdfName+'.pdf')
}
}
}
//当内容未超过pdf一页显示的范围,无需分页
if(leftHeight
pdf.addImage(
pageData,
'JPEG',
0,
0,
a4Width,
(a4Width/canvas.width)*leftHeight,
)
pdf.save(pdfName+'.pdf')
}else{
try{
pdf.deletePage(0)
setTimeout(createImpl,500,canvas)
}catch(err){
//console.log(err);
}
}
})
如果是连续的表格的,我们的方案是不使用一个表格来填充所有数据,这就有点像那个分页加载数据一样了,如果我们使用多个表格来循环这些数据,然后每个表格的高度设置为 a4 纸的高度,这样也许能够做到不被截断了