今天遇到一个需求是要实现二维码的批量下载功能,输出一个zip包。

首先从图片角度而言并不是单纯的一张二维码即可,还附加一些名称和描述。思路有两种:

  1. 利用canvas直接绘制,将二维码绘制后再绘制配套文字等内容;
  2. 利用html2canvas实现截取DOM功能;

本质上来说两者是一样的,html2canvas也是利用了canvas绘制。因为对canvas不熟悉 ,于是采用了第二种方法。

引入和使用 html2canvas

html2canvas的使用很简单,一步到位:

import html2canvas from 'html2canvas'
html2canvas(document.querySelector('#capture')).then((canvas) => {
    imgData = canvas.toDataURL()
})

其 中HTMLCanvasElement.toDataURL()返 回base64,单个图片的下载:

imgData = imgData.replace(_fixType(type), 'image/octetstream')
var saveFile = function (data, filename) {
    var save_link = document.createElementNS(
        'http://www.w3.org/1999/xhtml',
        'a'
    )
    save_link.href = data // a标签href
    save_link.download = filename //文件名
    var event = document.createEvent('MouseEvents') //创建事件,后边必须跟init初始化
    event.initMouseEvent(
        'click',
        true,
        false,
        window,
        0,
        0,
        0,
        0,
        0,
        false,
        false,
        false,
        false,
        0,
        null
    )
    save_link.dispatchEvent(event) // 派发前面初始化的点击事件,模拟用户点击
}
var filename = `${i.name}-${i.keycode}.${type}`
saveFile(imgData, filename) // 单个下载

关于initEvent以及document.creatEvent, 在这里能看到 更多的信息以及Event.initEventnew Event来代替。

下载功能是动态的创建一个a标签来实现的。若要实现多张图片下载并生成zip包,则用 到了jsZip插件。

jsZip 引入与使用

import JSZip from 'jszip'
var zip = new JSZip()
var img = zip.folder('images') // 创建images文件夹用于存放图片

img.file(filename, imgData, { base64: true }) // zip打包下载
if (index == _devList.length - 1) {
    // 判断循环结束,则开始下载压缩
    zip.generateAsync({ type: 'blob' }).then(function (content) {
        saveAs(content, _devList[0].name + +new Date() + '.zip')
    })
}

这里需要注意一点是,需要下载file-saver模块,saveAs是其下的方法。

JSZip模块中的base64.js会对文件格式进行检测,所以我们需要将之 前canvas.toDataURL()得到的data去除前 缀 imgData = imgData.split("base64,")[1];