1. 安装jszip、save-as-file
npm i jszip save-as-file -S
2. 封装压缩文件方法:batchDownLoadZip
import JSZip from 'jszip'
import saveFile from 'save-as-file'
const zip = new JSZip()
const cache = {}
const promises = []
/**
* 批量下载文件
* @param {Array} fileList 批量压缩的文件
* {
'fileName': '文件名,
'fileUrl': '文件地址',
}
* @param {string} zipName 生成压缩文件命名
*/
export function batchDownLoadZip(fileList, zipName) {
return new Promise((resolve, reject) => {
fileList.forEach(item => {
// item.fileUrl.split('?')[0] 处理fileList里的url地址 去除?号和后面的字符串
const promise = getImgArrayBuffer(item.fileUrl.split('?')[0]).then(data => { // 下载文件, 并存成ArrayBuffer对象
// item.fileName fileList里的文件名
zip.file(item.fileName, data, { binary: true }) // 逐个添加文件
cache[item.fileName] = data // 可要可不要 用来打印查检查添加了那些文件
}).catch(e => {
console.log('文件访问失败')
})
promises.push(promise) // 加到promises队列里
})
Promise.all(promises).then(() => { // 异步队列全部完成时 执行下面代码
console.log('开始压缩')
zip.generateAsync({ type: 'blob' }).then(content => { // 生成二进制流
console.log('压缩成功', content)
saveFile(content, zipName)
console.log('文件保存成功')
resolve()
}).catch(e => {
console.log('下载失败')
reject(e)
})
}).catch(e => {
console.log('压缩失败')
reject(e)
})
})
}
function getImgArrayBuffer(href) {
return new Promise((resolve, reject) => {
// 通过请求获取文件blob格式
const xmlhttp = new XMLHttpRequest()
xmlhttp.open('GET', href, true)
xmlhttp.responseType = 'blob'
xmlhttp.onload = function() {
if (this.status === 200) {
resolve(this.response)
} else {
reject(this.status)
}
}
xmlhttp.send()
})
}
3. 在生产环境下不执行问题解决
在浏览器生产环境下zip.generateAsync不会执行,这是由于该方法需要在node环境才能执行,使用JSZip-sync这个包代替jszip即可解决这个问题。
npm地址:https://www.npmjs.com/package/jszip-sync
用法:只需要在外层使用包裹
//import JSZip from 'jszip'
import JSZip from 'jszip-sync'
...
export function batchDownLoadZip(fileList, zipName) {
return new Promise((resolve, reject) => {
zip.sync(function() {
......
})
})
}