经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
SpringBoot3文件管理
来源:cnblogs  作者:知了一笑  时间:2023/8/11 8:38:05  对本文有异议

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

一、简介

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

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

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

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

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

二、工程搭建

1、工程结构

2、依赖管理

普通文件的上传下载,依赖spring-boot框架即可,而Excel类型选择easyexcel组件,该组件内部依赖了apache-poi组件的4.1.2版本;

  1. <!-- 基础框架组件 -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. <version>${spring-boot.version}</version>
  6. </dependency>
  7. <!-- Excel组件 -->
  8. <dependency>
  9. <groupId>com.alibaba</groupId>
  10. <artifactId>easyexcel</artifactId>
  11. <version>${easyexcel.version}</version>
  12. <exclusions>
  13. <exclusion>
  14. <groupId>org.slf4j</groupId>
  15. <artifactId>slf4j-api</artifactId>
  16. </exclusion>
  17. </exclusions>
  18. </dependency>

三、上传下载

1、配置管理

在配置文件中,添加max-file-size单个文件大小限制和max-request-size请求最大限制两个核心参数;

需要说明的一点是:如何设定参数值的大小,与业务场景和服务器的处理能力都有关系,在测试的过程中优化即可;

  1. spring:
  2. # 文件配置
  3. servlet:
  4. multipart:
  5. enabled: true
  6. # 文件单个限制
  7. max-file-size: 10MB
  8. # 请求最大限制
  9. max-request-size: 20MB

2、上传下载

这里提供一个文件批量上传接口和一个文件下载接口,把文件管理在工程中的resources/file目录下,下载接口中需要指定该目录下的文件名称;

  1. @RestController
  2. public class FileWeb {
  3. private static final Logger logger = LoggerFactory.getLogger(FileWeb.class);
  4. @Resource
  5. private FileService fileService ;
  6. /**
  7. * 文件上传
  8. */
  9. @PostMapping("/file/upload")
  10. public String upload (HttpServletRequest request,
  11. @RequestParam("file") MultipartFile[] fileList) throws Exception {
  12. String uploadUser = request.getParameter("uploadUser");
  13. if (uploadUser.isEmpty()){
  14. return "upload-user is empty";
  15. }
  16. logger.info("upload-user:{}",uploadUser);
  17. for (MultipartFile multipartFile : fileList) {
  18. // 解析文件信息和保存
  19. fileService.dealFile(multipartFile);
  20. }
  21. return "success" ;
  22. }
  23. /**
  24. * 文件下载
  25. */
  26. @GetMapping("/file/download")
  27. public void upload (@RequestParam("fileName") String fileName,
  28. HttpServletResponse response) throws Exception {
  29. if (!fileName.isBlank()){
  30. String filePath = ResourceUtils.getURL("m1-04-boot-file/src/main/resources/file").getPath();
  31. File file = new File(filePath,fileName) ;
  32. response.setHeader("Content-Disposition",
  33. "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
  34. response.setContentType("application/octet-stream");
  35. Files.copy(Paths.get(file.getPath()), response.getOutputStream());
  36. }
  37. }
  38. }
  39. /**
  40. * 文件服务类
  41. */
  42. @Service
  43. public class FileService {
  44. private static final Logger logger = LoggerFactory.getLogger(FileService.class);
  45. public void dealFile (MultipartFile multipartFile) throws Exception {
  46. logger.info("Name >> {}",multipartFile.getName());
  47. logger.info("OriginalFilename >> {}",multipartFile.getOriginalFilename());
  48. logger.info("ContentType >> {}",multipartFile.getContentType());
  49. logger.info("Size >> {}",multipartFile.getSize());
  50. // 文件输出地址
  51. String filePath = ResourceUtils.getURL("m1-04-boot-file/src/main/resources/file").getPath();
  52. File writeFile = new File(filePath, multipartFile.getOriginalFilename());
  53. multipartFile.transferTo(writeFile);
  54. }
  55. }

使用Postman测试文件批量上传接口:

四、Excel文件

1、Excel创建

基于easyexcel组件中封装的EasyExcel工具类,继承自EasyExcelFactory工厂类,实现Excel单个或多个Sheet的创建,并且在单个Sheet中写多个Table数据表;

  1. @Service
  2. public class ExcelService {
  3. /**
  4. * Excel-写单个Sheet
  5. */
  6. public static void writeSheet () throws Exception {
  7. // 文件处理
  8. String basePath = getAbsolutePath();
  9. File file = new File(basePath+"/easy-excel-01.xlsx") ;
  10. checkOrCreateFile(file);
  11. // 执行写操作
  12. EasyExcel.write(file).head(DataVO.class)
  13. .sheet(0,"用户信息").doWrite(DataVO.getSheet1List());
  14. }
  15. /**
  16. * Excel-写多个Sheet
  17. */
  18. public static void writeSheets () throws Exception {
  19. // 文件处理
  20. String basePath = getAbsolutePath();
  21. File file = new File(basePath+"/easy-excel-02.xlsx") ;
  22. checkOrCreateFile(file);
  23. ExcelWriter excelWriter = null;
  24. try {
  25. excelWriter = EasyExcel.write(file).build();
  26. // Excel-Sheet1
  27. WriteSheet writeSheet1 = EasyExcel.writerSheet(0,"分页1").head(DataVO.class).build();
  28. // Excel-Sheet2
  29. WriteSheet writeSheet2 = EasyExcel.writerSheet(1,"分页2").head(DataVO.class).build();
  30. // Excel-Sheet3,写两个Table
  31. WriteSheet writeSheet3 = EasyExcel.writerSheet(2,"分页3").build();
  32. WriteTable dataTable = EasyExcel.writerTable(0).head(DataVO.class).build();
  33. WriteTable dataExtTable = EasyExcel.writerTable(1).head(DataExtVO.class).build();
  34. // 执行写操作
  35. excelWriter.write(DataVO.getSheet1List(), writeSheet1);
  36. excelWriter.write(DataVO.getSheet2List(), writeSheet2);
  37. excelWriter.write(DataVO.getSheet1List(),writeSheet3,dataTable) ;
  38. excelWriter.write(DataExtVO.getSheetList(),writeSheet3,dataExtTable) ;
  39. } catch (Exception e){
  40. e.printStackTrace();
  41. } finally {
  42. if (excelWriter != null){
  43. excelWriter.close();
  44. }
  45. }
  46. }
  47. }
  48. /**
  49. * 实体类,这里的注解会解析为Excel中的表头
  50. */
  51. public class DataVO {
  52. @ExcelProperty("编号")
  53. private Integer id ;
  54. @ExcelProperty("名称")
  55. private String name ;
  56. @ExcelProperty("手机号")
  57. private String phone ;
  58. @ExcelProperty("城市")
  59. private String cityName ;
  60. @ExcelProperty("日期")
  61. private Date date ;
  62. }

文件效果:

2、Excel读取

对于读取Excel文件来说,则需要根据具体的样式来定了,在easyexcel组件中还可以添加读取过程的监听器;

  1. @Service
  2. public class ExcelService {
  3. /**
  4. * Excel-读取数据
  5. */
  6. public static void readExcel () throws Exception {
  7. // 文件处理
  8. String basePath = getAbsolutePath();
  9. File file = new File(basePath+"/easy-excel-01.xlsx") ;
  10. if (!file.exists()){
  11. return ;
  12. }
  13. // 读取数据
  14. List<DataVO> dataList = EasyExcel.read(file).head(DataVO.class)
  15. .sheet(0).headRowNumber(1).doReadSync();
  16. dataList.forEach(System.out::println);
  17. }
  18. /**
  19. * Excel-读取数据使用解析监听器
  20. */
  21. public static void readExcelListener () throws Exception {
  22. // 文件处理
  23. String basePath = getAbsolutePath();
  24. File file = new File(basePath+"/easy-excel-01.xlsx") ;
  25. if (!file.exists()){
  26. return ;
  27. }
  28. // 读取数据,并且使用解析监听器
  29. DataListener dataListener = new DataListener() ;
  30. List<DataVO> dataSheetList = EasyExcel.read(file,dataListener).head(DataVO.class)
  31. .sheet(0).headRowNumber(1).doReadSync();
  32. dataSheetList.forEach(System.out::println);
  33. }
  34. }

3、解析监听

继承AnalysisEventListener类,并重写其中的方法,可以监听Excel的解析过程,或者添加一些自定义的处理逻辑;

  1. public class DataListener extends AnalysisEventListener<DataVO> {
  2. /**
  3. * 接收解析的数据块
  4. */
  5. @Override
  6. public void invoke(DataVO data, AnalysisContext context) {
  7. System.out.println("DataListener:"+data);
  8. }
  9. /**
  10. * 接收解析的表头
  11. */
  12. @Override
  13. public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
  14. System.out.println("DataListener:"+headMap);
  15. }
  16. @Override
  17. public void doAfterAllAnalysed(AnalysisContext context) {
  18. System.out.println("DataListener:after...all...analysed");
  19. }
  20. }

4、导入导出

实际上Excel文件的导入导出,原理与文件的上传下载类似,只不过这里使用easyexcel组件中的API来直接处理Excel的写和读;

  1. @RestController
  2. public class ExcelWeb {
  3. @GetMapping("excel/download")
  4. public void download(HttpServletResponse response) throws IOException {
  5. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  6. response.setCharacterEncoding("utf-8");
  7. String fileName = URLEncoder.encode("Excel数据", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
  8. response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
  9. EasyExcel.write(response.getOutputStream(), DataVO.class).sheet("用户").doWrite(DataVO.getSheet1List());
  10. }
  11. @ResponseBody
  12. @PostMapping("excel/upload")
  13. public String upload(@RequestParam("file") MultipartFile file) throws IOException {
  14. List<DataVO> dataList = EasyExcel
  15. .read(file.getInputStream(), DataVO.class, new DataListener()).sheet().doReadSync();
  16. dataList.forEach(System.out::println);
  17. return "success";
  18. }
  19. }

使用Postman测试单个Excel上传接口:

五、参考源码

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

原文链接:https://www.cnblogs.com/cicada-smile/p/17619352.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号