作者: Memory(星哥) Wechat:/QQ: 574373426
整理不易,感谢支持,欢迎 收藏 转发 分享
专注IT职业教育多年,学编程找星哥

SpringBoot+Vue+ElementUI实现文件拖拽点击上传,文件下载

  • 前言
    • 技术栈
    • 引言
  • 前端代码
  • 后台项目搭建
    • 创建项目
    • 创建配置文件 image.properties
    • application.yml配置文件
  • 上传文件实现
    • 实体类
    • 控制层
    • 业务层
    • 效果
  • 下载文件实现
    • 控制层
    • 业务层
    • 效果
  • gitee代码仓库地址

前言

技术栈

前后端分离
后端: SpringBoot, IO流
前端: Vue , ElementUI , Axios
开发工具: IDEA2020.3.4

引言

文件上传,和下载在我们的大部分项目中都比较适用
比如: 学生提交作业,毕业设计,员工提交报销发票凭证等
本文章实现了文件拖拽或者点击上传,点击下载功能,方便大家在做相关业务的时候能快速上手,效果图如下

前端代码

使用 ElementUI 的文件上传组件,很方便
使用Vue做数据,事件绑定
重要:
业务逻辑: 在上传文件的时候在前端直接判断文件格式是否正确,我这里只判断了部分(jpg,png,pdf,xls等) 使用 file.type 这个属性做判断 如果大家不知道 某一个格式在浏览器解析时候前端的具体格式,可以上传文件触发事件时先 alert(file.type) 输出一下,就知道该如何判断了,例如PDF格式是这样的: file.type === 'application/pdf’

注意:代码里因为下载演示比较麻烦,没有实际业务数据,我下载文件地址动态的设置了上一次上传文件的路径,所以要先上传文件,再点击下载

ElementUI上传组件参数解释:
官方文档描述: https://element.eleme.cn/#/zh-CN/component/upload

我用到的:
action 必选参数,上传的地址
drag 支持拖拽上传
multiple 支持多选文件(前台支持,我后台代码没支持,略微麻烦可以自己尝试)
:file-list 显示已上传列表
:on-success 文件上传成功时的钩子函数(上传成功走此方法)
:before-upload 上传文件之前的钩子,参数为上传的文件,用来做判断(上传前先走此方法)
其他可以参考文档根据实际业务添加

代码如下: 采用cdn方式在线引入,保证电脑有网

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><body><!-- Vue开发环境版本,包含了有帮助的命令行警告 --><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><!-- 引入element样式element --><link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"><!-- 引入element组件库 --><script src="https://unpkg.com/element-ui/lib/index.js"></script><!-- 引入axios --><script src="https://unpkg.com/axios/dist/axios.min.js"></script><div id="app"><h2>文件上传</h2><el-uploadclass="upload-demo"dragaction="http://localhost:8080/upload"multiple:file-list="fileList":on-success="handleSucess":before-upload="beforeAvatarUpload"><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div><div class="el-upload__tip" slot="tip">只能上传jpg/png/txt/pdf/excel文件,且不超过2MB</div></el-upload><h2>文件下载</h2><p>模拟下载,假设下面是某个文件列表</p><div @click="downFile"><i class="el-icon-document"></i>娱乐圈不为人知的秘密.pdf</div></div><script>new Vue({el: "#app",data() {return {fileList: [],fileinfo:{virtualPath: ""}}},methods: {beforeAvatarUpload(file) {//alert(file.type)const isJPG = file.type === 'image/jpeg';const isPNG = file.type === 'image/png';const isPDF = file.type === 'application/pdf';const isXLSX = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';const isXLS = file.type === 'application/vnd.ms-excel'                    const isLt2M = file.size / 1024 / 1024 < 2;         if (!isJPG && !isPNG && !isPDF && isXLSX && isXLS) {this.$message.error('上传文件格式只能是 JPG PNG TXT PDF XLS XLSX格式!');}if (!isLt2M) {sthis.$message.error('上传头像图片大小不能超过 2MB!');}return (isJPG || isPNG || isPDF || isXLSX || isXLS) && isLt2M;},handleSucess(result) {alert("上传成功")console.log("存储路径:"+result.virtualPath)console.log("文件名:"+result.fileName)this.fileinfo.virtualPath=result.virtualPath},downFile(){alert("开始下载")//动态获取刚刚上传的文件的路径,所以必须先上传,再下载,当然你也可以把路径写死//实际项目中,获取目标文件路径即可,这个不是重点console.log(this.fileinfo.virtualPath)var url = "http://localhost:8080/downloadFile?filePath="+this.fileinfo.virtualPath//这里直接使用window.open 发起请求在新页面显示返回的内容,也可以使用axios,这样比较简单,效果类似window.open(url)}}})</script></body>
</html>

后台项目搭建

创建项目

采用阿里云脚手架创建SpringBoot项目: https://start.aliyun.com


勾选web和lombok依赖,也可以创建项目后手动添加

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

创建配置文件 image.properties

此配置文件配置上传文件的地址路径,你要想写死我也不拦你
在resource下,新建properties目录
在resource/properties目录下创建image.properties

#配置windows服务器路径
image.localPathDir=D:/files
#配置Linux服务器路径 我这是Mac系统 在业务中选择下面这个地址
image.localUrlPath=/Users/zhaoguoxing/Desktop/files

application.yml配置文件

springboot配置文件,只配个端口号即可

# 应用服务 WEB 访问端口
server:port: 8080

上传文件实现

实体类

在com.gx.vo下 创建FileVO
用于封装 文件路径以及文件名,返回给前端
我业务逻辑中没用到文件名,后期可扩展
使用lombok插件 帮我们自动生成构造方法和 get set方法

package com.gx.vo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class FileVO {private String virtualPath; //动态变化的路径private String fileName;    //文件名称  uuid.pdf
}

控制层

在com.gx.controller下创建FileController用于接收请求

package com.gx.controller;import com.gx.service.FileService;
import com.gx.vo.FileVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;@RestController
@CrossOrigin
public class FileController {@AutowiredFileService fileService;@PostMapping("/upload")public FileVO upload(MultipartFile file) throws IOException {System.out.println("upload--file is"+file);//调用service中的业务方法FileVO fileVO = fileService.upload(file);return fileVO;}
}

业务层

在com.gx.service下创建FileService以及FileServiceImpl

FileService

package com.gx.service;import com.gx.vo.FileVO;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.OutputStream;public interface FileService {//文件上传public FileVO upload(MultipartFile file) throws IOException;
}

FileServiceImpl
思路: 获取文件 重新定义文件名 以及文件存储路径 将文件保存到目录
这里没有连接数据库,我们可以将图片存储的地址实际放到数据库中存储

package com.gx.service;import com.gx.vo.FileVO;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;@Service
//加载指定的配置文件
@PropertySource("classpath:/properties/image.properties")
public class FileServiceImpl implements FileService{//获取配置文件中的配置 为属性动态赋值 注解@Value@Value("${image.localPathDir}")private String localPathDir;  // Windows路径 例如 D:/files@Value("${image.localUrlPath}")private String localUrlPath;  // Linux路径 例如 /Users/zhaoguoxing/Desktop/files@Overridepublic FileVO upload(MultipartFile file) throws IOException {//1.1 获取文件名称String fileName = file.getOriginalFilename();//2. 目录结构//2.1 实现分目录存储  可以以时间维度年月日进行分隔 /yyyy/MM/dd/String datePath =new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());//2.2 最终本地图片存储路径//    进行目录的拼接  "/Users/zhaoguoxing/Desktop/files/2022/03/22";String localDir = localUrlPath + datePath;//2.3 需要创建目录File dirFile = new File(localDir);if(!dirFile.exists()){dirFile.mkdirs();}//3.文件名称重复  采用UUID防止文件重名 uuid.pdfString uuid = UUID.randomUUID().toString().replace("-", "");//3.1.获取文件类型//fileName = abc.jpg  fileType=.pdfString fileType =fileName.substring(fileName.lastIndexOf("."));//3.2.重新拼接文件名  uuid.pdfString realFileName = uuid + fileType;//4.最终文件存储的路径+文件名 = /2021/11/11/uuid.pdf//可以在这里将路径存储到数据库 实际保存文件地址 此处省略String filePathAll = localDir + realFileName;//5.实现文件上传File realFile = new File(filePathAll);file.transferTo(realFile);//6.封装FileVO对象  //2021/11/11/uuid.pdf 图片路径 稍后给前台传递//我们不可能将filePathAll告诉用户,这样不安全,容易被攻击//virtualPath 半个路径,没有具体盘符或根目录 /2021/11/11/uuid.pdfString virtualPath = datePath + realFileName;//7.将文件存储路径(半个路径,没有具体盘符或根目录) 和 重命名后的文件名 封装到实体类中return new FileVO(virtualPath,realFileName);}
}

效果

前台可以拖拽或者点击选择文件上传
前端显示已上传文件历史,并在控制台输出了文件路径
这个路径肯定不能给用户返回实际带根目录的路径,不安全
根目录我们在后台动态拼接即可

实际存储到目录中

下载文件实现

控制层

在FileController中添加方法接收下载请求

@GetMapping("/downloadFile")public Object downloadFile(HttpServletResponse response,String filePath) throws IOException {// 清空输出流response.reset();response.setContentType("application/x-download;charset=UTF-8");response.setHeader("Content-Disposition", "attachment;filename="+ new String(filePath.getBytes("utf-8"), "utf-8"));fileService.download(response.getOutputStream(),filePath);return null;}

业务层

在FileService和FileServiceImpl中添加下载方法

FileService

public Object download(OutputStream os,String filePath) throws IOException;

FileServiceImpl

@Overridepublic Object download(OutputStream os, String filePath) throws IOException {//下载文件的路径String downPath = localUrlPath+filePath;//读取目标文件File f = new File(downPath);//创建输入流InputStream is = new FileInputStream(f);//做一些业务判断,我这里简单点直接输出,你也可以封装到实体类返回具体信息if (is == null) {System.out.println("文件不存在");}//利用IOUtils将输入流的内容 复制到输出流//org.apache.tomcat.util.http.fileupload.IOUtils//项目搭建是自动集成了这个类 直接使用即可IOUtils.copy(is, os);os.flush();is.close();os.close();return null;}

效果

点击娱乐圈不为人知的秘密.pdf开始下载 最后一次上传的文件
注意:
因为下载业务没有数据支持,我代码里下载文件设置的是上一次上传文件的路径,来演示效果,实际业务中,获取目标文件件路径即可

gitee代码仓库地址

https://gitee.com/memoryzgx/file-upload.git

欢迎转发,收藏,点赞
欢迎转发,收藏,点赞
欢迎转发,收藏,点赞

SpringBoot+Vue+ElementUI实现文件上传与文件下载相关推荐

  1. SpringBoot+Vue表单文件上传

    版权声明:本文首发 http://asing1elife.com ,转载请注明出处. https://blog.csdn.net/asing1elife/article/details/8281181 ...

  2. 【SpringBoot】简单的文件上传和文件下载以及图片回显

    介绍 这里是小编成长之路的历程,也是小编的学习之路.希望和各位大佬们一起成长! 以下为小编最喜欢的两句话: 要有最朴素的生活和最遥远的梦想,即使明天天寒地冻,山高水远,路远马亡. 一个人为什么要努力? ...

  3. 文件上传 java 完美,vue+java实现文件上传(excel等),会出现跨域问题,直接用form表单提交就不会有问题了(new FormData())...

    vue+java实现文件上传(excel等),会出现跨域问题,直接用form表单提交就不会有问题了(new FormData()) 地址:https://www.cnblogs.com/muscles ...

  4. vue上传zip文件到服务器,vue.js zip文件上传

    vue.js zip文件上传 内容精选 换一换 开发过程中,您有任何问题可以在github上提交issue,或者在华为云对象存储服务论坛中发帖求助.接口参考文档详细介绍了每个接口的参数和使用方法.在O ...

  5. vue自定义组件-文件上传后端接口

    学习目标: vue自定义组件-文件上传后端接口 学习内容: 准备工作: 后端环境:JAVA-Springboot项目数据库表(这里使用psql数据库):sys_file_record保存上传文件的信息 ...

  6. vue采用 XLSX文件上传与下载

    vue采用 XLSX文件上传与下载 先安装xlsx npm install xlsx 安装之后直接在该页面script标签里面导入 import * as XLSX from 'xlsx' 注意 此处 ...

  7. struts2的文件上传和文件下载

    实现使用Struts2文件上传和文件下载: 注意点: (1)对应表单的file1和私有成员变量的名称必须一致 <input type="file" name="fi ...

  8. hadoop HDFS的文件夹创建、文件上传、文件下载、文件夹删除,文件更名、文件详细信息、文件类型判断(文件夹或者文件)

    摘要: 本篇文章主要介绍的是hadoop hdfs的基础api的使用.包括Windows端依赖配置,Maven依赖配置.最后就是进行实际的操作,包括:获取远程hadoop hdfs连接,并对其进行的一 ...

  9. 基于OkHttp 、Retrofit 、Volley 、RxJava、Novate多种网络框架整合的快速项目开发框架,一行代码实现Ftp文件上传、文件下载、文件删除和进度监听的工具类的使用

    基于OkHttp .Retrofit .Volley .RxJava.Novate多种网络框架整合的快速项目开发框架,Ftp文件上传.文件下载的工具类的使用. 依赖于Ftp的jar包,对上传.下载.删 ...

最新文章

  1. numpy使用[]语法索引二维numpy数组中指定指定行之前所有数据行的数值内容(accessing rows in numpy array before specifc row)
  2. 中国新冠统计20200128-20200227 统计于网络发布数据 便于数据同比分析规律 公开透明 加强防范 减少恐慌 数学来加持
  3. php 位运算与权限,PHP巧妙利用位运算实现网站权限管理的方法
  4. python之初接触
  5. Java Stub 研究学习(2)
  6. 用自己的数据集在R-FCN框架下进行检测
  7. 系统学习Linux11点建议
  8. AngularJS select中ngOptions用法详解
  9. 【转】java中定义二维数组的几种写法
  10. AndroidStudio_安卓原生开发_自定义单选列表Spinner绑定自定义数据类型---Android原生开发工作笔记143
  11. c语言查找字符串中字母 数字的个数,请问这个用c怎么做:输入一串字符,分别统计其中数字和字母的个数...
  12. MPFlipViewController
  13. eclipse上新建Maven项目报错及解决
  14. 神经网络与深度学习第5章:卷积神经网络 阅读提问
  15. 简单个人网页设计作业 静态HTML个人博客主页 DW个人网站模板下载 大学生简单个人网页作品代码 个人网页制作 学生个人网页设计作业
  16. 【电商数仓】数仓即席查询之Kylin简介,安装和使用
  17. macOS如何格式化移动硬盘和U盘
  18. ISC技术分享:从RASP开启云上应用安全防护
  19. word怎么恢复默认样式
  20. 别再恐惧 IP 协议(万字长文 | 多图预警)

热门文章

  1. 2021全球数字经济白皮书 附下载
  2. W5500 ARM mbed 库发布
  3. 【python爬虫】Python爬取+PR绘制你出生那日的星图
  4. 【深度思考】快来看看这些方案,附答案
  5. AXI Ordering Model
  6. 通过一上午资料分析得出“裸身”跳楼高二女生可能是精神问题,非他杀
  7. C语言之初学者能够玩明白的函数(很重要)
  8. 三年Android开发快手、美团、支付宝连挂,android基础视频教程
  9. 小米Pro14 2021款和联想小新Air14Plus选哪个
  10. 字符串包含(指针)(C语言实现)