Vue文件下载和导出
1.Promise.all()的运行机制
-
输入参数是一个可迭代对象,每个元素是一个 Promise。
-
返回一个新的 Promise,该 Promise 在所有输入的 Promise 都成功解决时解决,或者在任何一个输入的 Promise 被拒绝时立即拒绝。
1.以下解释:该 Promise 在所有输入的 Promise 都成功解决时解决// 工具函数 function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } function fetchUser(id) { return delay(1000).then(() => ({ id, name: `User ${id}` })); } function fetchPost(id) { return delay(500).then(() => ({ id, title: `Post ${id}` })); } function fetchComment(id) { return delay(800).then(() => ({ id, content: `Comment ${id}` })); } async function fetchData() { try { const [user, post, comment] = await Promise.all([ fetchUser(1), fetchPost(1), fetchComment(1) ]); console.log('User:', user); console.log('Post:', post); console.log('Comment:', comment); } catch (error) { console.error('Error:', error); } } fetchData();
结果:
-
注:尽管 fetchPost 和 fetchComment 的延迟时间比 fetchUser 短,但 Promise.all 返回的结果数组中的顺序仍然是 [user, post, comment],对应输入数组中的顺序 等待所有 Promise 都解决后,将结果解构赋值给 user、post 和 comment。
2.以下解释:在任何一个输入的 Promise 被拒绝时立即拒绝。
function fetchUser(id) { return delay(1000).then(() => ({ id, name: `User ${id}` })); } function fetchPost(id) { return delay(500).then(() => ({ id, title: `Post ${id}` })); } function fetchComment(id) { return delay(800).then(() => { if (id === 1) { throw new Error('Comment not found'); } return { id, content: `Comment ${id}` }; }); } async function fetchData() { try { const [user, post, comment] = await Promise.all([ fetchUser(1), fetchPost(1), fetchComment(1) ]); console.log('User:', user); console.log('Post:', post); console.log('Comment:', comment); } catch (error) { console.error('Error:', error.message); } } fetchData();
结果:
-
2.Vue文件下载导出
如果请求没有设置responseType: 'blob',需要用new Blob()方法转化成Blob对象
如果请求设置了responseType: 'blob',返回的就是Blob对象了,可以直接用
Content-Type 头的区别
multipart/form-data
用于文件上传或表单数据包含文件的情况。
数据以二进制流的形式发送,每个部分都有自己的 Content-Type。
常见于 <form> 标签中使用 enctype="multipart/form-data" 属性。
application/x-www-form-urlencoded
用于普通的表单数据提交。
数据以键值对的形式发送,键和值都经过 URL 编码。
常见于 <form> 标签中默认的 enctype 属性值。
application/json;charset=utf-8
用于发送 JSON 格式的数据。
数据以 JSON 字符串的形式发送,通常用于 API 请求。
charset=utf-8 指定了字符编码为 UTF-8,确保数据的正确解析。
responseType: 'blob'// 表明返回服务器返回的数据类型
blob:
用于接收二进制大对象(Blob)格式的响应数据。
适用于下载文件、图片等二进制数据。
// 工具函数(下载+导出方法)
exportUtils(res) {
//如果请求中没有设置responseType: "blob",则需要把拿到的数据转成blob类型如下
let blob = new Blob([res], { type: 'application/vnd.ms-excel' });
// 创建下载链接
let url = window.URL.createObjectURL(blob);
let url = window.URL.createObjectURL(res.data);
//表示一个指定的file对象或Blob对象
let a = document.createElement("a");
document.body.appendChild(a);
a.href = url;
//filename名称截取(后端拼到了header头里了)
let fileName = res.headers["content-disposition"]
.split(";")[1]
.split("=")[1];
a.download = fileName; // 命名下载名称,文件名解码
a.click(); //点击触发下载
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
},
Vue使用new Blob()实现不同类型的文件下载导出
后缀名 | 文件类型 | 类型(type) |
---|---|---|
.xls | Microsoft Excel | application/vnd.ms-excel |
.xlsx | Microsoft Excel (OpenXML) | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
.csv | CSV | text/csv |
.doc | Microsoft Word | application/msword |
.docx | Microsoft Word (OpenXML) | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
application/pdf | ||
.ppt | Microsoft PowerPoint | application/vnd.ms-powerpoint |
.pptx | Microsoft PowerPoint (OpenXML) | application/vnd.openxmlformats-officedocument.presentationml.presentation |
.png | 便携式网络图形(PNG) | image/png |
.gif | GIF | image/gif |
.jpeg | JPEG 图片 | image/jpeg |
.jpg | JPEG 图片 | image/jpeg |
.mp3 | MP3 音频 | audio/mpeg |
.aac | AAC 音频 | audio/aac |
.html | 超文本标记语言 (HTML) | text/html |
.css | CSS | text/css |
.js | JavaScript | text/javascript |
.json | JSON 格式 | application/json |
.abw | AbiWord 文档 | application/x-abiword |
.arc | 存档文档(多个文件嵌入) | application/x-freearc |
.avi | AVI: 音频视频交错 | video/x-msvideo |
.azw | 亚马逊Kindle电子书格式 | application/vnd.amazon.ebook |
.bin | 任何类型的二进制数据 | application/octet-stream |
.bmp | Windows OS/2位图图形 | image/bmp |
.bz | BZip 存档 | application/x-bzip |
.bz2 | BZip2 存档 | application/x-bzip2 |
.csh | C-Shell 脚本 | application/x-csh |
.eot | MS嵌入式OpenType字体 | application/vnd.ms-fontobject |
.epub | 电子出版物(EPUB) | application/epub+zip |
.htm | 超文本标记语言 (HTML) | text/html |
.ico | Icon 格式 | image/vnd.microsoft.icon |
.ics | iCalendar 格式 | text/calendar |
.jar | Java Archive (JAR) | application/java-archive |
.jsonld | JSON-LD 格式 | application/ld+json |
.mid | 乐器数字接口(MIDI) | audio/midi audio/x-midi |
.midi | 乐器数字接口(MIDI) | audio/midi audio/x-midi |
.mjs | JavaScript 模块 | text/javascript |
.mpeg | MPEG 视频 | video/mpeg |
.mpkg | 苹果安装程序包 | application/vnd.apple.installer+xml |
.odp | OpenDocument演示文档 | application/vnd.oasis.opendocument.presentation |
.ods | OpenDocument 电子表格文件 | application/vnd.oasis.opendocument.spreadsheet |
.odt | OpenDocument 文本文档 | application/vnd.oasis.opendocument.text |
.oga | OGG 音频 | audio/ogg |
.ogv | OGG 视频 | video/ogg |
.ogx | OGG | application/ogg |
.otf | OpenType 字体 | font/otf |
.rar | RAR 存档 | application/x-rar-compressed |
.rtf | 富文本格式 (RTF) | application/rtf |
.sh | Bourne shell 脚本 | application/x-sh |
.svg | 可缩放矢量图形 (SVG) | image/svg+xml |
.swf | 小型web格式 (SWF) or Adobe Flash document | application/x-shockwave-flash |
.tar | Tape 归档(TAR) | application/x-tar |
.tif | 标记图像文件格式 (TIFF) | image/tiff |
.tiff | Tagged Image File Format (TIFF) | image/tiff |
.ttf | TrueType 字体 | font/ttf |
.txt | Text | text/plain |
.vsd | Microsoft Visio | application/vnd.visio |
.wav | 波形音频格式 | audio/wav |
.weba | WEBM 音频 | audio/webm |
.webm | WEBM 视频 | video/webm |
.webp | WEBP 图片 | image/webp |
.woff | 网页开放字体格式 (WOFF) | font/woff |
.woff2 | 网页开放字体格式 (WOFF) | font/woff2 |
.xhtml | XHTML | application/xhtml+xml |
.xml | XML | application/xml(普通用户不可读)、text/xml(普通用户可读) |
.xul | XUL | application/vnd.mozilla.xul+xml |
.zip | ZIP | application/zip |
.3gp | 3GPP audio/video 容器 | video/3gpp、audio/3gpp(不含视频) |
.3g2 | 3GPP2 audio/video 容器 | video/3gpp2、audio/3gpp2(不含视频) |
.7z | 7-zip | application/x-7z-compressed |
项目中后端返回的是文件上传成功生成的一个字符串,为了保证可以下载所有文件,需要对后缀进行截取进行判断然后取不同的new Blob,这里new Blob中后端直接返回的是文件流,所以直接用res进行获取
注意:responseType一定要指定类型
downloadExample(assetNo,downloadAddress){
axios({
method: "get",
url: '/dev-api/directory/io/exportdemo?assetNo=' + assetNo + '&fileNo=' + downloadAddress,
data: "",
responseType: "blob", // 指定响应类型为二进制数据
}).then((res) => {
// 下载格式为zip { type: "application/zip" }
let suffix = downloadAddress.substring(downloadAddress.lastIndexOf("."))
if (suffix=='.xls'){
let blob = new Blob([res], {type: "application/vnd.ms-excel"});
this.ways(blob,suffix);
}else if (suffix=='.xlsx'){
let blob = new Blob([res], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});
this.ways(blob,suffix);
}else if (suffix=='.doc'){
let blob = new Blob([res], {type: "application/msword"});
this.ways(blob,suffix);
}else if (suffix=='.docx'){
let blob = new Blob([res], {type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"});
this.ways(blob,suffix);
}else if (suffix=='.png'){
let blob = new Blob([res], {type: "pplication/pdf"});
this.ways(blob,suffix);
}else if (suffix=='.ppt'){
let blob = new Blob([res], {type: "application/vnd.ms-powerpoint"});
this.ways(blob,suffix);
}else if (suffix=='.png'){
let blob = new Blob([res], {type: "image/png"});
this.ways(blob)
}else if (suffix=='.pptx'){
let blob = new Blob([res], {type: "application/vnd.openxmlformats-officedocument.presentationml.presentation"});
this.ways(blob,suffix);
}else if (suffix=='.jpeg'){
let blob = new Blob([res], {type: "image/jpeg"});
this.ways(blob,suffix);
}else if (suffix=='.zip'){
let blob = new Blob([res], {type: "application/zip"});
this.ways(blob,suffix);
}else if (suffix=='.7z'){
let blob = new Blob([res], {type: "application/x-7z-compressed"});
this.ways(blob,suffix);
}else if (suffix=='tar'){
let blob = new Blob([res], {type: "application/x-tar"});
this.ways(blob,suffix);
}else if (suffix=='.7z'){
let blob = new Blob([res], {type: "application/x-7z-compressed"});
this.ways(blob,suffix);
}
})
},
ways(blob, suffix,res) {
let elink = document.createElement("a"); // 创建一个<a>标签
elink.style.display = "none"; // 隐藏标签
elink.href = window.URL.createObjectURL(blob); // 配置href
// 获取后端返回的响应头中的名称
let filename = res.headers["content-disposition"];
let newFilename = filename.split(';')[1].split('=')[1];
//自定义名称
// let newFilename = "样例文件" + new Date().getTime() + suffix;
//自定义名字
// let newFilename = decodeURIComponent(res.headers["content-disposition"].split(';')[1].split('=')[1])
newFilename = decodeURIComponent(newFilename);
elink.download = newFilename;
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象(弹出框进行下载)
document.body.removeChild(elink); // 移除<a>标签
},
文件流下载处理简单代码示例:
let blob = new Blob([res], {type:'application/vnd.ms-exce;chartset=utf-8' });
let downloadElement = document.createElement('a');
let href = window.URL.createObjectURL(blob); //创建下载的链接
downloadElement.href = href;
downloadElement.download ='用户.xlsx'; //下载后文件名
document.body.appendChild(downloadElement);
downloadElement.click(); //点击下载
document.body.removeChild(downloadElement); //下载完成移除元素
window.URL.revokeObjectURL(href);
原文链接:https://blog.csdn.net/oBoLuoMi1/article/details/137549304
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现