要求按A4纸大小生成pdf,支持分页且内容不被截断
npm install html2canvas --save
npm install jspdf --save
将DOM转换为canvas并将pdf的宽高设置为canvas的宽高,再将canvas转为图片,实例化jspdf,将内容图片完整的放在pdf中
在保持网页的宽高比以及pdf每页的大小(A4)的情况下,dom下元素越多,越可能出现生成多页pdf的情况,就很容易出现一个dom元素被截断分散在两页pdf里
两种思路:
1) 每页pdf中的元素以及高度固定 ,保证在分割的位置不会阶段dom元素,不过这个想法很快放弃,因为项目上需要被生成的dom区域的结构、高度都不固定
2) 不依赖布局,给页面上的子元素添加标识, 根据动态计算子元素所在的高度计算出一个位置插入空白高度
由于dom结构的大小宽高不固定,所以在不能被截断的元素上添加target-node-item,根据该标识遍历子节点中class为target-node-item的元素,计算出target-node-item的元素距离顶部的偏移量,如果(元素a距离上方或上层控件的位置+元素a本身的高度小于A4纸的高度,并且下一个元素距离上方或上层控件的位置+下一个元素本身的高度大于A4纸的高度),则在两个园中中间插入一个空白块,空白的高度通过计算,为a4纸的高度减去元素a的offsetTop + offsetHeight,我们可以在计算出的高度上插入占位高度,避免下一页内容挨着分割线、
如果需要页码的话,可以在判断高度的位置预留出页码的高度,在对应的位置插入页码节点。
处理前:
处理后:
由于html元素过多,页面上可滑动查看,此时 元素width≠元素scrollWidth , 元素height≠元素一开始的想法是把目标元素的width,height赋值为scrollWidth,scrollHeight,但这样会导致页面会闪烁
优化:把目标元素copy下来,html2canvas中引入cloneDom
配下参数即可即:
1.dom结构
<div class="liveInDetailList">
<div class="liveInDetail" v-for="(item,index) inPersonNamelist.guestList" :key="index">
<div class="infoDetail">
<span class="left">住客姓名</span>
<input type="text" placeholder="请输入姓名" class="searchRoomInp" autofocus="autofocus" v-model="item.name" ref="inputName" v-focus>
</div>
<div class="infoDetail">
<span class="left" >手机号</span>
<input type="text" placeholder="请输入手机号" class="searchRoomInp" v-model="item.mobilePhone" >
</div>
<div class="infoDetail">
<span class="left">身份z号</span>
<input type="text" placeholder="请输入身份z号" class="searchRoomInp" v-model="item.idCardNo">
</div>
<div class="handle" v-if="isShowDelete">
</div>
<div class="handle" v-else>
<i slot='rightIcon' class="iconfont icon-icon-shanchu deleterightIcon" @click.stop="delRoomCard(index)"></i>
</div>
</div>
</div>
2在data中定义
PersonNamelist:{
checkInRoomId:'',
guestList:[{id:"",name:"",mobilePhone:"",idCardNo:""}]
},
3.点击新增
1.定义一个obj
let obj={
id:"",
name:"",
mobilePhone:"",
idCardNo:""
}
2.点击一下将obj添加进数组PersonNamelist
4.该项目会从后台传来一个新增最多的人数所以需要判断下PersonNamelist中的guestList的长度
addPerson(){
let obj={
id:"",
name:"",
mobilePhone:"",
idCardNo:""
}
if(this.PersonNamelist.guestList.length<(后台数据))
this.PersonNamelist.guestList.push(obj)
}
else{
Toast({
message:'已超出该房间可住最大人数',
position:'bottom',
duration:1000,
className:'panduan'
})
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)