这种打包下载文件,如果后端并没有返回arraybuffer文件格式数据,其实不太建议在前端做,因为前端用url来进行打包下载,还需要再另行发起请求。
总之是可以实现的,我们只需要借助jszip和file-saver插件即可
下面基于vue-cli创建的项目来说明,我们来看看如何实现。
让我们先在项目里安装依赖包
npm i jszip file-saver --save axios
第一种情况:直接下载文件数据
首先看第一种情况,后端直接给我们返回了zip文件格式的数据,那么这个就很简单了,在你需要下载的页面引入file-saver(jszip都用不上)请求后端数据,保存即可
直接看保存的代码,这里假设后端返回的文件格式是blob,前端以相应的格式接收,ids是后端需要的参数
async saveFile(){
let fileData=await axios({
url:'/downloads',
withCredentials:false,
responseType:'blob',
data:ids,
method:'POST'
})
//fileData.data就是后端返回的文件数据
saveAs.saveAs(fileData.data, `资料.zip`) // 利用file-saver保存文件
}
如果后端都返了文件数据却不是zip的,那请他返zip的吧,前端就懒得麻烦了哦
第二种情况:只有文件Url
这种情况,我们只有一个可以访问的文件Url,那么就要多一步,先请求下这个文件,转为接收blob或者arraybuffer,然后用jszip转为zip文件,再用file-saver保存。这种情况需要请求接口,会受到浏览器并发限制。
这里来一个批量下载的示例
<template>
<button @click="downloadZip"></button>
</template>
<script>
export default{
data(){
return {
urlData:['url1','url2','url3','url4']
}
},
methods: {
//获取下载文件
async getDowloadFile(url){
return new Promise((resolve, reject) => {
store.state.instance({
url,
withCredentials:false,
responseType:'arraybuffer'
}).then(res=>{
resolve(res.data)
}).catch(err=>{
reject(err)
})
})
},
//下载zip文件
downloadZip(){
// urlData// 需要下载打包的路径, 可以是本地相对路径, 也可以是跨域的全路径
let {urlData}=this
let name="打包下载"
const zip = new JSZip()
const cache = {}
const promises = []
urlData.forEach(item => {
const promise = this.getDowloadFile(item).then(data => { // 下载文件, 并存成ArrayBuffer对象
// console.log(data)
const arr_name = item.split("/")
const file_name = arr_name[arr_name.length - 1] // 获取文件名
zip.file(file_name, data, { binary: true }) // 逐个添加文件
cache[file_name] = data
})
promises.push(promise)
})
console.log(promises)
Promise.all(promises).then(() => {
zip.generateAsync({type:"blob"}).then(content => { // 生成二进制流
saveAs.saveAs(content, `${name}.zip`) // 利用file-saver保存文件
})
})
},
}
}
</script>
第三种情况:打包json数据,或者字符串数据
假设我们想将页面上的某些json数据打包成json格式文件下载,那这也好办。看代码
let testJson={
name:"ZHANGSA",
age:18,
leval:2
}
zip.file('testJson.json', JSON.stringify(testJson), { binary: true }) // 逐个添加文件
zip.generateAsync({type:"blob"}).then(content => { // 生成二进制流
console.log(content)
saveAs.saveAs(content, `文件.zip`) // 利用file-saver保存文件
})