1.vue实现文件上传下载的方式
下载
- 第一种方式是前端创建超链接,通过a标签的链接向后端服务发get请求,接收后端的文件流
<a :href='"/user/downloadExcel"' >下载模板</a>
// 另一种情况是创建div标签,动态创建a标签:
<div name="downloadfile" onclick="downloadExcel()">下载</div>
function downloadExcel() {
let a = document.createElement('a')
a.href ="/user/downloadExcel"
a.click(); }
// 还有一种充:
function downloadExcel() {
window.location.href = "/tUserHyRights/downloadUsersUrl";
}
2. 通过创建iframe的方式
<el-button size="mini" class="filter-item" type="primary" icon="el-icon-download" @click="handleExport(scope.row)">导出</el-button>
//method方法:
handleExport(row) {
var elemIF = document.createElement('iframe')
elemIF.src = 'user/downloadExcel?snapshotTime=' + formatDate(new Date(row.snapshotTime), 'yyyy-MM-dd hh:mm') + '&category=' + row.category
elemIF.style.display = 'none'
document.body.appendChild(elemIF)
}
3. 向后端发的post请求,使用blob格式
var _this = this
const _searchForm = this.$refs.searchForm.searchForm
axios({ //该请求根据自己项目自己调整
method: 'get',
url: _this.baseUrl + 'prism/satisfaction/downloadTemplate',
responseType: 'blob',
params: { brand: 'xx', currentDate: _searchForm.currentDate, type: _searchForm.type, category: _searchForm.category },
headers: {
'data-type': 'Buffer',
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'token': getToken()
}
}).then(res => {
const url = window.URL.createObjectURL(new Blob([res.data]))
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', 'all_sample_fa_kegg_blast_bst.xls') // 指定下载后的文件名,防跳转
document.body.appendChild(link)
link.click()
})
downLoadFile(fileName){
axios({
url:'http://localhost:3030/api/download',
method:'get',
responseType: 'arraybuffer',
/*
当将responseType设置为一个指定类型时,你需要确保服务器所返回的类型和你所设置的返回值类型是兼容的。那么如果两者类型不兼容呢?恭喜你,你会发现服务器返回的数据变成了null,即使服务器返回了数据。
通俗来说,如果你resoinseType设置的是JSON,就会将后端穿过来的数据尝试转换为Json格式,如果转换不了那就会强制转换成null。
我们下载文件一般设置responseType为blob或者arraybuffer都可以,为什么呢,一般下载文件掉后台接口,一般后台返回都是二进制数据。而blob和arraybuffer都是二进制数据的一种,所以当我们设置responseType为blob时,请求到后台返回的二进制数据后就会将该二进制数据转换为blob类型的二进制数据。设置responseType为arraybuffer是一样的道理
当然如果你不安规矩来,瞎几把乱搞,比如后台穿的是一个对象类型的数据例如{name:'xq'},我们知道对象是可以转成Json的,但是如果你response不是设置的Json,而是设置的arraybuffer或者blob,那么请求到数据时就会尝试将对象类型的数据转换为arraybuffer或者blob类型的二进制数据。这很明显是转不了的,这不就乱套了嘛,所以这个时候就会直接返回一个null空数据。
*/
params:{
fileName
}
}).then(
(res) => {
console.log(res)
//使用Blob对象将后端返回的Arraybuffer格式得数据转成blob类型的数据 window.URL.createObjectURL(blob)可以把一个blob转成blobURL,用作图片显示,文件下载(不能再服务器上存储,只能在浏览器使用)
var b = new Blob([res.data], { type: 'application/vnd.ms-excel' });
// 使用URL对象将blob类型的数据生成一个在线下载的链接
var url = URL.createObjectURL(b);
// 然后我们使用a标签进行下载
var link = document.createElement('a');
// 设置导出的文件名
link.download = file.name;
link.href = url;
// 点击获取文件
link.click();
},
(err) => {
console.log(err);
}
);
}
上传
- input方式
vue中的文件上传主要分为两步:前台获取到文件和提交到后台。
(1)前台获取文件,主要是采用input框来实现。
<input type="file" ref="clearFile" @change="getFile($event)" multiple="multiplt" class="add-file-right-input" style="margin-left:70px;" accept=".docx,.doc,.pdf">
<el-button type="primary" @click="submitAddFile" size="small">开始上传</el-button> 复制代码
通过file类型的input框实现文件上传;然后通过设置multiple="multiplt"实现了多文件上传,并且使用accept实现了上传文件类型限制;最后通过监听change事件,前台获取到上传的文件。
getFile(event){
var file = event.target.files;
for(var i = 0;i<file.length;i++){
// 上传类型判断
var imgName = file[i].name;
var idx = imgName.lastIndexOf(".");
if (idx != -1){
var ext = imgName.substr(idx+1).toUpperCase();
ext = ext.toLowerCase( );
if (ext!='pdf' && ext!='doc' && ext!='docx'){
}else{
this.addArr.push(file[i]);
}
}else{
}
}
}
通过change事件中的event.target.files就能获取到上传的文件了,在上面再次对获取的文件进行了类型限制。
(2)数据提交
获取到文件数据后,就需要将数据提交到后台,这里可以采用FormData的方式提交。
submitAddFile(){
if(0 == this.addArr.length){
this.$message({
type: 'info',
message: '请选择要上传的文件'
});
return;
}
var formData = new FormData();
formData.append('num', this.addType);
formData.append('linkId',this.addId);
formData.append('rfilename',this.addFileName);
for(var i=0;i<this.addArr.length;i++){
formData.append('fileUpload',this.addArr[i]);
}
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': this.token
}
};
this.axios.post(apidate.uploadEnclosure,formData,config)
.then((response) => {
if(response.data.info=="success"){this.$message({
type: 'success',
message: '附件上传成功!'
});
}
})
}
在进行数据提交的时候,有两点需要注意:formData对象和Content-Type,处理好着两点以后,就和其他的接口一样了。
2. el-upload