寫在前面
最近做的一個小需求,需要給對應的數據生成二維碼卡片,同時要求能夠批量去生成,並且保存到本地。
於是查閱了網上的資料,用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