前端技术:vue,element-ui,axios
后台技术:springboot
本篇博客只给出关键的代码,提供思路,完全的涉及保密不方便提供
一,上传:
上传element组件代码,支持多文件,拖动文件进行上传:
<!--选择文件-->
<el-form-item label="选择模板" :label-width="formLabelWidth" :required="trueFlag">
<el-row>
<el-col :span="12">
<div class="grid-content bg-purple">
<el-upload
class="upload-demo"
ref="upload"
:action="actionUrl"
:auto-upload="false"
:limit="10"
multiple
accept="application/pdf"
:before-upload="beforeUpload"
:before-remove="beforeRemove"
:on-remove="handleRemove"
:on-change="fileChange"
:file-list="fileList"
:drag="trueFlag">
<el-button size="small" type="primary">选取模板</el-button>
<!--<el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button>-->
<div slot="tip" class="el-upload__tip">只能上传pdf文件,且不超过2M</div>
</el-upload>
</div>
</el-col>
</el-row>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button v-on:click="uploadDialogFormVisible = false">关闭</el-button>
<!--<el-button type="primary" v-on:click="uploadDialogFormVisible = false">上传</el-button>-->
<el-button type="primary" @click="submitUpload">上传到服务器</el-button>
</div>
</el-dialog>
上传前端js方法:
submitUpload: function () {
if (this.area == null || this.area == '' || this.fileList.length < 1) {
this.$message({
message: '区域未选择,或未选取上传模板',
type: 'error'
});
return;
}
let formData = new FormData();
this.fileList.forEach(function (file) {
formData.append("files", file.raw, file.name);
});
let config = {
'Content-Type': 'multipart/form-data'
};
formData.append("area", this.area);
let var_this = this;
axios.post('/model/upload', formData, config)
.then(function (response) {
if (response.data.status == 1) {
var_this.$message({
message: `${var_this.area}区域${var_this.fileList.length}个文件(上传/更新)成功`,
type: 'success'
});
} else {
var_this.$message({
message: response.data.msg,
type: 'error'
});
}
}).catch(function (error) {
console.log(error);
})
}
说明:这里使用的是表单上传多文件,element-ui上传组件默认多文件上传实际上是一个文件一个文件进行上传的,这里利用表单可以实现一次请求上传多个文件,而且,上传文件的同时可以添加其他额外的属性,字段信息
后台springboot接口核心代码:
@PostMapping("upload")
@ResponseBody
public ResponseResult uploadModel(@ModelAttribute ModelFileVO modelFileVO) {
//文件上传具体处理逻辑
return rs;
}
处理多文件上传的接口,内部处理逻辑网上很多资料,可以自己查找资料,主要使用到了@ModelAttribute注解,这个注解支持前端表单形式的参数,这里用来接收多文件,以及其他的参数,下面这个类是具体说明,出了多文件,还使用了额外的area字段,files表示多文件数组,@Data是用来解决set,get问题
@Data
public class ModelFileVO {
private String area;
private MultipartFile[] files;
}
效果图如下:
二,下载:
element-ui下载核心代码:
<template slot-scope="scope">
<!--下载按钮-->
<el-button type="warning" icon="el-icon-download" :circle="isCircle" @click="downloadModel(scope.row)"></el-button>
<!--编辑按钮-->
<el-button type="primary" v-on:click="editUpload" icon="el-icon-edit"
:circle="isCircle"></el-button>
<!--删除按钮-->
<el-button type="danger" v-on:click="deleteModel(scope.$index, scope.row)"
icon="el-icon-delete" :circle="isCircle"></el-button>
</template>
下载vue.js的处理核心代码:
downloadModel: function (row) {
console.log(row);
let param = `?area=${this.area}&id=${row.id}&name=${row.name}`;
axios.post('/model/download'+param
,{area:this.area,id:row.id, name:row.name},{responseType: 'blob'})
.then(response =>{
let data = response.data;
if (!data) {
return
}
console.log(response);
let contentDisposition = response.headers['content-disposition'];
let fileName = contentDisposition.substring(contentDisposition.indexOf('=')+1);
console.log('fileName=' + fileName);
let url = window.URL.createObjectURL(new Blob([data]))
let a = document.createElement('a')
a.style.display = 'none'
a.href = url
a.setAttribute('download',fileName)
document.body.appendChild(a)
//点击下载
a.click()
// 下载完成移除元素
document.body.removeChild(a);
// 释放掉blob对象
window.URL.revokeObjectURL(url);
console.log("下载完成");
}).catch(function (error) {
console.log(error);
});
}
说明:由于下载的是文件流,所以请求的方法配置参数需要把返回类型设置为blob,eg:responseType: 'blob',另外注意axios的get和post方法的传参顺序问题。get方法第一个参数是url+ur后面的参数,第二个参数是请求配置参数;post:有三个参数,第一个是url,第二个是请求参数,第三个是请求的配置数据。
下载下来的blob,我们需要创建一个url来指定这个流,创建html的a标签,设置下载属性download,下载的url,最后调用click方法进行下载,下载完成文件以后记得删除创建的a标签,释放资源。
后端核心代码:
@PostMapping("/download")
@ResponseBody
public ResponseResult download(HttpServletRequest request, HttpServletResponse response, @RequestBody ModelVO modelVO) throws UnsupportedEncodingException {
//.......................业务代码省略,下面给出下载核心代码
//下载逻辑:
// 设置强制下载不打开
response.setContentType("application/force-download");
// 设置文件名,fileName是下载文件的文件名
response.addHeader("Content-Disposition",
"attachment;fileName=" + URLEncoder.encode(downloadModel.getName()+".pdf","UTF-8"));
byte[] buffer = new byte[1024];
//需要下载文件的字节数组
byte[] modelByte = Base64Utils.base64String2Byte(downloadModel.getContent());
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(modelByte);
try {
OutputStream out = response.getOutputStream();
int i = byteArrayInputStream.read(buffer);
while (i != -1) {
out.write(buffer, 0, i);
i = byteArrayInputStream.read(buffer);
}
out.flush();
System.out.println("********************下载success**************");
} catch (IOException e) {
e.printStackTrace();
}finally {
if (byteArrayInputStream != null) {
try {
byteArrayInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return ResponseResult.success();
}
说明:ModelVO是封装的一个类,用来接收post传输的参数,我的项目里使用了thymeleaf模板,所以下载接口需要添加@ResponseBody,不然以为不是接口,是需要返回一个页面的,下载接口是支持get和post,只是get和post方式的话,传参不一样,方法上面的注解也不一样,@PostMapping或@GetMapping
欢迎加群学习交流:331227121