前端,单个文件下载或者分批压缩多个文件下载
import JSZip from "jszip";
import fileSaver from "file-saver";
import axios from 'axios'
import {
Message,
Notification
} from "element-ui";
//下载单个文件
export const downloadSingleFile = (url, filename,postfix,blodFile) => {
filename = filename || "文件名";
let suffix =!postfix? /\.([0-9a-zA-Z]+)$/i.exec(url)[1]:postfix;
const file_type = {
'doc': 'application/msword',
'bin': 'application/octet-stream',
'exe': 'application/octet-stream',
'so': 'application/octet-stream',
'dll': 'application/octet-stream',
'pdf': 'application/pdf',
'ai': 'application/postscript',
'xls': 'application/vnd.ms-excel',
'ppt': 'application/vnd.ms-powerpoint',
'dir': 'application/x-director',
'js': 'application/x-javascript',
'swf': 'application/x-shockwave-flash',
'xhtml': 'application/xhtml+xml',
'xht': 'application/xhtml+xml',
'zip': 'application/zip',
'mid': 'audio/midi',
'midi': 'audio/midi',
'mp3': 'audio/mpeg',
'rm': 'audio/x-pn-realaudio',
'rpm': 'audio/x-pn-realaudio-plugin',
'wav': 'audio/x-wav',
'bmp': 'image/bmp',
'gif': 'image/gif',
'jpeg': 'image/jpeg',
'jpg': 'image/jpeg',
'png': 'image/png',
'css': 'text/css',
'html': 'text/html',
'htm': 'text/html',
'txt': 'text/plain',
'xsl': 'text/xml',
'xml': 'text/xml',
'mpeg': 'video/mpeg',
'mpg': 'video/mpeg',
'avi': 'video/x-msvideo',
'movie': 'video/x-sgi-movie',
'xlsx':"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}
if (blodFile) {
try {
BlodTurnFile(blodFile,file_type[suffix],filename);
} catch (error) {
console.log(error,"文件流下载失败");
}
return
}
return new Promise((resolve, reject) => {
console.log(url, "url");
axios
.get(url, {
responseType: 'blob',
})
.then((res) => {
// const blob = new Blob([res.data], {
// type: file_type[suffix]
// }) // 构造一个blob对象来处理数据,并设置文件类型
// if (window.navigator.msSaveOrOpenBlob) {
// // 兼容IE10
// navigator.msSaveBlob(blob, filename)
// } else {
// const href = URL.createObjectURL(blob) // 创建新的URL表示指定的blob对象
// const a = document.createElement('a')
// a.style.display = 'none'
// a.href = href // 指定下载链接
// a.download = filename // 指定下载文件名
// a.click()
// URL.revokeObjectURL(a.href) // 释放URL对象
// a.remove();
// }
BlodTurnFile(res.data,file_type[suffix],filename);
resolve("下载成功!")
})
})
}
/**
* 二进制转文件
* @param {*} blodStr 二进制流
* @param {*} type 文件类型
* @param {*} name 文件名称
*/
const BlodTurnFile=(blodStr,type,filename)=>{
const blob = new Blob([blodStr], {
type: type
}) // 构造一个blob对象来处理数据,并设置文件类型
if (window.navigator.msSaveOrOpenBlob) {
// 兼容IE10
navigator.msSaveBlob(blob, filename)
} else {
const href = URL.createObjectURL(blob) // 创建新的URL表示指定的blob对象
const a = document.createElement('a')
a.style.display = 'none'
a.href = href // 指定下载链接
a.download = filename // 指定下载文件名
a.click()
URL.revokeObjectURL(a.href) // 释放URL对象
a.remove();
}
}
let file_num = 0;
const zip = new JSZip();
let zip_obj = [];
let floder_obj = [];
let file_order = 0;
let file_floder = null;
let file_data = [];
let file_title = "";
let cur_title = "";
let breakpoint_num = 500; //断点数据
let allowZipFile = true; //等待压缩完成
/**
* [链接数组]
* @param {[type]} paths [{"name":"初三排课班级课表","path":"https://liangcai-product-south.oss-cn-shenzhen.aliyuncs.com/newUpload/xls/初三排课班级课表_1589189955975.xls"}]
* @return {[type]} 下载压缩文件 [description]
*/
export const downloadCompressedFiles = ({
paths = [],
title = "文件批量下载",
percentCallback = () => {},
}) => {
allowZipFile = true;
file_order = 0;
cur_title = (title && title) || "文件批量下载";
file_title = paths.length > breakpoint_num ? title ? `${title}文件第1~${breakpoint_num}个` : `文件批量下载文件1~${breakpoint_num}个` : (title && title) || "文件批量下载";
zip_obj[file_order] = new JSZip();
floder_obj[file_order] = zip_obj[file_order].folder(file_title);
// file_floder = zip.folder((title && title) || "文件批量下载");
file_num = 0;
if (paths.length) {
file_data = paths;
if (file_num < paths.length) {
getUrlBlod(paths[file_num].path, paths[file_num].name, percentCallback);
}
}
}
const getUrlBlod = (url, name, percentCallback = () => {}) => {
// 从url获取文件后缀
let suffix = /\.([0-9a-zA-Z]+)$/i.exec(url)[1];
let promise = httpPost({
url
}).then((data) => {
console.log(file_order, "data123");
// console.log(floder_obj[file_order]);
floder_obj[file_order].file(`${name}.${suffix}`, data, {
binary: true
}); //逐个添加文件
file_num = file_num + 1;
if (file_num != file_data.length) {
if (file_num % breakpoint_num == 0) {
let _temp = file_order;
file_order = file_order + 1;
// file_title = (breakpoint_num + file_num) <= file_data.length ? `${cur_title}文件第${breakpoint_num*_temp}~${file_num}个` : `${cur_title}文件第${file_num}~${file_data.length}个`;
file_title=`${cur_title}文件第${breakpoint_num*_temp}~${file_num}个`;
zip_obj[file_order] = new JSZip();
floder_obj[file_order] = zip_obj[file_order].folder((file_title && file_title) || "文件批量下载");
Notification({
title: '提示',
message: file_title + '开始压缩文件中!请等待',
type: 'info',
duration: 0
});
allowZipFile = false;
zipGenerateAsync(_temp, percentCallback);
}
percentCallback(file_num)
if (allowZipFile) {
getUrlBlod(file_data[file_num].path, file_data[file_num].name, percentCallback);
}
} else {
if (file_num >= file_data.length) {
file_title = `${cur_title}文件第${breakpoint_num * file_order}~${file_data.length}个`;
}
let _temp = file_order;
Notification({
title: '提示',
message: file_title + '开始压缩文件中!请等待',
type: 'info',
duration: 0
});
allowZipFile = false;
zipGenerateAsync(_temp, percentCallback);
}
return file_num;
}).catch(err => {
// console.log(err, "err123");
// Message.error(`${name}文件下载失败!`);
file_num = file_num + 1;
if (file_num != file_data.length) {
if (file_num % breakpoint_num == 0) {
let _temp = file_order;
file_order = file_order + 1;
// file_title = (breakpoint_num + file_num) <= file_data.length ? `${cur_title}文件第${breakpoint_num*_temp}~${file_num}个` : `${cur_title}文件第${file_num}~${file_data.length}个`;
file_title=`${cur_title}文件第${breakpoint_num*_temp}~${file_num}个`;
zip_obj[file_order] = new JSZip();
floder_obj[file_order] = zip_obj[file_order].folder(file_title);
Notification({
title: '提示',
message: file_title + '开始压缩文件中!请等待',
type: 'info',
duration: 0
});
allowZipFile = false;
zipGenerateAsync(_temp, percentCallback);
}
percentCallback(file_num)
if (allowZipFile) {
getUrlBlod(file_data[file_num].path, file_data[file_num].name, percentCallback);
}
} else {
if (file_num >= file_data.length) {
file_title = `${cur_title}文件第${breakpoint_num * file_order}~${file_data.length}个`;
}
Notification({
title: '提示',
message: file_title + '开始压缩文件中!请等待',
type: 'info',
duration: 0
});
let _temp = file_order;
allowZipFile = false;
zipGenerateAsync(_temp, percentCallback);
}
});
}
const zipGenerateAsync = (num, percentCallback = () => {}) => {
zip_obj[num].generateAsync({
type: "blob"
}).then((content) => {
Notification({
title: '成功',
message: file_title + '压缩文件下载成功',
type: 'success',
duration: 0
});
// 生成二进制流
fileSaver.saveAs(
content,
(file_title && `${file_title}.zip`) || "文件批量下载.zip"
); // 利用file-saver保存文件
// Message.error(`压缩文件下载成功!`);
if (file_num == file_data.length) {
file_num = file_num + 1;
}
percentCallback(file_num);
zip_obj[num] = "";
floder_obj[num] = "";
if (file_num < file_data.length) {
allowZipFile = true;
getUrlBlod(file_data[file_num].path, file_data[file_num].name, percentCallback);
}
// Message({
// message: '压缩包文件下载成功!',
// type: 'success'
// });
}).catch(err => {
console.log(err, "压缩下载失败");
zip_obj[num] = "";
floder_obj[num] = "";
allowZipFile = true;
getUrlBlod(file_data[file_num].path, file_data[file_num].name, percentCallback);
Notification.error({
title: '错误',
message: file_title + '压缩下载失败',
duration: 0
});
});
}
const getInPath = (url, name = "") => {
return new Promise(async (resolve, reject) => {
// let result = await axiosDownload(url);
// if (result) {
// resolve(result.data);
// } else {
// reject();
// }
await axiosDownload(url).then(res => {
resolve(res.data)
}).catch(err => {
reject(err)
})
});
};
const axiosDownload = (url, resOpts = {}) => {
const {
type = "get", data = ""
} = resOpts;
const queryArgs = {
url,
method: type,
data,
responseType: "blob",
// headers: {//这个地方看情况而定,如果打开会存在跨域问题
// Accept: "application/json",
// "Content-Type": "application/json; charset=utf-8",
// withCredentials: true,
// },
};
// tips: 这里直接返回的是response整体!
return new Promise((resolve, reject) =>
axios
.request(queryArgs)
.then((res) => resolve(res))
.catch((err) => reject(err))
);
};
const axiosConfig = {
// headers: {
// 'Content-Type': 'application/json;charset=UTF-8',
// },
// timeout: 60000,
responseType: 'blob',
}
const request = axios.create(axiosConfig);
let isRefreshing = false;
let queue = [];
let runQueue = () => {
isRefreshing = true
let first = queue.shift();
first.request()
}
//请求拦截
//所有的网络请求都会先走这个方法
// 添加请求拦截器,所有的网络请求都会先走这个方法,我们可以在它里面为请求添加一些自定义的内容
request.interceptors.request.use((config) => {
// 在发送请求之前做些什么
return config;
}, function (error) {
return Promise.reject(error);
});
// 添加响应拦截器
request.interceptors.response.use(function (response) {
isRefreshing = false
if (!(queue.length === 0)) runQueue()
return response.data
}, function (error) {
console.log(error, 2343);
isRefreshing = false
if (!(queue.length === 0)) runQueue()
// 对响应错误做点什么
return Promise.reject(error);
});
const httpPost = async ({
url,
method = 'get',
data = "",
}) => {
return new Promise((resolve, reject) => {
queue.push({
request: () => {
request({
method,
url,
data,
}).then(res => {
resolve(res)
}).catch(e => {
reject(e)
})
}
})
if (!isRefreshing) runQueue()
})
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix