SpringBoot3文件管理操作方法
一、簡介
在項(xiàng)目中,文件管理是常見的復(fù)雜功能;
首先文件的類型比較多樣,處理起來比較復(fù)雜,其次文件涉及大量的IO操作,容易引發(fā)內(nèi)存溢出;
不同的文件類型有不同的應(yīng)用場景;
比如:圖片常用于頭像和證明材料;Excel偏向業(yè)務(wù)數(shù)據(jù)導(dǎo)入導(dǎo)出;CSV偏向技術(shù)層面數(shù)據(jù)搬運(yùn);PDF和Word用于文檔類的材料保存等;
下面的案例只圍繞普通文件和Excel兩種類型進(jìn)行代碼實(shí)現(xiàn);
二、工程搭建
1、工程結(jié)構(gòu)
2、依賴管理
普通文件的上傳下載,依賴 spring-boot
框架即可,而Excel類型選擇 easyexcel
組件,該組件內(nèi)部依賴了 apache-poi
組件的 4.1.2
版本;
<!-- 基礎(chǔ)框架組件 --> <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
單個(gè)文件大小限制和 max-request-size
請(qǐng)求最大限制兩個(gè)核心參數(shù);
需要說明的一點(diǎn)是:如何設(shè)定參數(shù)值的大小,與業(yè)務(wù)場景和服務(wù)器的處理能力都有關(guān)系,在測(cè)試的過程中優(yōu)化即可;
spring: # 文件配置 servlet: multipart: enabled: true # 文件單個(gè)限制 max-file-size: 10MB # 請(qǐng)求最大限制 max-request-size: 20MB
2、上傳下載
這里提供一個(gè)文件批量上傳接口和一個(gè)文件下載接口,把文件管理在工程中的 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()); } } } /** * 文件服務(wù)類 */ @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測(cè)試文件批量上傳接口:
四、Excel文件
1、Excel創(chuàng)建
基于 easyexcel
組件中封裝的 EasyExcel
工具類,繼承自 EasyExcelFactory
工廠類,實(shí)現(xiàn)Excel單個(gè)或多個(gè) Sheet
的創(chuàng)建,并且在單個(gè) Sheet
中寫多個(gè) Table
數(shù)據(jù)表;
@Service public class ExcelService { /** * Excel-寫單個(gè)Sheet */ public static void writeSheet () throws Exception { // 文件處理 String basePath = getAbsolutePath(); File file = new File(basePath+"/easy-excel-01.xlsx") ; checkOrCreateFile(file); // 執(zhí)行寫操作 EasyExcel.write(file).head(DataVO.class) .sheet(0,"用戶信息").doWrite(DataVO.getSheet1List()); } /** * Excel-寫多個(gè)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,寫兩個(gè)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(); // 執(zhí)行寫操作 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(); } } } } /** * 實(shí)體類,這里的注解會(huì)解析為Excel中的表頭 */ public class DataVO { @ExcelProperty("編號(hào)") private Integer id ; @ExcelProperty("名稱") private String name ; @ExcelProperty("手機(jī)號(hào)") private String phone ; @ExcelProperty("城市") private String cityName ; @ExcelProperty("日期") private Date date ; }
文件效果:
2、Excel讀取
對(duì)于讀取Excel文件來說,則需要根據(jù)具體的樣式來定了,在 easyexcel
組件中還可以添加讀取過程的監(jiān)聽器;
@Service public class ExcelService { /** * Excel-讀取數(shù)據(jù) */ public static void readExcel () throws Exception { // 文件處理 String basePath = getAbsolutePath(); File file = new File(basePath+"/easy-excel-01.xlsx") ; if (!file.exists()){ return ; } // 讀取數(shù)據(jù) List<DataVO> dataList = EasyExcel.read(file).head(DataVO.class) .sheet(0).headRowNumber(1).doReadSync(); dataList.forEach(System.out::println); } /** * Excel-讀取數(shù)據(jù)使用解析監(jiān)聽器 */ public static void readExcelListener () throws Exception { // 文件處理 String basePath = getAbsolutePath(); File file = new File(basePath+"/easy-excel-01.xlsx") ; if (!file.exists()){ return ; } // 讀取數(shù)據(jù),并且使用解析監(jiān)聽器 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、解析監(jiān)聽
繼承 AnalysisEventListener
類,并重寫其中的方法,可以監(jiān)聽Excel的解析過程,或者添加一些自定義的處理邏輯;
public class DataListener extends AnalysisEventListener<DataVO> { /** * 接收解析的數(shù)據(jù)塊 */ @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、導(dǎo)入導(dǎo)出
實(shí)際上Excel文件的導(dǎo)入導(dǎo)出,原理與文件的上傳下載類似,只不過這里使用 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數(shù)據(jù)", 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測(cè)試單個(gè)Excel上傳接口:
五、參考源碼
文檔倉庫: https://gitee.com/cicadasmile/butte-java-note 源碼倉庫: https://gitee.com/cicadasmile/butte-spring-parent
Gitee主頁: https://gitee.com/cicadasmile/butte-java-note
到此這篇關(guān)于SpringBoot3文件管理的文章就介紹到這了,更多相關(guān)SpringBoot文件管理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java?Selenium實(shí)現(xiàn)修改打開頁面窗口大小
Selenium是一個(gè)強(qiáng)大的自動(dòng)化測(cè)試工具,支持多種編程語言和瀏覽器,本文將詳細(xì)介紹如何使用Java?Selenium來修改打開頁面窗口的大小,需要的可以參考下2025-01-01SpringBoot @FixMethodOrder 如何調(diào)整單元測(cè)試順序
這篇文章主要介紹了SpringBoot @FixMethodOrder 調(diào)整單元測(cè)試順序方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09SpringBoot?熱搜與不雅文字過濾的實(shí)現(xiàn)
本文主要介紹了SpringBoot?熱搜與不雅文字過濾的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07MyBatis源碼解析——獲取SqlSessionFactory方式
這篇文章主要介紹了MyBatis源碼解析——獲取SqlSessionFactory方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12SpringBoot Mybatis批量插入Oracle數(shù)據(jù)庫數(shù)據(jù)
這篇文章主要介紹了SpringBoot Mybatis批量插入Oracle數(shù)據(jù)庫數(shù)據(jù),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08