VUE3+jszip和file-saver如何实现下载多个文件导出为一个zip格式

借鉴大佬写的文章,他这个是图片的
https://www.jb51.net/javascript/31723515u.htm

业务场景:
后端会给在线文件地址,然后根据列表点击批量下载
当前存在问题
会有文件跨域的情况,这个我试过几个方案都不行,只能遵循同源政策,放一起

插件安装

npm install jszip
npm install file-saver
我遇到的是,下载依赖会失败
我的解决方案
npm install file-saver --legacy-peer-deps
npm install jszip --legacy-peer-deps

在所需页面引入 

import JSZip from "jszip";
import FileSaver from "file-saver";

文件JSON展示

const  transferData=ref() 如下数据

[
    {
        "fileName": "pH记录(pH).xlsx",
        "feilePath": "https://www.baidu.com/mnt/2024/5/9/1788514725233643521.xlsx"
    },
    {
       "fileName": "pH记录(pH).xlsx",
        "feilePath": "https:///www.baidu.com/mnt/2024/5/9/1788514725233643522.xlsx"
    },
    {
         "fileName": "pH记录(pH).xlsx",
        "feilePath": "https:///www.baidu.com/mnt/2024/5/9/1788514725359472642.xlsx"
    },
    {
        "fileName": "pH记录(pH).xlsx",
        "feilePath": "https:///www.baidu.com/mnt/2024/5/9/1788514725359472643.xlsx"
    },
    {
         "fileName": "pH记录(pH).xlsx",
        "feilePath": "https:///www.baidu.com/mnt/2024/5/9/1788514725367861250.xlsx"
    },
    {
         "fileName": "pH记录(pH).xlsx",
        "feilePath": "https:///www.baidu.com/mnt/2024/5/9/1788514725372055553.xlsx"
    }
]

代码展示

const downloadFiles = async () => {
	// 创建一个新的JSZip实例
	const zip = new JSZip();
	const now = new Date();
	var blogTitle = '全部文件';
	var promises = [];
	// 假设你有一个文件列表
	
	// 遍历文件列表,下载并添加到ZIP文件中
	for (const item of transferData.value) {
		if (item.feilePath) {
			const promise = getImgArrayBuffer(item.feilePath).then((data) => {
				// 下载文件, 并存成ArrayBuffer对象(blob)
				zip.file(item.fileName, data, {binary: true}); // 逐个添加文件
				cache[item.fileName] = data;
			});
			promises.push(promise);
		} else {
			// feilePath地址不存在时提示
			console.log(`附件${item.fileName}地址错误,下载失败`);
		}
	}

	debounceTimeout = setTimeout(() => {
		zip.generateAsync({type: "blob"}).then((content) => {
			// 生成二进制流
			FileSaver.saveAs(content, blogTitle); // 利用file-saver保存文件  blogTitle:自定义文件名
		});
	}, 100 * transferData.value.length); // 在实际的测试中,Promise会执行压缩失败,试过几次,特别的文件很多的情况下,然后就用了个很挫的解决方案,反正解决了

}

//文件以流的形式获取(参数url为文件链接地址)
const getImgArrayBuffer = (url) => {
	return new Promise((resolve, reject) => {
		//通过请求获取文件blob格式
		let xmlhttp = new XMLHttpRequest();
		xmlhttp.open("GET", url, true);
		xmlhttp.responseType = "blob";
		xmlhttp.onload = function () {
			if (xmlhttp.status == 200) {
				resolve(xmlhttp.response);
			} else {
				console.log('下载失败====', xmlhttp.response)
				reject(xmlhttp.response);
			}
		};
		xmlhttp.send();
	});
}

  



posted @ 2024-05-30 18:14  好色的菜狗  阅读(69)  评论(0编辑  收藏  举报