700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > JS生成二维码以及保存页面为图片的解决方案:html2Canvas+file-saver+qrcodejs2的使用

JS生成二维码以及保存页面为图片的解决方案:html2Canvas+file-saver+qrcodejs2的使用

时间:2021-05-12 14:28:37

相关推荐

JS生成二维码以及保存页面为图片的解决方案:html2Canvas+file-saver+qrcodejs2的使用

前言

最近因为工作需求,需要前端根据后端传过来的链接生成二维码,并且要使用JS保存页面为图片。然后网上搜了很多解决办法。最终都是用h5的canvas进行绘制然后保存为图片。其中,又以html2Canvas最为出众。当然在此之前要先用qrcodejs2生成二维码,然后调用file-saver保存。相关sdk自己点进去研究,下面我就来讲讲我的实现思路。

注意:因为项目是由vue2写的,这里以vue2的写法进行演示。

一、生成二维码

1、安装qrcodejs2

npm install qrcodes2 --save

2、编写代码

2.1 布局

<!--将下面那个canvas绘制的二维码转换为base64后塞到img元素里面 可以支持长按另存为图片--><img v-if="showQRImage" :src="qrImage" class="qr"><!--根据canvas直接绘制的二维码 无法长按另存为图片--><div v-else ref="qr" class="qr" />

如果只是展示,只需要下面那个div即可。如果想要长按另存为图片,就要写成上面那个样子。二者的class样式要保持一致,这样可以达到用户无感知替换。

2.2 JS脚本

import QRCode from 'qrcodejs2'// 生成的二维码的宽高const qr_width = 150const qr_height = 150export default {data() {return {qrImage: '',showQRImage: false}},computed: {// 获取前一个页面传过来的qr链接 自己根据实际情况修改获取方式qrURL() {return this.$route.query.entranceUrl || ''}},created() {// 建议放在created里面进行二维码生成this.generateQRCode()},methods: {generateQRCode() {// 确保dom渲染完组件后再调用生成方法 否则可能不能生成二维码this.$nextTick(() => {new QRCode(this.$refs.qr, {text: this.qrURL, // 页面地址 ,如果页面需要参数传递请注意哈希模式#width: qr_width,height: qr_height,colorDark: '#000000',colorLight: '#ffffff',correctLevel: QRCode.CorrectLevel.H})this.saveQRCode()})},saveQRCode() {html2canvas(this.$refs.qr, {backgroundColor: null, // 透明背景width: qr_width,height: qr_height,useCORS: true // 解决跨域保存图片的问题}).then(canvas => {this.qrImage = canvas.toDataURL('image/jpeg') // 转换保存二维码图片为Base64字符this.showQRImage = true})}}}

需要注意的是,将URL转换为二维码的URL里面不要带中文。如果有,请先转码。

然后自己可以写一个按钮,给它设置点击事件为saveQRCode即可。

二、保存页面为图片

1、安装html2Canvas

npm install html2Canvas --save

2、安装file-saver

npm install file-saver --save

3、代码编写

import html2canvas from 'html2canvas'import { saveAs } from 'file-saver'savePage() {html2canvas(this.$refs.qrContainer, {useCORS: true, // 解决跨域保存图片的问题}).then(canvas => {// 将canvas内容保存为文件并下载canvas.toBlob((blob) => {saveAs(blob, 'xxxxx二维码.png')})})}

this.$refs.qrContainer是vue的写法,指代具体的dom节点。当然你也可以用document.getElementById取代。

上面的就是主代码。将savePage方法绑定在一个按钮的点击事件后,点击时,浏览器会提示下载图片。

但是问题很多。

3.1 如果当前页面中有一个保存图片的按钮,但是保存的时候不要想要这个按钮,该怎么办?

按照vue的思路,肯定给这个按钮设置一个v-if="showButton"的配置,保存的时候showButton=false,保存完后showButton=true。

想法很美好,实际很残酷,最终你失败了。

我们仔细阅读html2Canvas的api,会发现有一个ignoreElements的配置属性。这个配置,就是用来忽略不需要转换为canvas的dom元素的。那么,这个代码就应该这样写:

import html2canvas from 'html2canvas'import { saveAs } from 'file-saver'savePage() {html2canvas(this.$refs.qrContainer, {useCORS: true, // 解决跨域保存图片的问题ignoreElements: (item) => {// 这个save就是你给需要忽略的元素设置class的名字if (item.classList.contains('save')) {return true // 排除掉保存二维码按钮}return false // 保留这个元素}}).then(canvas => {// 将canvas内容保存为文件并下载canvas.toBlob((blob) => {saveAs(blob, 'xxxxx二维码.png')})})}

3.2 保存的图片不完整

如果你需要转换为图片的布局有padding或者margin之类的设置。那么在调用html2Canvas生成的canvas是不会包含这部分值的。也就意味着你的图片顶部和底部如果有间距值,那实际就是直接贴屏的。解决的方式,就是在顶部和底部设置空的视图进行占位。

<!--父布局--><div id="container"><!--保存图片的时候防止贴顶--><div style="height: 20pt;width: 100%" /><!--真正的内容区域--><div class="content"></div><!--保存图片的时候贴底--><div style="height: 60pt;width: 100%" /></div>

此外,如果你的页面超过了屏幕高度,能滑动,那么这时,你看到保存的图片可能也是残缺的。html2Canvas默认保存的是可见的区域,超出屏幕部分无法保存。

网上流传一种办法:

在调用savePge之前,调用

window.pageYoffset = 0document.documentElement.scrollTop = 0document.body.scrollTop = 0

意思就是让屏幕滚回至最初状态。这。。。。。实际上就是掩耳盗铃,没啥卵用

最终解决办法就是手动设置canvas的绘制宽高,将其设置为实际内容的宽高,并且设置缩放。

import html2canvas from 'html2canvas'import { saveAs } from 'file-saver'savePage() {html2canvas(this.$refs.qrContainer, {useCORS: true, // 解决跨域保存图片的问题scale: 1, height: this.$refs.qrContainer.scrollHeight,windowHeight: this.$refs.qrContainer.scrollHeight,ignoreElements: (item) => {// 这个save就是你给需要忽略的元素设置class的名字if (item.classList.contains('save')) {return true // 排除掉保存二维码按钮}return false // 保留这个元素}}).then(canvas => {// 将canvas内容保存为文件并下载canvas.toBlob((blob) => {saveAs(blob, 'xxxxx二维码.png')})})}

这里的this.$refs.qrContainer.scrollHeight你也可以用document.getElementById('xxx').scrollHeight代替。另外,scale是一定要设置的,否则还是会出现残缺。

3.3 图片失真了

按照上面的写法,在手机上保存的时候,图片会失真。最终测试的解决办法就是改scale,从1改到3就能解决问题。

JS生成二维码以及保存页面为图片的解决方案:html2Canvas+file-saver+qrcodejs2的使用心得以及解决图片失真 保存不完整的解决办法

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。