springboot结合vue的文件上传下载
Posted 你,好
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot结合vue的文件上传下载相关的知识,希望对你有一定的参考价值。
我们项目需要一个文件上传在后台解析后再下载的功能,正好记录一下,以后拿来就能用,有问题的小伙伴可以留言,一起解决哦。
文件上传
前端
我使用了element-ui的上传组件,由于需要携带自己的参数,所以覆盖了默认上传的方法,改用自己post上传,并加入了Loading组件,提高使用感。细节看代码。
<template>
<el-main style="margin-left: 50%; transform: translateX(-200px)">
<div>
<h1>解析板块</h1>
</div>
<div class="upload-box">
<el-upload
<!-- action必须为空 -->
action=""
class="upload"
ref="upload"
<!-- 限制只能上传一个文件 -->
:limit="1"
<!-- 自定义提交函数 -->
:http-request="myUpload"
<!-- 关闭自动提交 -->
:auto-upload="false"
<!-- 提交前触发的函数 -->
:before-upload="beforeUpload"
<!-- 从待上传文件列表中删除文件触发的函数 -->
:on-remove="formHandleRemove"
<!-- 文件允许上传的格式 -->
accept=".txt"
<!-- 待上传文件列表 -->
:file-list="fileList">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<el-button style="margin-left: 20px" size="small" type="success" @click="upload">解析</el-button>
<!-- v-if 当解析完成后,会显示出来 -->
<el-button v-if="downloadUrl" size="small" type="warning"><a :href="downloadUrl">下载</a></el-button>
<div slot="tip" class="el-upload__tip"><p>单文件上传</p>只能上传txt文件,最大100MB</div>
</el-upload>
</div>
</el-main>
</template>
<script>
import axios from "axios";
export default
name: "Analyze",
data()
return
// 待上传文件列表
fileList: [],
// 文件名
fileName: "",
// 后台接口
url: "step_one/analyze",
// 下载地址
downloadUrl: "",
;
,
methods:
// 以elementui的方式提交,on-remove before-upload 这些属于elementui的属性才能生效.
// 也可以全部自己写然后在自定义上传函数调用.
async upload()
this.$refs.upload.submit();
,
// 自定义上传函数 param 是 上传的参数,默认存在
myUpload(param)
// 开启loading
const loading = this.$loading(
lock: true,
text: '正在解析,请稍候。。。',
spinner: 'el-icon-loading',
);
// 因为后台接收formdata格式,所以要创建formdata对象
const formdata = new FormData()
// 添加参数
formdata.append('file', param.file)
formdata.append('fileName', this.fileName)
// post上传
this.$http.post(this.url, formdata).then(res =>
let data = res.data
// 获取成功
if (data.code === 200)
this.$message.success(data.msg);
// 给downloadUrl赋值,同时,下载按钮会出现
this.downloadUrl = this.$http.defaults.baseURL + "download/" + this.fileName;
// 获取失败
else
this.$message.error(data.msg);
// 关闭loading
loading.close();
)
// 清空列表
this.fileList = []
,
formHandleRemove(file)
// 从fileList中移除选中的文件
for (let i = 0; i < this.fileList.length; i++)
if (this.fileList[i].name === file.name)
this.fileList.splice(i, 1)
break
,
beforeUpload(file)
// 限制100M
if (file.size > 100 * 1024 * 1024)
this.$message.error('上传文件过大!')
return false
let filename = file.name
let arr = filename.split('.')
// 检验上传文件格式
if (arr[1] !== 'txt')
this.$message.error('上传文件只能是 txt 格式!')
return false
this.fileName = arr[0];
return arr
,
</script>
<style scoped>
</style>
后端
后端对文件解析之后保存在本地,方便用户下载。直接抛异常是因为有全局异常处理,在这里不是重点,就不细说了。
@PostMapping("step_one/analyze")
public R segment(@RequestParam("file") MultipartFile file, @RequestParam(value = "fileName") String fileName) throws Exception
// 加txt后缀
fileName += ".txt";
// 文件完整路径 savePath是保存路径
String filePath = savePath + fileName;
// 读取文件
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream ips = file.getInputStream();
byte[] buffer = new byte[8192]; // 这样效率与缓冲流持平
int len = 0;
while ((len = ips.read(buffer)) != -1)
baos.write(buffer, 0, len);
String content = baos.toString();
// 解析文件
System.out.printf("正在解析--%s\\n", fileName);
PerceptronLexicalAnalyzer analyzer = new PerceptronLexicalAnalyzer();
Sentence analyze = analyzer.analyze(content);
System.out.printf("解析完成--%s\\n", fileName);
// 保存文件
System.out.printf("开始保存--%s\\n", filePath);
FileOutputStream fops = new FileOutputStream(filePath);
fops.write(analyze.toString().getBytes());
System.out.printf("保存完毕--%s\\n",filePath);
// 关闭流
ips.close();
fops.close();
baos.close();
// 返回
return new R(200, "解析成功", null);
效果
下载
前端
在上传成功之后,我们就获得了下载地址,直接用 a 标签即可。
<el-button v-if="downloadUrl" size="small" type="warning"><a :href="downloadUrl">下载</a></el-button>
后端
后端只需要设置一下响应头即可。值得注意的是如果是中文文件名必须要转一下码,否则不会正常显示,细节看代码。
@RequestMapping("download/fileName")
public void download(HttpServletResponse response, @PathVariable String fileName) throws Exception
fileName += ".txt";
// 设置请求头 new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1) 转码
response.setHeader("Content-Disposition", "attachment; filename="
+ new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
System.out.printf("正在下载--%s\\n", fileName);
// 从刚刚保存的路径下载
FileInputStream fips = new FileInputStream(savePath + fileName);
// 获取输出流
ServletOutputStream sops = response.getOutputStream();
byte[] buffer = new byte[8192];
int len = 0;
while ((len = fips.read(buffer)) != -1)
sops.write(buffer, 0, len);
System.out.printf("下载完毕--%s\\n", fileName);
// 关闭流
sops.flush();
fips.close();
sops.close();
效果
以上是关于springboot结合vue的文件上传下载的主要内容,如果未能解决你的问题,请参考以下文章
最细致的Spring Boot结合Vue前后端分离项目打包部署步骤(搭配Nginx)
最细致的Spring Boot结合Vue前后端分离项目打包部署步骤(搭配Nginx)