vue使用js-zip前端解压、压缩、下载文件

1,800 阅读2分钟

需求1:后端返回的是一个压缩包链接,前端要下载和解压得到里面的文件。

为了简洁代码省略错误处理。

第一步,封装下载方法,转为blob。

export const urlToBlob = (url:string) => {
    return new Promise((resolve,reject)=>{
        fetch(url).then( response => {
            return response.blob();//解析成blob对象
        })
        .then( blobData => {
            console.log('blob-----------------',blobData)
            resolve(blobData)
        })
    })
}

第二步,封装解压方法,用blob解压,得到解压后的数据(格式可选)

根据实际业务需求,压缩包里的图片文件我需要转为blob返回,json文件则直接返回json格式。

import JSZip from 'jszip';
export const getZipData = (blobData:Blob) => {
    return new Promise(async (resolve,reject)=>{
            let result = {
                blobArr: [],
                data: {}
            };
            let zipObj = new JSZip();
            let zipFile = await zipObj.loadAsync(blobData as any);
            for(let key in zipFile.files){
                let tempName = zipFile.files[key].name;
                if(tempName.indexOf('.png') != -1 || tempName.indexOf('.jpg') != -1){
                    console.log('有用到的图层文件和字体文件',zipFile.files[key]);
                    //@ts-ignore
                    let fileBlob = await zipFile.file(tempName).async("blob");//传入解压文件命名和解压缩后想得到的格式。
                    //@ts-ignore
                    result.blobArr.push({name:tempName,blob:fileBlob})
                }
                //json文件转为字符串
                if(tempName.indexOf('.json') != -1){
                    console.log('有用到的json文件',zipFile.files[key]);
                    //@ts-ignore
                    let jsonString = await zipFile.file(tempName).async("string");
                    result.data = JSON.parse(jsonString);
                    //后面还发现貌似有asnyc('json')方法直接得到json格式,可能就不用走以上两步了
                }
            }
            console.log('解压后得到的数据---------------',result)
            resolve(result);
    })
}

第三步,封装最终方法,调用上面两个方法即可。

export const getTemplateZipData = (url:string) => {
    return new Promise( async (resolve,reject)=> {
        let blobData = await urlToBlob(url) as Blob;
        let templateData = await getZipData(blobData)
        resolve(templateData);
    })
}

需求2:前端以压缩包格式下载。

既然下的是压缩包,当然是有多个文件的压缩,涉及异步的处理。

import JSZip from 'jszip';
let blobArr; //假设这是要下载的几个文件的promise,返回blob数组。
let zip =  new JSZip();
Promise.all(blobArr).then((res)=>{
    res.forEach((item,index)=>{
        zip.file(`文件名.png`, item, {base64: true});//每个文件的文件名、配置项
        })
        console.log('压缩开始')
        // 生成zip文件并下载
        zip.generateAsync({ 
            type: 'blob' //压缩后的压缩包,转成blob形式
        }).then((content) => {
            console.log('压缩完毕,下载压缩包开始')
            let eleLink = document.createElement('a');
            eleLink.download = `压缩包名字.zip`;
            eleLink.href = URL.createObjectURL(content);
            eleLink.click();
            console.log('下载压缩包结束')
        })
    })