过程总结:
1、安装插件
import JSZip from 'jszip'
import FileSaver from 'file-saver'
2、打包下载
//文件批量下载
downloadedFiles:将要下载的文件数组
download:调取的下载方法,我这里返回的data进行了封装,包括二进制流和文件名称、路径等信息
export function batchDownload(downloadedFiles,download){
const fileBaseUrl= 'http://localhost:8088'
let zip = new JSZip()
let promises = []
downloadedFiles.forEach(item => {
const { filePath } = item
const url = /http/.test(filePath)
? filePath
: `${fileBaseUrl + filePath}` //路径拼接
//download 请求后台数据方法
const promise =
download({ url, fileName: filePath.split('/').pop() }) //接口请求要下载的数据
.then(data => {
let fileName = item.fileName
if(!!zip.files[fileName]){
//如果该文件名已经存在,调用handleDuplicationName进行重命名处理
fileName= handleDuplicationName(zip.files,fileName)
}
// 第一个参数下载后的文件名,第二个参数是后台返回的二进制流,第三个参数必填,是否是二进制
zip.file(fileName, data.data, {
binary: true,
})
})
promises.push(promise)
})
Promise.all(promises)
.then(() => {
zip.generateAsync({ type: 'blob' }).then(content => {
// 生成二进制流,(.zip尽可能加上)
FileSaver.saveAs(content, '文件下载.zip') // 利用file-saver保存文件 自定义文件名
})
})
.catch(res => {
Vue.prototype.$message({
type:'error',
message:'文件压缩失败'
})
})
}
//文件同名处理
export const handleDuplicationName = (files,fileName) => {
let name = fileName
if(!!files[name]){
let splitName = name.split('.')
//文件名存在,从后往前找是否有括号,如果没有则从(1)开始
if(name.lastIndexOf("(") <= 0 || name.lastIndexOf(")") <= 0) {
name = splitName[0]+ "("+ 1 +")" +'.'+splitName[1];
}else{
//如果文件名存在(含括号的文件名),则截取括号中的值,并替换
let num = name.slice(name.indexOf("(")+1,name.indexOf(")"));
// name = splitName[0]+ "("+ (++num) +")" +'.'+splitName[1];
name =name.replace(num,++num);
}
//通过递归,修改文件名,返回zip.files中还没有的文件名,并将其添加进去
name = handleDuplicationName(files,name);
}
return name
}