写在前面
最近做的一个小需求,需要给对应的数据生成二维码卡片,同时要求能够批量去生成,并且保存到本地。
于是查阅了网上的资料,用Cavans+QRCode+JSZip+FileSaver可以解决这个问题,小小记录一下。
代码Demo:saver.zip 提取码:stp8
进入正题
三七二十一,别的先不管,先引入所需要的的js,因为qrcode.js是依赖jQuery的,所以要先引入jQuery,注意引入顺序,js资源都在上面的demo中
在开始生成二维码前,我们先初始化一些数据,这个demo是用jq写的,所以直接通过原生js去生成数据了,略显繁琐,不喜欢的小伙伴可以用vue去写
最终的效果是做出这样一个简单的表格
可以点击生成单个二维码,也可以勾选后批量生成
html:
1 <button onclick="saveSome()">批量生成</button> 2 <table border="1px"> 3 <thead> 4 <tr> 5 <th><input type="checkbox" id="checkAll" /></th> 6 <th width="100">名字</th> 7 <th width="100">操作</th> 8 </tr> 9 </thead> 10 <tbody> 11 </tbody> 12 </table>
js:
1 var list = [{ //初始化一些数据 2 id: 1, 3 name: '张三' 4 }, 5 { 6 id: 2, 7 name: '李四' 8 }, 9 { 10 id: 3, 11 name: '王五' 12 } 13 ] 14 15 $(function() { 16 for (var i = 0; i < list.length; i++) { 17 var html = '<tr><td><input id="item_' + i + 18 '" name="checkItem" type="checkbox"/>' + 19 '</td><td>' + list[i].name + '</td><td>' + 20 '<a onclick="saveOne(' + i + ')">生成二维码</a></td></tr>' 21 $('tbody').append(html) 22 } 23 }) 24 25 $("#checkAll").bind("click", function() { //全选或全不选 26 if (this.checked) { 27 $("[name = checkItem]:checkbox").attr("checked", true); 28 } else { 29 $("[name = checkItem]:checkbox").attr("checked", false); 30 } 31 });
定义一些全局参数,单个或批量下载都能复用的
1 var canvas = document.createElement('canvas'); //创建一个全局画布 2 canvas.width = 300; //设置画布的宽和高 3 canvas.height = 400; 4 var ctx = canvas.getContext('2d'); //画笔
公用的绘制代码
1 function draw(item) { //绘制二维码及名字标识 2 return new Promise((resolve, reject) => { 3 var div = document.createElement('div'); 4 var qrcode = new QRCode(div, { //绘制二维码 5 text: 'index.html?id=' + item.id + Math.random(), //内容加个随机数,可以看出来区别 6 width: 250, 7 height: 250, 8 colorDark: "#000000", 9 colorLight: "#ffffff", 10 correctLevel: QRCode.CorrectLevel.H 11 }); 12 let mc = div.querySelector('canvas'); 13 ctx.beginPath(); //开始绘制 14 ctx.fillStyle = '#7ee2f1'; 15 ctx.fillRect(0, 0, 300, 400) //填充底色 16 ctx.drawImage(mc, 25, 25) //绘制二维码 17 ctx.font = "bold 45px 微软雅黑"; 18 ctx.textAlign = "center"; 19 ctx.textBaseline = "middle"; 20 ctx.fillStyle = '#000000'; 21 ctx.fillText(item.name, 150, 350) //绘制文字在底部 22 ctx.closePath(); //结束绘制 23 resolve(); 24 }) 25 }
1、单个二维码:
1 async function saveOne(i) { 2 let item = list[i]; 3 console.log(item) 4 await draw(item); //绘图需要时间,如果异步完成的话可能会导致保存了一张空白的图,所以使用await等待这个方法完成再往后操作 5 canvas.toBlob(function(blob) { //canvas下载到本地 6 saveAs(blob, 'img_' + item.id + ".png"); 7 }); 8 }
效果呈现:点击任意的生成二维码按钮,就可以下载图片到本地了
上述代码中,主要的两点其实就是生成二维码和保存到本地,其他的绘制只是为了加上标记
(1)生成二维码,参考:生成二维码
(2)使用FileSaver.js保存Canvas到本地,根据官网给出的栗子,直接套就行了
2、批量下载二维码
这个其实跟单个二维码下载同理,只不过我们需要把它打包成zip,再下载
初始化一个zip文件
1 var zip = new JSZip(); //初始化一个zip文件
批量生成
1 async function saveSome() { //生成多个并打包下载到本地 2 let my_list = []; 3 $("[name = checkItem]").each(function() { //遍历哪个是选中需要生成二维码的 4 if($(this).is(':checked')) 5 my_list.push(list[$(this).attr('id')]); 6 }); 7 if(my_list.length==0){ 8 alert('请选择需要生成二维码的数据') 9 }else{ 10 for (var i = 0; i < my_list.length; i++) { 11 let item = my_list[i]; 12 await draw(item); //等待绘图 13 await addToZip(canvas,zip,'img_' + item.id + ".png"); //等待加入zip文件 14 } 15 createZip() 16 } 17 }
将一个canvas加入到zip文件中
1 function addToZip(canvas, zip, name) { 2 return new Promise((resolve, reject) => { 3 canvas.toBlob(function(blob) { 4 zip.file(name, blob); // 将每次不同的canvas数据添加到zip文件中 5 resolve(); 6 }); 7 }) 8 }
下载zip文件到本地的代码
1 async function createZip() { //下载zip文件到本地 2 zip.generateAsync({ 3 type: 'blob' 4 }).then(function(content) { 5 saveAs(content, 'demo.zip'); 6 }); 7 }
效果呈现:勾选想要下载出二维码的行,点击批量下载,就可以将二维码打包下载到本地了
批量打包下载,这里需要用到刚开始提到的JSZip了
参考官方代码:
1.这一部分是将数据添加进zip文件中
2.配合FileSaver.js将zip文件下载到本地
参考文章:
https://stuk.github.io/jszip/
https://github.com/eligrey/FileSaver.js