后端jeecg-boot框架,前端直接使用vue进行截图还是很简单的,网上很多教程。简单分享一下。
首先根据要截图的元素(一般选一个html的节点id属性,也可以是class)本身的宽度和高度等比例创建画布,可以设置倍数,本实例设置倍数放大两倍。vue引入canvas2html,方法很简单,yarn add canvas2html就可以自动引入,也可以使用npm install canvas2html引入该js.下面图片中的方法很简单,应该也不需要过多解释怎么使用。
1.yarn add canvas2html
2.import html2canvas from 'html2canvas' //引入
3.使用如下
而jeecg-boot该框架支持自定义表单,使用表单生成器可以让用户自定义生成表单,这个时候的页面就不是vue页面了,而是临时生成的动态表单。其处理逻辑是:定义表单模板 -- 取表单数据 -- 填充模板并返回一个填充完成的html页面(包括引入的css和js)-- vue页面iframe加载该动态页面并显示。
此时的html、css、js页面是从后端下载的,不受vue的路由控制。所以没法用vue引入的库,所以要给动态页面截图,必须修改后端代码模板,在后端jeecg-boot增加html2canvas.js(从vue安装完成的npm_moudules下面找到,也可以自己在网上下载),如下图所示
将该js文件拷贝到后端资源文件夹中,并在templates中引入,
<script src="${base}/desform/html2canvas.js?${CACHE_VERSION}"></script>
此时若截图有滚动条,一定要注意给html2canvas方法加上参数:
scrollY:-$(document).scrollTop(),
scrollX:-$(document).scrollLeft(),
这两个参数表示文档滚动的高度和左偏移量,缺少该参数将导致截图起点会在节点起点左偏移scrollX,上偏移scrollY,效果就是在scrollX和scrollY的面积是空白的,而且截图不全。
完整后端代码:
//el元素节点,photoAddUrl为保存图片的请求路径
doLoadQR:function(el,photoAddUrl) { var _this = this //新建一个画布元素 let canvas2 = document.createElement('canvas') //获取该元素区块的本身宽高 const targetDom = document.querySelector(el) let w = parseInt(targetDom != null ? targetDom.offsetWidth : 800) let h = parseInt(targetDom != null ? targetDom.offsetHeight : 1000) //因为直接用默认画布会模糊,因此自定义画布,设置画布尺寸为容器的两倍大小,再将内容放大两倍画上去, // 修改偏移量,就可以解决模糊问题 //画布真实宽高 canvas2.width = w canvas2.height = h //宽高宽高 canvas2.style.width = w + 'px' canvas2.style.height = h + 'px' //设置画布的内容 let context = canvas2.getContext('2d') console.log('调用html2canvas库') //调用库 html2canvas(targetDom, { useCORS: true, scale: 1, scrollY:-$(document).scrollTop(), scrollX:-$(document).scrollLeft(), width: targetDom.scrollWidth, height: targetDom.scrollHeight, //使用自定义的画布 canvas: canvas2, // window.devicePixelRatio是设备像素比 dpi: window.devicePixelRatio }).then(function(canvas) { // 回调生成的画布canvas对象 // 获取生成的图片的相对url,其实将bese64加密的数据 的数据类型image/png换成image/octet-stream console.log('回调生成的画布canvas对象') console.log('返回图片流') // copyDom.parentNode.removeChild(copyDom) let imgUrl=canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream') let postData = {} postData.photoValue = imgUrl //写入数据库请求 let obj={} obj.url=photoAddUrl obj.method='post' obj.data=postData obj.token=token obj.success=_this.requestSuccess() _this.saveFile(obj) }) }