js实现多文件打包成zip下载

1,021 阅读1分钟

1、安装插件

npm i -s jszip file-saver

2、封装函数

import JSZip from 'jszip';
import { saveAs } from 'file-saver';

//通过请求获取文件blob格式
function getFileBlob(url) {
  return new Promise((resolve, reject) => {
    let request = new XMLHttpRequest()
    request.open("GET", url, true)
    request.responseType = "blob"
    request.onload = (res) => {
      if (res.target.status == 200) {
        resolve(res.target.response)
      } else {
        reject(res)
      }
    }
    request.send()
  })
}



export const DownloadJSZip = (
  files, // 要压缩下载的文件集合
  fileName = '文件下载', // 压缩后的文件夹名称
  callback // 回调函数
) => {
  // console.log('下载 DownloadJSZip', files, fileName)
  const zip = new JSZip()

  let result = files.map(item => {
    let promise = getFileBlob(item).then(res => {
      let format = item.substring(item.lastIndexOf("/") + 1, item.length)
      if (format.indexOf('.') === -1) {
        format += '.png';
      }
      zip.file(format, res, { binary: true })
    })
    return promise;
  })

  Promise.all(result).then(() => {
    zip.generateAsync({ type: "blob" }).then((res) => {
      callback && callback()
      saveAs(res, `${fileName}.zip`)
    })
  }).catch(() => {
    callback && callback();
  })
}


/**
 * 多文件夹 压缩成 zip并下载
 * @param {*} files {'分类文件名': [文件内容]}
 * @param {*} fileName 
 * @param {*} callback 
 */
export const DownloadJSZipToMultifile = (
  files, // 要压缩的文件集合
  fileName = '文件下载', // 压缩后的文件夹名称
  callback
) => {
  
  const zip = new JSZip()
  let result = [];

  Object.keys(files).map(item => {
    // 创建一个文件夹,名为item
    let foleder = zip.folder(item);
    // 为 item 文件夹添加内容后文件
    files[item].map(val => {
      const obj = val.path
      let promise = getFileBlob(obj).then(res => {
        let format = obj.substring(obj.lastIndexOf("/") + 1, obj.length)
        if (format.indexOf('.') === -1) {
          format += '.png';
        }
        foleder.file(format, res, { binary: true })
        
      })
      return result.push(promise)
    })
    
  })

  Promise.all(result).then(() => {
    zip.generateAsync({ type: "blob" }).then((res) => {
      callback && callback()
      saveAs(res, `${fileName}.zip`)
    })
  }).catch(() => {
    callback && callback();
  })
}

3、使用 (示例为react中使用)

import { DownloadJSZip } from './DownloadJsZip';

timeFormat = (timeStamp) => {
    const addZero = num => (num >= 10 ? num : `0${num}`);
    if (typeof (Number(timeStamp)) != "number") {
      console.warn("Parameter is not a number!");
      return null;
    }
    const TimeTxtLength = String(timeStamp).length === 13;
    const transformTime = TimeTxtLength ? timeStamp : timeStamp * 1000;
    const UTCtime = new Date(transformTime);

    let formatTime = UTCtime.getFullYear();
    formatTime += `-${addZero(UTCtime.getMonth() + 1)}-`;
    formatTime += addZero(UTCtime.getDate());

    return formatTime
};

// 下载文件
onDownLoadEvent = () => {
    const files = [
        'https://qncdn.wanshifu.com/3c48cce2d80235ac902f31abd5cb3e10',
        'http://qncdn.wanshifu.com/mp4/b7f76f72c2fe890af0a89c9e2315153b.mp4',
    ]
    DownloadJSZip(files, `下载文件_${this.timeFormat(Date.now())}`)
}

render () {
    return (
        <Button onClick={this.onDownLoadEvent}>下载</Button>
    )
}

image.png