引入JSZip 和 FileSaver 资源包
npm install JSZip FileSaver
使用方式
使用了ant Design 里面的 message
和 notification
组件,需要的话可以自行替换;
实现思路,通过将获取到的 Url
资源转换为Blob对象,拿到文件的数据流,然后通过 JSZip
进行资源压缩,最后通过 FileSaver
进行资源下载;
获取 Url
资源的时候使用了 fetch
请求,这里可以根据自己的需求修改为其他请求方式;
import JSZip from "jszip";
import FileSaver from "file-saver";
import { message, notification } from "antd";
/**
* 批量下载图片,Zip压缩包
* @filesList
* @type
* @callback
*/
export function batchDownLoadZip(filesList: any, type: string, callback: any) {
const zip = new JSZip();
const promises: any = [];
const cache = {};
const title: string = `${
type == "picture" ? "图片" : type == "video" ? "视频" : "文件"
}`;
if (filesList.length > 1) {
filesList.forEach((item: any, idx: number) => {
const fileList = getFile(item.url, type).then((data: any) => {
// 下载文件, 并存成ArrayBuffer对象
// 逐个添加文件,视频后缀-.mp4 图片后缀-.png
zip.file(
type == "video"
? `【${Number(idx) + 1}】${item.name}.mp4`
: `${Number(item.rowIndex) + 1}_picture_${Number(idx) + 1}.png`,
data,
{ binary: true }
);
cache[item.url] = data;
});
promises.push(fileList);
});
notification.success({
message: `${title}下载中`,
description: `${title}资源准备中,请稍等...`,
duration: 5,
onClose: () => {
Promise.all(promises)
.then(() => {
// 生成二进制流
zip.generateAsync({ type: "blob" }).then((content) => {
// 利用file-saver保存文件 自定义文件名
FileSaver.saveAs(content, `${title}`);
message.success(`${title}下载完成`);
callback();
});
})
.catch((res) => {
message.warning(`${title}下载失败!`);
callback();
});
},
});
} else {
if (filesList.length == 0) {
return false;
}
notification.success({
message: `${title}下载中`,
description: `${title}资源准备中,请稍等...`,
duration: 2,
onClose: () => {
getFile(filesList[0].url, type).then((data: any) => {
FileSaver.saveAs(
data,
filesList[0].name ||
`${Number(filesList[0].rowIndex) + 1}_picture.png`
);
});
callback();
},
});
}
}
/**
*
* @param url
* @returns
*/
//批量
export function getFile(url: string, type: string) {
return new Promise((resolve, reject) => {
if (type != "video") {
fileUrlToBlob(url, (event: any) => {
resolve(event);
});
} else {
urlToBlob(url, (event: any) => {
resolve(event);
});
}
});
}
/**
* URL转为Blob格式
* 图片地址需要允许跨域
* @param url
* @param callback
*/
function urlToBlob(url: any, callback: any) {
// 隐藏referrer属性
const meta = document.createElement("meta");
meta.setAttribute("name", "referrer");
meta.setAttribute("content", "never");
meta.setAttribute("id", "remove");
document.getElementsByTagName("head")[0].appendChild(meta);
const xhr = new XMLHttpRequest();
xhr.open("get", url, true);
// ""|"text"-字符串 "blob"-Blob对象 "arraybuffer"-ArrayBuffer对象
xhr.responseType = "blob";
xhr.onload = function () {
if (this.status == 200) {
const blob: any = this.response;
// const path: any = URL.createObjectURL(xhr.response);
callback(blob);
}
};
xhr.send();
}
/**
*
* @param url
* @param callback
*/
function fileUrlToBlob(url: any, callback: any) {
fetch(url)
.then((res) => res.blob())
.then((res) => {
callback(res);
});
}