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)

springboot整合vue实现上传下载文件

springboot项目结合fastdfs做文件上传

springboot+vue结合,后端学习前端(前端拦截器+后端拦截器)未登录访问其他页面,直接进入登陆界面

Vue + SpringBoot 上传 Excel 文件