SpringBoot3文件管理
标签:上传.下载.Excel.导入.导出;
一、简介
在项目中,文件管理是常见的复杂功能;
首先文件的类型比较多样,处理起来比较复杂,其次文件涉及大量的IO操作,容易引发内存溢出;
不同的文件类型有不同的应用场景;
比如:图片常用于头像和证明材料;Excel偏向业务数据导入导出;CSV偏向技术层面数据搬运;PDF和Word用于文档类的材料保存等;
下面的案例只围绕普通文件和Excel两种类型进行代码实现;
二、工程搭建
1、工程结构

2、依赖管理
普通文件的上传下载,依赖spring-boot框架即可,而Excel类型选择easyexcel组件,该组件内部依赖了apache-poi组件的4.1.2版本;
<!-- 基础框架组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- Excel组件 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${easyexcel.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
三、上传下载
1、配置管理
在配置文件中,添加max-file-size单个文件大小限制和max-request-size请求最大限制两个核心参数;
需要说明的一点是:如何设定参数值的大小,与业务场景和服务器的处理能力都有关系,在测试的过程中优化即可;
spring:
# 文件配置
servlet:
multipart:
enabled: true
# 文件单个限制
max-file-size: 10MB
# 请求最大限制
max-request-size: 20MB
2、上传下载
这里提供一个文件批量上传接口和一个文件下载接口,把文件管理在工程中的resources/file目录下,下载接口中需要指定该目录下的文件名称;
@RestController
public class FileWeb {
private static final Logger logger = LoggerFactory.getLogger(FileWeb.class);
@Resource
private FileService fileService ;
/**
* 文件上传
*/
@PostMapping("/file/upload")
public String upload (HttpServletRequest request,
@RequestParam("file") MultipartFile[] fileList) throws Exception {
String uploadUser = request.getParameter("uploadUser");
if (uploadUser.isEmpty()){
return "upload-user is empty";
}
logger.info("upload-user:{}",uploadUser);
for (MultipartFile multipartFile : fileList) {
// 解析文件信息和保存
fileService.dealFile(multipartFile);
}
return "success" ;
}
/**
* 文件下载
*/
@GetMapping("/file/download")
public void upload (@RequestParam("fileName") String fileName,
HttpServletResponse response) throws Exception {
if (!fileName.isBlank()){
String filePath = ResourceUtils.getURL("m1-04-boot-file/src/main/resources/file").getPath();
File file = new File(filePath,fileName) ;
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
response.setContentType("application/octet-stream");
Files.copy(Paths.get(file.getPath()), response.getOutputStream());
}
}
}
/**
* 文件服务类
*/
@Service
public class FileService {
private static final Logger logger = LoggerFactory.getLogger(FileService.class);
public void dealFile (MultipartFile multipartFile) throws Exception {
logger.info("Name >> {}",multipartFile.getName());
logger.info("OriginalFilename >> {}",multipartFile.getOriginalFilename());
logger.info("ContentType >> {}",multipartFile.getContentType());
logger.info("Size >> {}",multipartFile.getSize());
// 文件输出地址
String filePath = ResourceUtils.getURL("m1-04-boot-file/src/main/resources/file").getPath();
File writeFile = new File(filePath, multipartFile.getOriginalFilename());
multipartFile.transferTo(writeFile);
}
}
使用Postman测试文件批量上传接口:

四、Excel文件
1、Excel创建
基于easyexcel组件中封装的EasyExcel工具类,继承自EasyExcelFactory工厂类,实现Excel单个或多个Sheet的创建,并且在单个Sheet中写多个Table数据表;
@Service
public class ExcelService {
/**
* Excel-写单个Sheet
*/
public static void writeSheet () throws Exception {
// 文件处理
String basePath = getAbsolutePath();
File file = new File(basePath+"/easy-excel-01.xlsx") ;
checkOrCreateFile(file);
// 执行写操作
EasyExcel.write(file).head(DataVO.class)
.sheet(0,"用户信息").doWrite(DataVO.getSheet1List());
}
/**
* Excel-写多个Sheet
*/
public static void writeSheets () throws Exception {
// 文件处理
String basePath = getAbsolutePath();
File file = new File(basePath+"/easy-excel-02.xlsx") ;
checkOrCreateFile(file);
ExcelWriter excelWriter = null;
try {
excelWriter = EasyExcel.write(file).build();
// Excel-Sheet1
WriteSheet writeSheet1 = EasyExcel.writerSheet(0,"分页1").head(DataVO.class).build();
// Excel-Sheet2
WriteSheet writeSheet2 = EasyExcel.writerSheet(1,"分页2").head(DataVO.class).build();
// Excel-Sheet3,写两个Table
WriteSheet writeSheet3 = EasyExcel.writerSheet(2,"分页3").build();
WriteTable dataTable = EasyExcel.writerTable(0).head(DataVO.class).build();
WriteTable dataExtTable = EasyExcel.writerTable(1).head(DataExtVO.class).build();
// 执行写操作
excelWriter.write(DataVO.getSheet1List(), writeSheet1);
excelWriter.write(DataVO.getSheet2List(), writeSheet2);
excelWriter.write(DataVO.getSheet1List(),writeSheet3,dataTable) ;
excelWriter.write(DataExtVO.getSheetList(),writeSheet3,dataExtTable) ;
} catch (Exception e){
e.printStackTrace();
} finally {
if (excelWriter != null){
excelWriter.close();
}
}
}
}
/**
* 实体类,这里的注解会解析为Excel中的表头
*/
public class DataVO {
@ExcelProperty("编号")
private Integer id ;
@ExcelProperty("名称")
private String name ;
@ExcelProperty("手机号")
private String phone ;
@ExcelProperty("城市")
private String cityName ;
@ExcelProperty("日期")
private Date date ;
}
文件效果:

2、Excel读取
对于读取Excel文件来说,则需要根据具体的样式来定了,在easyexcel组件中还可以添加读取过程的监听器;
@Service
public class ExcelService {
/**
* Excel-读取数据
*/
public static void readExcel () throws Exception {
// 文件处理
String basePath = getAbsolutePath();
File file = new File(basePath+"/easy-excel-01.xlsx") ;
if (!file.exists()){
return ;
}
// 读取数据
List<DataVO> dataList = EasyExcel.read(file).head(DataVO.class)
.sheet(0).headRowNumber(1).doReadSync();
dataList.forEach(System.out::println);
}
/**
* Excel-读取数据使用解析监听器
*/
public static void readExcelListener () throws Exception {
// 文件处理
String basePath = getAbsolutePath();
File file = new File(basePath+"/easy-excel-01.xlsx") ;
if (!file.exists()){
return ;
}
// 读取数据,并且使用解析监听器
DataListener dataListener = new DataListener() ;
List<DataVO> dataSheetList = EasyExcel.read(file,dataListener).head(DataVO.class)
.sheet(0).headRowNumber(1).doReadSync();
dataSheetList.forEach(System.out::println);
}
}
3、解析监听
继承AnalysisEventListener类,并重写其中的方法,可以监听Excel的解析过程,或者添加一些自定义的处理逻辑;
public class DataListener extends AnalysisEventListener<DataVO> {
/**
* 接收解析的数据块
*/
@Override
public void invoke(DataVO data, AnalysisContext context) {
System.out.println("DataListener:"+data);
}
/**
* 接收解析的表头
*/
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
System.out.println("DataListener:"+headMap);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("DataListener:after...all...analysed");
}
}
4、导入导出
实际上Excel文件的导入导出,原理与文件的上传下载类似,只不过这里使用easyexcel组件中的API来直接处理Excel的写和读;
@RestController
public class ExcelWeb {
@GetMapping("excel/download")
public void download(HttpServletResponse response) throws IOException {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("Excel数据", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), DataVO.class).sheet("用户").doWrite(DataVO.getSheet1List());
}
@ResponseBody
@PostMapping("excel/upload")
public String upload(@RequestParam("file") MultipartFile file) throws IOException {
List<DataVO> dataList = EasyExcel
.read(file.getInputStream(), DataVO.class, new DataListener()).sheet().doReadSync();
dataList.forEach(System.out::println);
return "success";
}
}
使用Postman测试单个Excel上传接口:

五、参考源码
文档仓库:
https://gitee.com/cicadasmile/butte-java-note
源码仓库:
https://gitee.com/cicadasmile/butte-spring-parent
SpringBoot3文件管理的更多相关文章
- Linux安装LAMP开发环境及配置文件管理
Linux主要分为两大系发行版,分别是RedHat和Debian,lamp环境的安装和配置也会有所不同,所以分别以CentOS 7.1和Ubuntu 14.04做为主机(L) Linux下安装软件,最 ...
- java springMVC SSM 操作日志 4级别联动 文件管理 头像编辑 shiro redis
A 调用摄像头拍照,自定义裁剪编辑头像 B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单; 技术:313596790freemaker模版技术 ,0个代码不用写 ...
- BPM体系文件管理解决方案分享
一.方案概述 企业管理在很大程度上是通过文件化的形式表现出来,体系文件管理是管理体系存在的基础和证据,是规范企业管理活动和全体人员行为,达到管理目标的管理依据.对与公司质量.环境.职业健康安全等体系有 ...
- 简单的学习心得:网易云课堂Android开发第五章SharedPreferences与文件管理
一.SharedPreferences (1)SharedPreferences能够用来保存一些属于基本数据类型的数据. (2)保存数据,删除数据都是由SharedPreferences的内部接口Ed ...
- 归档NSKeyedArchiver解归档NSKeyedUnarchiver与文件管理类NSFileManager (文件操作)
========================== 文件操作 ========================== 一.归档NSKeyedArchiver 1.第一种方式:存储一种数据. // 归档 ...
- BZOJ 3289: Mato的文件管理[莫队算法 树状数组]
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 2399 Solved: 988[Submit][Status][Di ...
- linux 基础命令与文件管理
Linux终端介绍 Shell提示符 Bash Shell基本语法 基本命令的使用:ls.pwd.cd 查看系统和BIOS硬件时间 Linux如何获得帮助 Linux关机命令:shutdow.in ...
- 文件管理[Linux]
文件系统 rootfs: 根文件系统 /boot 系统启动相关的文件,如内核.initrd.以及grub(bootloader) /dev 设备文件 块设备 随机访问 字符设备 线性访问 设备号 主设 ...
- iOS路径沙盒文件管理(转载)
iOS路径沙盒文件管理,看到博主总结的很好,转载过来,原文:http://www.aichengxu.com/view/35264 一.iOS中的沙盒机制 iOS应用程序只能对自己创建的文件系统读取文 ...
- 3-1 Linux文件管理类命令详解
根据马哥Linux初级 03-01整理 1. 目录管理 ls cd pwd mkdir rmdir tree 2. 文件管理 touch stat file rm cp mv nano 3. 日期时间 ...
随机推荐
- 用go设计开发一个自己的轻量级登录库/框架吧(业务篇)
用go设计开发一个自己的轻量级登录库/框架吧(业务篇) 本篇会讲讲框架的登录业务的实现.实现三种登录模式: 同一用户只能登录一次 同一用户多次登录多token 同一用户多次登录共享一个token 源码 ...
- Windows server 2012 r2 激活方法
slmgr /ipk W3GGN-FT8W3-Y4M27-J84CP-Q3VJ9 slmgr /skms kms.03k.org slmgr /ato
- 时间函数strftime和strptime的差别
strftime是转换为特定格式输出, strptime是将一个时间字符串解析为时间类型对象. strftime是按照想要的格式,去转换.重点是格式! strptime不管什么格式,只要把特定的时间字 ...
- C++实现查询本机信息并且上报
业务需求 共享文件夹.盘会导致系统安全性下降,故IT部门需要搜集公司中每台电脑的共享情况,并且进行上报 关键字 WMI查询.Get请求.C++网络库mongoose 前置需要 1.简单C++语法知识2 ...
- L3-017 森森快递
一.题目: 7-2 森森快递 (30 分) 森森开了一家快递公司,叫森森快递.因为公司刚刚开张,所以业务路线很简单,可以认为是一条直线上的N个城市,这些城市从左到右依次从0到(N−1)编号.由于道路限 ...
- 【HarmonyOS】元服务和APP的相互跳转、相互成就
[关键字] 卡片.跳转.加桌 [背景介绍] 随着鸿蒙生态的发展,各种类型的应用都已经可以在Harmony OS上无差异的运行,面对鸿蒙新兴元服务的兴起,各大厂家可能都在考虑一个问题:如果已经有AP ...
- docker desktop 与 wmware tv-x
开启WSL2,获得docker desktop的最佳性能 windows默认拥有WSL1 PS C:\Users\supermao> wsl --list --verbose NAME STAT ...
- STL-deque(ACM)
1.两段都可以插入和删除(头 插入删除 尾 插入删除) 普通队列无法用pop_back()删除队列最后的元素,类似地,由于普通队列只能插入头删除,所以push().pop()无需带_front()._ ...
- DosBox环境配置
DosBox环境配置 DOSBox 是一个基于 x86 架构的 PC 的模拟器,它允许用户在现代操作系统上运行 DOS 程序.DOSBox 是自由软件,可以在 Windows.Linux ,macOS ...
- 推送服务接入指导(HarmonyOS篇)
消息推送作为App运营日常使用的用户促活和召回手段,是与用户建立持续互动和连接的良好方式.推送服务(Push Kit)是华为提供的消息推送平台,建立了从云端到终端的消息推送通道,本文旨在介绍Harmo ...