在做后台管理时会碰到文件下载压缩的需求,这里简单整理一下代码,主要依赖两个库
npm i jszip
npm i file-saver
安装完成后引入到组件
import JSZip from 'jszip'
import FileSaver from 'file-saver'
import dayjs from 'dayjs'
<template>
<a-table :row-selection="{onSelect: rowSelectionHandle}">
</a-table>
<a-button type="primary" @click="handleMultiDownload">批量下载</a-button>
</template>
interface IAnnexList {
/**附件名称 */
annexName: string
/**附件url */
annexUrl: string
/**附件id */
id: string
/**计划单id */
warehousingPlanId: string
/**上传uid */
uid?: string
}
const selectTableData = ref<IAnnexList[]>([])
/**
* @method table选中
*/
const rowSelectionHandle = (keys: Array<string>, data: IAnnexList[]) => {
selectTableData.value = data
}
/**
* @method 批量下载附件为压缩包
*/
const handleMultiDownload = () => {
if (!selectTableData.value.length) return proxy?.$message.error('请选择需要操作的数据')
downLoadFile(selectTableData.value,'测试压缩包')
}
/**
* @method 下载文件 传入文件数组
* @param {*} fileList 实例:[{annexUrl:www.123.jpg,annexName:'123.jpg'}] url:文件网络路径,name:文件名字
*/
function downLoadFile(fileList: IAnnexList[],zipName?:string) {
let zip = new JSZip()
let cache = {}
let promises = []
for (const item of fileList) {
const promise = getFile(item.annexUrl).then((data: any) => {
// 下载文件, 并存成ArrayBuffer对象(blob)
zip.file(item.annexName, data, { binary: true }) // 逐个添加文件
cache[item.annexName] = data
})
promises.push(promise)
}
Promise.all(promises)
.then(() => {
zip.generateAsync({ type: 'blob' }).then((content) => {
// 生成二进制流
FileSaver.saveAs(content, zipName || `${dayjs(new Date()).format('YYYY-MM-DD')}` ) // 利用file-saver保存文件 自定义文件名
})
})
.catch((error) => {
console.log('文件压缩-error', error)
proxy?.$message.error('文件压缩失败')
})
}
/**
* @method 通过请求获取文件的blob格式
* @param url 文件url
*/
function getFile(url: string) {
return new Promise((resolve, reject) => {
let xmlHttp = new XMLHttpRequest()
xmlHttp.open('GET', url, true)
xmlHttp.responseType = 'blob'
xmlHttp.onload = function () {
if (this.status == 200) {
resolve(this.response)
} else {
reject(this.status)
}
}
xmlHttp.send()
})
}