首页 前端知识 springboot vue elementUI实现文件上传和下载(上传到本地文件夹)

springboot vue elementUI实现文件上传和下载(上传到本地文件夹)

2024-02-06 15:02:51 前端知识 前端哥 127 445 我要收藏

后端使用springboot

1.pom文件依赖:添加web和lombok依赖,也可以只添加web

         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

2.在application.yml中指定文件上传路径(根据电脑实际情况修改即可)

# 文件上传
file:
  uploadFilePath: E:/file/upload/

3.新建工具包util,新建类R作为统一返回值

@Data
public class R<T> implements Serializable {

    private Integer code; //编码:1成功,0和其它数字为失败

    private String msg; //错误信息

    private T data; //数据

    private Map map = new HashMap(); //动态数据

    public static <T> R<T> success(T object) {
        R<T> r = new R<T>();
        r.data = object;
        r.code = 1;
        return r;
    }

    public static <T> R<T> error(String msg) {
        R r = new R();
        r.msg = msg;
        r.code = 0;
        return r;
    }

    public R<T> add(String key, Object value) {
        this.map.put(key, value);
        return this;
    }

}

4.编写controller

@RestController
@RequestMapping("/file")
public class FileController {
    @Value("${file.uploadFilePath}")
    String folder;//文件存放路径

    @PostMapping("/upload")
    public R fileUpload(HttpServletRequest req, MultipartFile file) {
        //获取文件路径
        String originalFilename = file.getOriginalFilename();//获取文件名

        //判断文件是否有效 截取看大小和扩展名是否存在
        if (file.getSize() == 0) {
            return R.error("文件无效");
        }
        //文件扩展名是否存在
        String expandedName = originalFilename.substring(originalFilename.lastIndexOf("."));
        if (expandedName == null) {
            return R.error("文件无效");
        }
        //创建文件夹 根据时间 每天为一个文件夹
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String folderLastPath = sdf.format(new Date());//文件夹后缀
        String folderPath = folder + folderLastPath;//文件夹全路径
        //判断文件夹是否存在
        //创建文件夹前判断文件夹是否存在
        File folder = new File(folderPath);
        if (!folder.exists()) {
            folder.mkdirs();//不存在 新建一个文件夹
        }
        //全路径文件名
        String realPath = folderPath + "/" + originalFilename;

        try {
            //判断文件夹内是否存在同名的文件
            File file1 = new File(realPath);
            if (file1.exists()) {//文件已经存在
                //修改文件名
                //获取文件名 shhs.doc中的shhs
                String fileRealName = originalFilename.substring(0, originalFilename.lastIndexOf("."));
                String kuozhanName = originalFilename.substring(originalFilename.lastIndexOf("."));
                //将真是名字设置为(1)后拼接上扩展名
                fileRealName = fileRealName + "(1)";
                originalFilename = fileRealName + kuozhanName;
                //创建文件
                file.transferTo(new File(folder, originalFilename));
                realPath = folderPath + "/" + originalFilename;
                return R.success(realPath);
            }
            //文件不存在 创建文件
            file.transferTo(new File(folder, originalFilename));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return R.success(realPath);
    }
}

5.使用postman进行测试(也可以不用,直接写前端测试)

新建post请求-->输入地址-->选择Body-->选择form-data-->输入file-->在file的行末有一个选项,下拉是文本和file,选择file -->选择文件后发送即可

前端:采用vue+elementUI

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Login</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="keywords"
          content="Flat Dark Web Login Form Responsive Templates, Iphone Widget Template, Smartphone login forms,Login form, Widget Template, Responsive Templates, a Ipad 404 Templates, Flat Responsive Templates"/>
    <!--引入vue.js核心库-->
    <script src="js/vue.js"></script>
    <!--引入elementUI-->
    <script src="element-ui/lib/index.js"></script>
    <!--引入axios.js-->
    <!--axios没用到 可以不引-->
    <!--    <script src="js/axios-0.18.0.js"></script>-->
    <!--引入css-->
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
</head>
<body>
<div id="app">
    <!--判断elementUI是否导入成功-->
    <el-button>默认按钮</el-button>
    <el-button type="primary">主要按钮</el-button>
    <el-button type="success">成功按钮</el-button>

    <el-upload
            action="/upload"
            :on-preview="handlePreview"
            :limit="100"
    >
        <el-button size="small" type="primary">点击上传</el-button>
        <div slot="tip" class="el-upload__tip">只能上传pdf文件 最大值为100M</div>

    </el-upload>
</div>
<script>
    new Vue({
        el: '#app',
        data() {
            return {}
        },
        methods: {
            handlePreview(file) {
                window.open(file.response.url)
            }
        },
        mounted() {

        }
    })
</script>
</body>
</html>

文件下载使用的是浏览器提供的功能,在新窗口打开,pdf等可以预览和下载,图片等直接下载

前后端分离需要解决跨域问题

不足之处:

如果上传的文件在文件夹中已存在,则会自动在后面拼上(1),如abc.docx已存在,则会变成abc(1).docx

但是如果再传一个abc.docx,则原来的abc(1).docx会被覆盖

 可以通过判断数量来不断新增,写起来麻烦,就没有写了,希望对大家有所帮助!!!

转载请注明出处或者链接地址:https://www.qianduange.cn//article/1464.html
评论
发布的文章
大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!