https://www.zhangxinxu.com/wordpress/2019/08/js-zip-download/
jszip和filesaver的下载链接可以从上面的链接中找到

阅读了大神的这篇文章,正好工作中需要用到这个技术,于是就练习了一下jszip的用法。

要实现的效果是:用js生成多张图片,打包到zip文件中,并下载到本地。

首先新建一个html页面,然后引用jszip和FileSaver,我已经把这两个js文件保存到了本地:

<script src="jszip.min.js"></script>
<script src="filesaver.min.js"></script>

页面中只需一个canvas

<canvas id="canvas" height="100" width="100"></canvas>

js中,首先初始化需要的对象:

var zip = new JSZip();  // jszip对象

var canvas = document.getElementById('canvas');
var d = canvas.width,
    ctx = canvas.getContext('2d');

接下来建立一个简单的绘图函数,它接收一个color参数:

// 仅仅为了演示,只要每次生成的图片显著不同就行了
function draw(color) {
    ctx.beginPath();
    ctx.moveTo(d / 2, 0);
    // 为了让每次生成的图像有区别,随机变换位置
    ctx.lineTo(d - Math.random() * 50, d - Math.random() * 50);
    ctx.lineTo(0, d);
    ctx.closePath();
    ctx.fillStyle = color;
    ctx.fill();
}

然后需要一个函数来获取canvas数据并添加到zip文件中:

// canvas.toBlob是异步的,所以用Promise来保证操作执行完才进行接下来的操作
function addToZip(canvas, zip, name) {
    return new Promise((resolve, reject) => {
        canvas.toBlob(function (blob) {
            zip.file(name, blob);  // 将每次不同的canvas数据添加到zip文件中
            resolve();
        });
    })
}

最后,需要一个生成zip文件的函数:

// 生成zip文件并下载到本地
function createZip() {
    zip.generateAsync({ type: 'blob' }).then(function (content) {
        saveAs(content, 'example.zip');
    });
}

所需的功能都已经准备好,接下来循环绘制10张图:

async function createImg() {
    for (var i = 0; i < 10; i++) {
        // 为了能显著区分生成的img,每次循环都对颜色进行一些调整
        draw('rgb(' + (255 - i * 20) + ',' + (165 + i + 20) + ', ' + (100 + i * 10) + ')');
        // addToZip是异步的,用await来保证同步执行
        await addToZip(canvas, zip, 'img' + (i + 1) + '.png');
    }

    createZip();
}

功能已经完成了,现在只要调用

createImg();

就能立刻生成一个包含十个png图像的zip压缩包并立即下载了。

这是生成的压缩包:
{AB93C84C-87B3-4A35-A8F6-469F07C06EF1}_20190930153950.jpg

解压后:
{65DC149E-A26C-41CE-AD4E-9E8F888F46B2}_20190930154039.jpg

其中的一张图片:
{E96A7466-EDB4-4272-A30A-AF90285A9E56}_20190930154109.jpg

完整代码:
前端生成zip.rar

End

标签: jszip