1. 程式人生 > 其它 >【Excel】Poi + Hutool Springboot 讀寫Excel案例

【Excel】Poi + Hutool Springboot 讀寫Excel案例

 

 

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