前言:期望本文的读者,在此前已经对vue-qr,canvas,jsZip,FileSaver有了解。笔者将尽量详细的介绍。
1.添加依赖
1.1下载依赖
npm install vue-qr --save //vue-qr 的依赖
npm install jszip //jszip 的依赖
npm install file-saver --save //FileSaver 的依赖
1.2添加依赖
import VueQr from 'vue-qr' //引入VueQr
import JSZip from 'jszip' //引入 jsZip
import FileSaver from 'file-saver' //引入FileSaver
1.3添加组件
export default {
.../*其他代码*/...
components: {
VueQr,
JSZip,
FileSaver
}
.../*其他代码*/...
}
参考地址:
官网参考地址:
vue-qr,
jsZip,
FileSaver
材料参考地址:实例详解Vue 中批量下载文件并打包方法
vue-qr:https://www.npmjs.com/package/vue-qr](https://www.npmjs.com/package/vue-qr
jsZip:https://stuk.github.io/jszip/](https://stuk.github.io/jszip/
FileSaver:https://www.npmjs.com/package/file-saver](https://www.npmjs.com/package/file-saver
材料参考地址:http://www.php.cn/js-tutorial-382680.html](http://www.php.cn/js-tutorial-382680.html
说明:
百度现在太多的文章都是复制粘贴,很少有自己实践,参考价值很低,很多不但不能解决问题,也会加剧问题的处理。作为编程人员还是要勇于向原文档去进军,虽然大部分都是英文,但是看多了,自然而然的就懂了。笔者曾经过度依赖百度的答案,虽然有时候能解决问题,但是碰到同样的还是不明就里,学习还是要有打破砂锅问到底的精神。
2.实例说明
2.1 生成二维码
<template>
<Button @click="paintCanvas(1,'single')">合成图片并下载</Button> //点击按钮 合成二维码和文字的图片
<div id="1">
<vue-qr
:correctLevel="3" //容错登记 有0~3 3 最高
:logoScale="0.4" //中间图标的大小 太大会显示默认值
:logoSrc="logoAddress" //logo的地址 建议导入到项目的静态文件中
:text=qrCodeText" //二维码的内容
:size="200" //生成二维码的大小 二维码默认是正方形所以只需要设置一个值
:margin="0" //二维码的边距,默认为白色的
:dotScale="1" //二维码的中点的大小 可以设置 0~1
style="margin: 10px" //css样式>
</vue-qr>
</div>
</template>
只要前面有引入,参数设置正确,到这里就能看到二维码了,示例如下
![](https://img.haomeiwen.com/i8312491/a5212d0e301690c3.png)
2.2 使用HTML原生<canvas>标签合成带文字说明的二维码
2.2.1在HTML里面新建一个画布标签
<canvas id="box" style="display: none;background: #FFFFFF;" width="250px"
height="350px"></canvas>
根据需求设置画布是否可见,此处画布设置成不可见
2.2.2新建一个方法,处理画布(合成二维码和二维码下的文字)
methods: {
paintCanvas(id, type) {//id表示对应的二维码标签的id type表示画布的类型
let c = document.getElementById("box") //获取canvas画布 画布大小和canvas大小一致
let picName="测试图片"+id;
let ctx = c.getContext("2d");
c.height = c.height;//清空画布,重新绘制
let div = null; //设置div变量
//判断类型:single 单张 batch 批量
if (type != 'single')
div = document.getElementById('batch' + id); //获取到需要绘制到canvas的div即二维码div
else
div = document.getElementById(id); //获取到需要绘制到canvas的div即二维码div
let img = div.getElementsByTagName("img")[0];//获取二维码
ctx.drawImage(img, 25, 25, 200, 200) //参数依次为:绘制图片, 左,上,宽,高
ctx.font = "20px bold 微软雅黑" //设置字体大小 这里文字的加粗一直无效,至今没搞清楚原因 有能解决的朋友可以私聊
//多画几次,让字体加粗 解决文字无法加粗问题
for (let i = 0; i < 10; i++) {
ctx.fillText("TestCanvas", 26, 250) //使用偏移量加粗字体
}
let dataUrl = c.toDataURL(); //获取返回的base64的信息
this.dataUrls.push({picData: dataUrl, fileName: picName}); //把数据存进数组里面
//如果类型是单张(single)则下载合成好的图片
if (type == 'single') {
const link = document.createElement('a');
link.download = "测试合成图片.jpg";
link.href = dataUrl;
link.click();
}
}
}
到这里,单张二维码和文字的合成图片生成完成
点击下载按钮,可以看到会加载一张图片,下载的图片如下:
![](https://img.haomeiwen.com/i8312491/44fd9619a47dba79.png)
2.2.3批量生成二维码并打包成zip下载
说明:这里需要先生成所有的二维码图片(如不想显示出来可以隐藏),建议真正使用可以考虑动态生成
HTML代码:
<template>
<Button @click="batchDownLoad()">压缩并批量下载</Button>
<div id="batch" hidden>
<div v-for="item in testList"> //循环列表
<div :id="'batch'+item.id">
<vue-qr :correctLevel="3" :logoScale="0.4" :logoSrc="config.logo" :text="item.qrText" :size="200"
:margin="0" :dotScale="1"
style="margin: 10px"></vue-qr>
</div>
</div>
</div>
</template>
vue设置参数(对应HTML中的testList)该参数放置再data(){return{}}里面:
dataUrls: [], //缓存批量下载图片(即画布生成的二维码)的地址
testList: [
{
id: 1,
qrText: "测试内容1"
},
{
id: 2,
qrText: "测试内容2"
},
{
id: 3,
qrText: "测试内容3"
}
]
新建批量下载的方法:
//批量下载
batchDownLoad() {
this.dataUrls = [] //重置dataUrls
for (const a of this.testList) {
this.paintCanvas(a.id, 'batch')
}
this.handleBatchDownload();
},
//压缩图片
handleBatchDownload() {
const zip = new JSZip()
const zipName = '测试压缩包.zip'
this.dataUrls.forEach(item => {
const fileName = item.fileName + '.jpg'
let arrData = item.picData.split(',')
zip.file(fileName, arrData[1], {base64: true}) //向zip中添加文件
zip.file(fileName, arrData[1], {base64: true}) //向zip中添加文件
})
zip.generateAsync({type: "blob"})
.then(function (content) {
saveAs(content, zipName);
});
},
至此,程序完成
![](https://img.haomeiwen.com/i8312491/72d01da7ba57a895.png)
完整代码如下:
<template>
<Card>
<template>
<Button @click="paintCanvas(1,'single')">合成图片并下载</Button>
<div id="1">
<vue-qr :correctLevel="3" :logoScale="0.4" :logoSrc="config.logo" :text="qrCodeText" :size="200"
:margin="0" :dotScale="1"
style="margin: 10px"></vue-qr>
</div>
</template>
<template>
<Button @click="batchDownLoad()">压缩并批量下载</Button>
<div id="batch" hidden>
<div v-for="item in testList">
<div :id="'batch'+item.id">
<vue-qr :correctLevel="3" :logoScale="0.4" :logoSrc="config.logo" :text="item.qrText" :size="200"
:margin="0" :dotScale="1"
style="margin: 10px"></vue-qr>
</div>
</div>
</div>
</template>
<canvas id="box" style="display: none;background: #FFFFFF;width: 500px;height: 700px" width="250px"
height="350px"></canvas>
</Card>
</template>
<script>
import VueQr from 'vue-qr'
import JSZip from 'jszip'
import FileSaver from 'file-saver'
import picture from '_pub/static/img/logo.png'
export default {
name: "test",
components: {
VueQr,
JSZip,
FileSaver
},
data() {
return {
dataUrls:[],
qrCodeText: 'test',
config: {
logo: picture//中间logo的地址
},
testList: [
{
id: 1,
qrText: "测试内容1"
},
{
id: 2,
qrText: "测试内容2"
},
{
id: 3,
qrText: "测试内容3"
}
]
}
},
methods: {
paintCanvas(id, type) {
let c = document.getElementById("box") //获取canvas画布 画布大小和canvas大小一致
let picName="测试图片"+id;
let ctx = c.getContext("2d");
c.height = c.height;//清空画布,重新绘制
let div = null;
if (type != 'single')
div = document.getElementById('batch' + id);
else
div = document.getElementById(id);
let img = div.getElementsByTagName("img")[0];//获取图片
ctx.drawImage(img, 25, 25, 200, 200) //绘制图片, 左,上,宽,高
ctx.font = "20px bold 微软雅黑" //设置字体大小
//多画几次,让字体加粗
for (let i = 0; i < 10; i++) {
ctx.fillText("TestCanvas", 26, 250) //使用偏移量加粗字体
}
let dataUrl = c.toDataURL();
this.dataUrls.push({picData: dataUrl, fileName: picName});
if (type == 'single') {
const link = document.createElement('a');
link.download = "合成测试.jpg";
link.href = dataUrl;
link.click();
}
},
//批量下载
batchDownLoad() {
this.dataUrls = [] //重置dataUrls
for (const a of this.testList) {
this.paintCanvas(a.id, 'batch')
}
this.handleBatchDownload();
},
//压缩图片
handleBatchDownload() {
const zip = new JSZip()
const zipName = '测试压缩包.zip'
this.dataUrls.forEach(item => {
const fileName = item.fileName + '.jpg'
let arrData = item.picData.split(',')
zip.file(fileName, arrData[1], {base64: true}) //向zip中添加文件
})
//打包压缩
zip.generateAsync({type: "blob"})
.then(function (content) {
saveAs(content, zipName);
});
}
}
}
</script>
<style scoped>
</style>
程序界面如下:
![](https://img.haomeiwen.com/i8312491/0f43b8782b5b8ac2.png)
总结
1.在批量生成文件的时候,注意每个文件名称都要唯一,否则会替换掉原来的文件,只生成一个文件
2.如果想要充分了解这几个插件的功能,参数,可以参看原文档
网友评论