【Excel】Poi + Hutool Springboot 讀寫Excel案例
阿新 • • 發佈:2022-04-01
Excel處理需要的依賴:
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.2</version> </dependency> <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.22</version> </dependency>
資料對映的PO類:
package cn.cloud9.demo.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.time.LocalDateTime; /** * @projectName: demo * @author: cloud9 * @date: 2022年03月30日 16:32 * @version: 1.0 */ @Data @AllArgsConstructor @NoArgsConstructor @ToString public class DictDTO { Integer id; String code; Boolean status; LocalDateTime createAt; }
Excel表格資料
Controller類:
處理流程直接寫Controller裡面了
package cn.cloud9.demo.easyexcel.controller; import cn.cloud9.demo.dto.DictDTO; import cn.hutool.poi.excel.ExcelReader; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelWriter; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @projectName: demo * @author: cloud9 * @date: 2022年03月30日 14:50 * @version: 1.0 */ @RestController @RequestMapping("/excel") public class DemoController { static Map<String, String> map = new ConcurrentHashMap<>(); static { /** * 注意別名Map設定 * 生成Excel的時候 - 屬性做Key 翻譯的名稱標題做Value * 讀取Excel的時候 - 翻譯的名稱標題做Key 屬性做Value */ map.put("ID", "id"); map.put("程式碼", "code"); map.put("狀態", "status"); map.put("建立日期", "createAt"); } }
Excel檔案上傳進行讀取
Hutool提供的ExcelReader可以簡化資料裝填處理
直接按照PO類和頭別名對映進行資料封裝:
/** * localhost:8085/excel/upload * @param multipartFile * @return void * @author cloud9 * @createTime 2022/3/31 16:04 * */ @PostMapping("/upload") public void upload(@RequestParam(name = "excel") MultipartFile multipartFile) throws Exception{ // 獲取檔名稱 String filename = multipartFile.getOriginalFilename(); // 檔案輸入流 InputStream inputStream = multipartFile.getInputStream(); // 得到Hutool的Reader ExcelReader reader = ExcelUtil.getReader(inputStream); /** * 預設讀取第一個Sheet * 讀取為Map列表,預設第一行為標題行,Map中的key為標題,value為標題對應的單元格值。 * @param multipartFile * @return void * @author cloud9 * @createTime 2022/3/31 16:18 * */ List<Map<String, Object>> list = reader.readAll(); // PO需要設定Map來對應設定 reader.setHeaderAlias(map); // 能解析公式 List<DictDTO> list2 = reader.readAll(DictDTO.class); System.out.println(filename); System.out.println(list); System.out.println(list2); }
取出資料,裝填到Excel檔案中返回出去
這樣遍歷map裝填不能指定標題欄位的順序
如果需要指定順序,就需要自己一個個呼叫add方法手動設定
/** * localhost:8085/excel/download * @param response * @return void * @author 戴知舟 * @createTime 2022/4/1 09:21 * */ @GetMapping("/download") public void download(HttpServletResponse response) throws Exception{ // 建立模擬資料 List<DictDTO> dicts = new ArrayList<>(); dicts.add(new DictDTO(1001, "Code-1001", true, LocalDateTime.now())); dicts.add(new DictDTO(2002, "Code-2002", true, LocalDateTime.now())); dicts.add(new DictDTO(3003, "Code-3003", true, LocalDateTime.now())); dicts.add(new DictDTO(4004, "Code-4004", false, LocalDateTime.now())); dicts.add(new DictDTO(5005, "Code-5005", true, LocalDateTime.now())); dicts.add(new DictDTO(6006, "Code-6006", false, LocalDateTime.now())); // 獲取寫入器物件 ExcelWriter excelWriter = ExcelUtil.getWriter(); // 設定別名標題對映 // excelWriter.setHeaderAlias(map); × // 如果要指定欄位順序,還是一個個新增操作 map.forEach((k, v) -> excelWriter.addHeaderAlias(v, k)); // 裝填資料, 並設定了標題頭的資訊 excelWriter.write(dicts, true); // true 設定標題(灰色背景), false 不設定 // 獲取服務的響應流,設定檔案資訊 String filename = "測試Excel檔案-" + System.currentTimeMillis() + ".xlsx"; response.setContentType("application/vnd.ms-excel;charset=utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + filename + ";filename*=utf-8''" + URLEncoder.encode(filename, "UTF-8")); final OutputStream OUTPUT_STREAM = response.getOutputStream(); // 開始寫入 excelWriter.flush(OUTPUT_STREAM, true); // 關閉資源 excelWriter.close(); OUTPUT_STREAM.close(); }
Postman檔案上傳測試
localhost:8085/excel/upload
調整輸出程式碼:
list.forEach(System.out::println); list2.forEach(System.out::println);
控制檯列印:
XLS表.xls {ID=1001, 程式碼=CODE-1001, 狀態=true, 建立日期=2022-03-22 00:00:00} {ID=1002, 程式碼=CODE-1002, 狀態=true, 建立日期=2022-03-23 00:00:00} {ID=1003, 程式碼=CODE-1003, 狀態=true, 建立日期=2022-03-24 00:00:00} {ID=1004, 程式碼=CODE-1004, 狀態=true, 建立日期=2022-03-25 00:00:00} {ID=1005, 程式碼=CODE-1005, 狀態=true, 建立日期=2022-03-26 00:00:00} {ID=1006, 程式碼=CODE-1006, 狀態=true, 建立日期=2022-03-27 00:00:00} {ID=1007, 程式碼=CODE-1007, 狀態=true, 建立日期=2022-03-28 00:00:00} {ID=1008, 程式碼=CODE-1008, 狀態=true, 建立日期=2022-03-29 00:00:00} {ID=1009, 程式碼=CODE-1009, 狀態=true, 建立日期=2022-03-30 00:00:00} DictDTO(id=1001, code=CODE-1001, status=true, createAt=2022-03-22T00:00) DictDTO(id=1002, code=CODE-1002, status=true, createAt=2022-03-23T00:00) DictDTO(id=1003, code=CODE-1003, status=true, createAt=2022-03-24T00:00) DictDTO(id=1004, code=CODE-1004, status=true, createAt=2022-03-25T00:00) DictDTO(id=1005, code=CODE-1005, status=true, createAt=2022-03-26T00:00) DictDTO(id=1006, code=CODE-1006, status=true, createAt=2022-03-27T00:00) DictDTO(id=1007, code=CODE-1007, status=true, createAt=2022-03-28T00:00) DictDTO(id=1008, code=CODE-1008, status=true, createAt=2022-03-29T00:00) DictDTO(id=1009, code=CODE-1009, status=true, createAt=2022-03-30T00:00)
測試Excel檔案下載:
http://localhost:8085/excel/download