循环url地址数组创建iframe标签下载的方法,但浏览器有限制,超过10个文件将不能下载,最多下载10个。
// arr 是要下载的文件列表
for (let i = 0; i < arr.length; i++) {
const iframe: any = document.createElement('iframe')
iframe.style.display = 'none' // 防止影响页面
iframe.style.height = 0 // 防止影响页面
iframe.src = arr[i]?.url
document.body.appendChild(iframe) // iframe挂在到dom树上才会发请求
setTimeout(() => {
iframe.remove()
}, 1000)
}
可解决下载数量限制问题,但是浏览器的内存非常有限,对大文件的下载,不建议此方法。
const download = (item: any) => {
axios({
method: 'get',
url: item.url,
responseType: 'blob',
onDownloadProgress: function (e: any) {}//监控下载进度
}).then(data => {
const url = window.URL.createObjectURL(data.data)
const a = document.createElement('a')
a.download = item.original
a.href = url
a.click()
})
}
const multipleSelection = ref<User[]>([])
const batchDownload = () => {
if (multipleSelection.value?.length > 0) {
let files = multipleSelection.value;
files.forEach((item: any) => {
download(item)
})
} else {
ElMessage.warning('请先勾选需要下载的文件')
}
}
该插件将客户端内存存储中的文件给导出并打包.但是这插件有很大的限制就是文件大小限制,谷歌浏览器都只能2GB以下,其他更低。浏览器的内存非常有限,对大文件的下载,不建议此方法。
npm install file-saver
npm install jszip
import { saveAs } from 'file-saver';
import JSZip from 'jszip';
import axios from 'axios';
//声明获取文件的函数
const download = (href: any) => {
return new Promise((resolve, reject) => {
axios({
method: 'get',
url: href,
responseType: 'arraybuffer'
}).then(data => {
resolve(data.data)
}).catch(error => {
reject(error.toString())
ElMessage.error(error.toString())
})
})
}
// 声明下载按钮所绑定的函数
//multipleSelection.value 要下载的文件列表
const batchDownload = () => {
if (multipleSelection.value?.length > 0) {
loadLoading.value = true;
let files = multipleSelection.value;
let filename = '档案.zip';
const zip = new JSZip()
const cache = {}
const promises: any[] = [];
files.forEach((item:any) => {
const promise = download(item.url).then((data:any) => {
// 下载文件, 并存成ArrayBuffer对象
zip.file(item.name, data, { binary: true }) // 逐个添加文件
cache[item.name] = data //可要可不要 用来打印查检查添加了那些文件
})
promises.push(promise) //加到promises队列里
})
Promise.all(promises).then(() => {
//异步队列全部完成时 执行下面代码
zip.generateAsync({ type: "blob" }).then(content => {
// 生成二进制流
saveAs(content, filename) // 利用file-saver保存文件
ElMessage.success('批量下载完成')
}).finally(() => { loadLoading.value = false; })
}).finally(() => { loadLoading.value = false; })
} else {
ElMessage.warning('下载的文件不能为空')
}
}
注意:打包好的zip文件中,会自动去重 zip.file()传入的文件名参数如果相同,不会重复添加。例如如果有10个文件,其中3个重名, 那么zip文件里只有7个文件 ,不会重复打包如果想全部下载,建议文件名传入时加个index下标尾缀 例:原文件名 + ‘_’ + index
StreamSaver.js采用直接创建一个可写流到文件系统的方法。而不是将数据保存在客户端存储或内存中。解决了文件下载受浏览器内存的限制。
npm install StreamSaver
const batchDownload = () => {
files.forEach((item: any, index: number) => { item.name= index + 1 + '_' + item.name; })//对文件名重名处理
let filename = `压缩包.zip`;
const zipFileOutputStream = StreamSaver.createWriteStream(filename)
// 创建文件列表迭代
const fileIterator = files.values();
const readableZipStream = new ZIP({
async pull(ctrl: any) {
const fileInfo = fileIterator.next()
if (fileInfo.done) {//迭代终止
ctrl.close();
} else {
const { original, url } = fileInfo.value;
return fetch(url).then(res => {
ctrl.enqueue({
name: name,
stream: () => res.body
});
})
}
}
});
if (window.WritableStream && readableZipStream.pipeTo) {
readableZipStream.pipeTo(zipFileOutputStream)
.then(() => ElMessage.success('批量下载完成'))
}
}