SpringBoot3文件管理

标签:上传.下载.Excel.导入.导出;

一、简介

在项目中,文件管理是常见的复杂功能;

首先文件的类型比较多样,处理起来比较复杂,其次文件涉及大量的IO操作,容易引发内存溢出;

不同的文件类型有不同的应用场景;

比如:图片常用于头像和证明材料;Excel偏向业务数据导入导出;CSV偏向技术层面数据搬运;PDF和Word用于文档类的材料保存等;

下面的案例只围绕普通文件Excel两种类型进行代码实现;

二、工程搭建

1、工程结构

SpringBoot3文件管理

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测试文件批量上传接口:

SpringBoot3文件管理

四、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 ; } 

文件效果:

SpringBoot3文件管理

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上传接口:

SpringBoot3文件管理

五、参考源码

文档仓库: https://gitee.com/cicadasmile/butte-java-note  源码仓库: https://gitee.com/cicadasmile/butte-spring-parent 

发表评论

评论已关闭。

相关文章