害嗨嗨,我又来了奥。今天呢,我们讨论的话题是下载文件。当前需求如下:前端写一个文件上传的页面,设置一个上传的按钮,打开后,利用el-upload组件,将Excel文件上传。后端接收到文件后,也返回一个文件流给前端。
后端具体怎么做的这里就不说了,直接说前端需要做哪些操作吧。我们用的是vue脚手架,在template里写html代码如下:
<template>
<div class="box">
<el-card style="width:80%" class="header-card">
<template #header>
<h3>上传文件</h3>
</template>
<el-button size="mini" @click="openUpload" type="success" icon="el-icon-upload">点击上传</el-button>
</el-card>
<el-dialog
:visible.sync="importDialog"
width="1200px"
:close-on-click-modal="false"
center
destroy-on-close
>
<div style="text-align: left" slot="title">index上传</div>
<el-upload
drag
v-loading="importLoading"
action
:before-upload="beforeSampleImportUpload"
:http-request="handleSampleImportUploading"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">请上传excel文件!</div>
</el-upload>
</el-dialog>
</div>
</template>
并配置好样式:
<style lang="scss" scoped>
.box{
//背景占满全屏
min-height: 100%;
background-image: url(../assets/bg0.jpg);
background-repeat: no-repeat;
background-size: cover;
//卡片内容水平垂直居中
display: flex;
justify-content: center;
align-items: center;
}
:deep(.el-upload--text) {
width: 100% !important;
}
:deep(.el-upload-dragger) {
width: 100% !important;
}
.el-upload:before {
content: "";
}
.header-card{
margin: 0 0.5rem 0;
}
:deep(.el-card__body){
min-height: 150px;
}
</style>
现在,得到的网页如下:
下面是js的代码:
<script>
//引入axios,也可以通过拦截器interceptors进行封装
import axios from 'axios'
//引入vuex里的数据(这里专门存的baseurl地址,如果封装了axios,就不需要这一步,这里讲最基础的做法)
import { mapState } from 'vuex';
export default {
data() {
return {
//对话框的显示
importDialog: false,
//对话框的loading
importLoading: false
};
},
methods: {
//在实例文件导入前做的事
beforeSampleImportUpload(file) {
//声明变量,判断是否是Excel文件
const isExcel =
file.type ===
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" || "application/vnd.ms-excel";
//如果不是的话,就不允许上传,并提示信息
if (!isExcel) {
this.$message({
message: "上传失败,只接受excel文件!",
type: "warning",
showClose: true,
});
return false;
}
return true;
},
//在实例文件导入的过程中(调接口)
handleSampleImportUploading(item) {
let formdata = new FormData();
//file字段就是后端接收的字段,值为item.file
formdata.append("file", item.file);
//开始显示加载中
this.importLoading = true;
//调接口
axios({
method: 'post',
url: this.globalBaseUrl + '/xxx', //这里填写url
headers: {
'Content-Type': 'multipart/form-data'
},
data: formdata
}).then(res=>{
//(文件流)
//设置后缀,根据type设置相应的后缀名称(".xls"/".xlsx")
let suffix;
if(res.data && res.data.type=="application/vnd.ms-excel"){
suffix = ".xls"
}else if(res.data && res.data.type=="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"){
suffix = ".xlsx"
}
let url = window.URL.createObjectURL(new Blob([res.data], { type: suffix }));
//弄出一个a标签,隐藏起来,点击后下载文件并移除这个anchor的html标签
let a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.setAttribute('download', `1${suffix}`);
document.body.appendChild(a);
a.click();
url = window.URL.revokeObjectURL(url); //释放内存
document.body.removeChild(a)
}).catch(()=>{
this.$notify({
title:"上传失败",
type:"error",
duration:3500,
showClose:true
})
}).finally(()=>{
//关闭加载和对话框
this.importLoading = false;
this.importDialog = false;
})
},
openUpload(){
//打开对话框
this.importDialog = true
}
},
computed: {
...mapState(["globalBaseUrl"])
},
};
</script>
这样的话,就搞定了。就会直接下载文件了。代码不要直接从头到尾的抄哦,要根据实际应用的需要,来进行操作。