**瑱 2021-09-08 10:31 采纳率: 55%
浏览 191
已结题

vue + springboot 如何实现,下载文件保存到本地,并指定文件夹

需求是:一个保存(保存到本地),一个打开(打开保存在本地的文件)
类似与word,该如何实现

  • 写回答

3条回答 默认 最新

  • 是赵敢敢啊 2021-09-08 10:37
    关注

    创建OutputStream的时候指定好目录就行了,把这个目录还有文件名存下来,下次想打开就再读出来

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • _oP_i 2021-09-08 10:40
    关注
    评论
  • 小P聊技术 2021-09-08 10:42
    关注

    目前使用 Java 实现对 Excel 解析的功能已经实现。前人已经帮助我们造好了轮子,我直接用就好了,通过在网上一番搜索,我查到了两种方式可以实现对 Excel 解析的第三方库

    1. POI (Apache 出品)
    2. easyExcel (阿里巴巴项目组出品)

    这里我只是提一下有哪些工具可以协助我们完成文件解析的工作,我们今天的重心是如何实现在 Vue CLI4 创建的项目中,实现文件的上传功能。

    2.1 SpringBoot 后端部分功能实现 —— 配置文件部分

    在 application.yml 文件中做如下相关配置

    1. 是否开启文件上传的功能,以及配置文件写入大小,等等一些其他内容
    2. 自定义文件存储路径 (将从前端上传的文件保存至我们的本地)
    spring:
      servlet:
        multipart:
          enabled: true 
          file-size-threshold: 2KB 
          max-file-size: 100MB
          max-request-size: 215MB 
    
    
    gorit:
      file:
        root:
          path: I:\dev\
    

    2.2 SpringBoot 后端文件上传的 controller 编写

    package cn.gorit.controller.api.v1.file;
    
    import cn.gorit.common.lang.Result;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.multipart.MultipartFile;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.File;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    
    @Api(value = "文件上传,下载相关功能")
    @RestController
    @RequestMapping("/api/v1")
    public class FileController {
        
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        
        @Value("${gorit.file.root.path}")
        private String filePath;
        
        private Logger log = LoggerFactory.getLogger("FileController");
    
        
        @PostMapping("/upload")
        public Result fileUploads(HttpServletRequest request,@RequestParam("file") MultipartFile file) throws IOException {
            
            String format = sdf.format(new Date());
            
            String fileName = file.getOriginalFilename();
            
            String newFileName = format + "_" + fileName;
            
            File dest = new File(filePath + newFileName);
            try {
                
                file.transferTo(dest);
                
                log.info("上传成功,当前上传的文件保存在 {}",filePath + newFileName);
                
                return Result.succ("上传成功");
            } catch (IOException e) {
                log.error(e.toString());
            }
            
            return Result.fail("上传错误");
        }
    }
    

    ---------- 2020年12月2日补充 ----------
    后台收到了多个小伙伴的询问,cn.gorit.common.lang.Result; 中的 Result 类是啥意思。

    这个类的作用是我自定义的一个通用返回结果集,一般情况下返回的数据格式如下

    {
        "code": 200,
        "msg": "success",
        "data": ""
    }
    

    如果要想返回指定格式的数据,只需要加入泛型即可 Result< T >

    package cn.gorit.common.lang;
    
    public class Result {
        private Object data;
        private String msg;
        private int code;
    
        
        
        public static Result succ(Object data) {
            return succ(200, "操作成功", data);
        }
    
        public static Result succ(String msg) {
            return succ(200, msg, null);
        }
    
    
        public static Result succ(int code, String msg, Object data) {
            Result r = new Result();
            r.setCode(code);
            r.setMsg(msg);
            r.setData(data);
            return r;
        }
    
        public static Result succ(String msg, Object data) {
            return succ(200,msg,data);
        }
    
        
        public static Result fail(int code, String msg, Object data) {
            Result r = new Result();
            r.setCode(code);
            r.setMsg(msg);
            r.setData(data);
            return r;
        }
    
        public static Result fail(String msg) {
            return fail(400,msg,null);
        }
    
        public static Result fail(int code, String msg) {
            return fail(code,msg,"null");
        }
    
        public static Result fail(String msg, Object data) {
            return fail(400,msg,data);
        }
    }
    
    

    2.3 Vue 前端编写

    文件上传我自己编写了一个对话框上去

    逻辑代码如下

    <template>
        <div>
            <el-button class="btn-upload" type="primary" @click="handleUpdate">上传题库</el-button>
            <el-dialog
                title="提示"
                :visible.sync="dialogVisible"
                width="30%"
                >
                <span>
                    <el-upload class="upload-demo"
                        ref="upload"
                        drag 
                        action="http://localhost:9999/api/v1/upload" 
                        multiple
                        :auto-upload="false"
                        :limit="5"
                        :on-success="handleFilUploadSuccess"
                        :on-remove="handleRemove"
                        >
                        <i class="el-icon-upload"></i>
                        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
                        <div class="el-upload__tip" slot="tip">只能上传 Excel 文件,且不超过500kb</div>
                    </el-upload>
                </span>
                <span slot="footer" class="dialog-footer">
                    <el-button @click="dialogVisible = false">取 消</el-button>
                    <el-button type="primary" @click="handleUpload">确 定</el-button>
                </span>
            </el-dialog>
        </div>
    </template>
    
    <script>
        export default {
            name: "Upload",
            data () {
                return {
                    dialogVisible: false
                }
            },
            methods: {
                handleRemove(file,fileList) {
                    console.log(file,fileList);
                },
                submitUpload() {
                    this.$refs.upload.submit();
                },
                
                handleFilUploadSuccess (res,file,fileList) {
                    console.log(res,file,fileList)
                    this.$message.success("上传成功")
                },
                handleUpdate () {
                    this.dialogVisible = true;
                },
                
                handleUpload () {
                    
                    this.submitUpload()
                    this.dialogVisible = false
                }
            }
        }
    </script>
    
    <style scoped="scoped">
        .btn-upload {
            top: 70px;
            right: 40px;
            position: fixed;
            z-index: 100;
            border-radius: 30px;
            box-shadow: 0 2px 12px 0 rgba(91, 156, 255, 0.9)
        }
        
        .el-upload {
            margin: 5px;
        }
    </style>
    

    前端上传我还用到了 Element UI 组件,并且我禁用了自动上传到后端的功能,用户可以一次添加多份文件,然后最终一起上传

    在后台可以看到打印的 日志信息

    我们进入该路径查看上传好的内容

    可以看到上传好的文件在上面了

    2020年7月31日 补充更新


    其实这个问题第二天就解决了,然后现在也到月底了,也给自己这篇文章画上一份完结的计划。

    文件下载的逻辑,其实没有很复杂,我们是用一个 a 标签,然后加上一个 download 属性,href 就对应静态资源在后端服务的地址,就可以实现下载功能了。

    3.1 配置后端服务的静态资源路径

    我们在创建好的 SpringBoot 项目中,资源目录专门存放在 resources 目录下,里面有个 static 目录和 templates 目录。这里我们会用到 static 目录作为我们的静态资源的路径。

    我们在学习 SpringBoot 整合 SpringMVC 的时候,我们需要自己编写一个 配置类,来指定 SpringBoot 项目的静态资源的目录。配置类的编写如下

    package cn.gorit.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    
    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
    
        
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry
                    .addResourceHandler("/static/**")
                    .addResourceLocations("classpath:/static/");
        }
    }
    

    这样做的话,我们就可以在静态文件里面编写静态页面,并在后端服务显示了。但是我们的项目是 前后端分离的,所以就不会在 static 目录里面编写任何静态页面,我们把需要下载的静态资源放进去

    然后在外面,这个静态资源的请求路径就是 http://localhost:xxx/data/你的文件名称

    3.2 Vue 前端实现下载功能

    我们看下这个下载的链接有什么特殊的。这里我们参考菜鸟教程给的格式来修改

    我们来看看两个属性的作用

    • href 表示资源的路径,
    • download 表示指定下载的文件

    说完就改,我们的资源是放在 SpringBoot 的 resources 目录下。我们也在前面配置了 SpringMVC 的相关配置,这样这个静态资源之后就可以获取到了。

    可以先看看效果如何

    然后我们直接在 href 中填写,后端指定资源的路径,就完成下载功能啦

        <a style="color: #ffffff;" class='download' href='http://localhost:9999/data/contest_templates.xls' download="contest_templates.xls" title="excel模板下载">
            Excel模板下载
        </a>
    
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 9月16日
  • 已采纳回答 9月8日
  • 创建了问题 9月8日

悬赏问题

  • ¥60 悬赏求解,通过实时现场摄像头的视频图像识别其他对家打出的麻将牌,识别麻将牌,识别牌墙位置,通过识别对家打出了什么牌
  • ¥15 关于#GPU jetson#的pcie驱动开发问题,如何解决?
  • ¥15 stm32f103zet6 串口5无法收发数据
  • ¥15 关于C语言使用线程队列实现多线程并发
  • ¥15 这个运行,错误在哪里呀,大家看看吧,教导我
  • ¥15 advanceinstaller对话框设置
  • ¥100 正常上网,内部网页无法打开
  • ¥15 组件库引入并使用在若依框架未展示
  • ¥149 关于#使用python 的Flash Echarts+ajax+mysql动态数据实现饼图#的问题,请各位专家解答!
  • ¥15 RichTextBox中追加文本时报错