问题原因:后端返回了一个zip格式文件供前端下载,然后下载后,形成了zip套zip的形式,当后端不愿处理时,前端不能坐以待毙
PS:当压缩包文件量过大,前端可能会出问题(脑测,未实测)
递归解压文献:JS前端解压zip的方法和技巧分享_javascript技巧_脚本之家
多文件压缩文献:前端下载多个压缩包中的文件 - 简书
代码:
依赖:jszip,file-saver
import JSZip from 'jszip'
import { saveAs } from 'file-saver'
// 下载为压缩包
async downloadZip(res, name) {
/*
res: 后端文件流
name: xxx.zip
*/
const blobs = await extractNestedZip(res)
return createAndDownloadNewZip(blobs, name)
// 递归解压
async function extractNestedZip(zipBlob) {
const zip = new JSZip()
const zipData = await zip.loadAsync(zipBlob)
const extractedFiles = []
for (const [name, file] of Object.entries(zipData.files)) {
// 如果文件是嵌套的 ZIP 文件,则递归解压
if (name.endsWith('.zip')) {
const nestedZipBlob = await file.async('blob')
const nestedFiles = await extractNestedZip(nestedZipBlob)
extractedFiles.push(...nestedFiles)
} else {
// 如果文件不是 ZIP 文件,则处理
if (['.xlsx', '.xls'].some(item => name.endsWith(item))) {
const blob = await file.async('blob')
extractedFiles.push({ name, data: blob })
} else if (!name.endsWith('/')) {
// 过滤掉文件夹
const fileData = await file.async('text')
extractedFiles.push({ name, data: fileData })
}
}
}
return extractedFiles
}
// 下载 返回格式为 extractNestedZip 返回格式
function createAndDownloadNewZip(blobs, zipName) {
/*
blobs: [{name: '',data: blob文件}]
*/
const zip = new JSZip()
// 为每个PDF文件生成一个新的文件名(如果需要)并添加到新压缩包中
blobs.forEach(item => {
const fileName = item.name
zip.file(fileName, item.data, { binary: true })
})
// 生成新的压缩包Blob对象
zip.generateAsync({ type: 'blob' }).then((content) => {
// 下载新的压缩包
saveAs(content, zipName)
})
}
}