SpringBoot實現Excel匯入匯出,好用到爆,POI可以扔掉了!

macrozheng發表於2021-10-27
在我們平時工作中經常會遇到要操作Excel的功能,比如匯出個使用者資訊或者訂單資訊的Excel報表。你肯定聽說過POI這個東西,可以實現。但是POI實現的API確實很麻煩,它需要寫那種逐行解析的程式碼(類似Xml解析)。今天給大家推薦一款非常好用的Excel匯入匯出工具EasyPoi,希望對大家有所幫助!

SpringBoot實戰電商專案mall(50k+star)地址:https://github.com/macrozheng/mall

EasyPoi簡介

用慣了SpringBoot的朋友估計會想到,有沒有什麼辦法可以直接定義好需要匯出的資料物件,然後新增幾個註解,直接自動實現Excel匯入匯出功能?

EasyPoi正是這麼一款工具,如果你不太熟悉POI,想簡單地實現Excel操作,用它就對了!

EasyPoi的目標不是替代POI,而是讓一個不懂匯入匯出的人也能快速使用POI完成Excel的各種操作,而不是看很多API才可以完成這樣的工作。

整合

在SpringBoot中整合EasyPoi非常簡單,只需新增如下一個依賴即可,真正的開箱即用!
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-spring-boot-starter</artifactId>
    <version>4.4.0</version>
</dependency>

使用

接下來介紹下EasyPoi的使用,以會員資訊和訂單資訊的匯入匯出為例,分別實現下簡單的單表匯出和具有關聯資訊的複雜匯出。

簡單匯出

我們以會員資訊列表匯出為例,使用EasyPoi來實現下匯出功能,看看是不是夠簡單!
  • 首先建立一個會員物件Member,封裝會員資訊;
/**
 * 購物會員
 * Created by macro on 2021/10/12.
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class Member {
    @Excel(name = "ID", width = 10)
    private Long id;
    @Excel(name = "使用者名稱", width = 20, needMerge = true)
    private String username;
    private String password;
    @Excel(name = "暱稱", width = 20, needMerge = true)
    private String nickname;
    @Excel(name = "出生日期", width = 20, format = "yyyy-MM-dd")
    private Date birthday;
    @Excel(name = "手機號", width = 20, needMerge = true, desensitizationRule = "3_4")
    private String phone;
    private String icon;
    @Excel(name = "性別", width = 10, replace = {"男_0", "女_1"})
    private Integer gender;
}
  • 在此我們就可以看到EasyPoi的核心註解@Excel,通過在物件上新增@Excel註解,可以將物件資訊直接匯出到Excel中去,下面對註解中的屬性做個介紹;

    • name:Excel中的列名;
    • width:指定列的寬度;
    • needMerge:是否需要縱向合併單元格;
    • format:當屬性為時間型別時,設定時間的匯出匯出格式;
    • desensitizationRule:資料脫敏處理,3_4表示只顯示字串的前3位和後4位,其他為*號;
    • replace:對屬性進行替換;
    • suffix:對資料新增字尾。
  • 接下來我們在Controller中新增一個介面,用於匯出會員列表到Excel,具體程式碼如下;
/**
 * EasyPoi匯入匯出測試Controller
 * Created by macro on 2021/10/12.
 */
@Controller
@Api(tags = "EasyPoiController", description = "EasyPoi匯入匯出測試")
@RequestMapping("/easyPoi")
public class EasyPoiController {

    @ApiOperation(value = "匯出會員列表Excel")
    @RequestMapping(value = "/exportMemberList", method = RequestMethod.GET)
    public void exportMemberList(ModelMap map,
                                 HttpServletRequest request,
                                 HttpServletResponse response) {
        List<Member> memberList = LocalJsonUtil.getListFromJson("json/members.json", Member.class);
        ExportParams params = new ExportParams("會員列表", "會員列表", ExcelType.XSSF);
        map.put(NormalExcelConstants.DATA_LIST, memberList);
        map.put(NormalExcelConstants.CLASS, Member.class);
        map.put(NormalExcelConstants.PARAMS, params);
        map.put(NormalExcelConstants.FILE_NAME, "memberList");
        PoiBaseView.render(map, request, response, NormalExcelConstants.EASYPOI_EXCEL_VIEW);
    }
}
  • LocalJsonUtil工具類,可以直接從resources目錄下獲取JSON資料並轉化為物件,例如此處使用的members.json

  • 執行專案,直接通過Swagger訪問介面,注意在Swagger中訪問介面無法直接下載,需要點選返回結果中的下載按鈕才行,訪問地址:http://localhost:8088/swagger...

  • 下載完成後,檢視下檔案,一個標準的Excel檔案已經被匯出了。

簡單匯入

匯入功能實現起來也非常簡單,下面以會員資訊列表的匯入為例。
  • 在Controller中新增會員資訊匯入的介面,這裡需要注意的是使用@RequestPart註解修飾檔案上傳引數,否則在Swagger中就沒法顯示上傳按鈕了;
/**
 * EasyPoi匯入匯出測試Controller
 * Created by macro on 2021/10/12.
 */
@Controller
@Api(tags = "EasyPoiController", description = "EasyPoi匯入匯出測試")
@RequestMapping("/easyPoi")
public class EasyPoiController {

    @ApiOperation("從Excel匯入會員列表")
    @RequestMapping(value = "/importMemberList", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult importMemberList(@RequestPart("file") MultipartFile file) {
        ImportParams params = new ImportParams();
        params.setTitleRows(1);
        params.setHeadRows(1);
        try {
            List<Member> list = ExcelImportUtil.importExcel(
                    file.getInputStream(),
                    Member.class, params);
            return CommonResult.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return CommonResult.failed("匯入失敗!");
        }
    }
}
  • 然後在Swagger中測試介面,選擇之前匯出的Excel檔案即可,匯入成功後會返回解析到的資料。

複雜匯出

當然EasyPoi也可以實現更加複雜的Excel操作,比如匯出一個巢狀了會員資訊和商品資訊的訂單列表,下面我們來實現下!
  • 首先新增商品物件Product,用於封裝商品資訊;
/**
 * 商品
 * Created by macro on 2021/10/12.
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class Product {
    @Excel(name = "ID", width = 10)
    private Long id;
    @Excel(name = "商品SN", width = 20)
    private String productSn;
    @Excel(name = "商品名稱", width = 20)
    private String name;
    @Excel(name = "商品副標題", width = 30)
    private String subTitle;
    @Excel(name = "品牌名稱", width = 20)
    private String brandName;
    @Excel(name = "商品價格", width = 10)
    private BigDecimal price;
    @Excel(name = "購買數量", width = 10, suffix = "件")
    private Integer count;
}
  • 然後新增訂單物件Order,訂單和會員是一對一關係,使用 @ExcelEntity註解表示,訂單和商品是一對多關係,使用@ExcelCollection註解表示,Order就是我們需要匯出的巢狀訂單資料;
/**
 * 訂單
 * Created by macro on 2021/10/12.
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class Order {
    @Excel(name = "ID", width = 10,needMerge = true)
    private Long id;
    @Excel(name = "訂單號", width = 20,needMerge = true)
    private String orderSn;
    @Excel(name = "建立時間", width = 20, format = "yyyy-MM-dd HH:mm:ss",needMerge = true)
    private Date createTime;
    @Excel(name = "收貨地址", width = 20,needMerge = true )
    private String receiverAddress;
    @ExcelEntity(name = "會員資訊")
    private Member member;
    @ExcelCollection(name = "商品列表")
    private List<Product> productList;
}
  • 接下來在Controller中新增匯出訂單列表的介面,由於有些會員資訊我們不需要匯出,可以呼叫ExportParams中的setExclusions方法排除掉;
/**
 * EasyPoi匯入匯出測試Controller
 * Created by macro on 2021/10/12.
 */
@Controller
@Api(tags = "EasyPoiController", description = "EasyPoi匯入匯出測試")
@RequestMapping("/easyPoi")
public class EasyPoiController {

    @ApiOperation(value = "匯出訂單列表Excel")
    @RequestMapping(value = "/exportOrderList", method = RequestMethod.GET)
    public void exportOrderList(ModelMap map,
                                HttpServletRequest request,
                                HttpServletResponse response) {
        List<Order> orderList = getOrderList();
        ExportParams params = new ExportParams("訂單列表", "訂單列表", ExcelType.XSSF);
        //匯出時排除一些欄位
        params.setExclusions(new String[]{"ID", "出生日期", "性別"});
        map.put(NormalExcelConstants.DATA_LIST, orderList);
        map.put(NormalExcelConstants.CLASS, Order.class);
        map.put(NormalExcelConstants.PARAMS, params);
        map.put(NormalExcelConstants.FILE_NAME, "orderList");
        PoiBaseView.render(map, request, response, NormalExcelConstants.EASYPOI_EXCEL_VIEW);
    }
}
  • 在Swagger中訪問介面測試,匯出訂單列表對應Excel;

  • 下載完成後,檢視下檔案,EasyPoi匯出複雜的Excel也是很簡單的!

自定義處理

如果你想對匯出欄位進行一些自定義處理,EasyPoi也是支援的,比如在會員資訊中,如果使用者沒有設定暱稱,我們新增下暫未設定資訊。
  • 我們需要新增一個處理器繼承預設的ExcelDataHandlerDefaultImpl類,然後在exportHandler方法中實現自定義處理邏輯;
/**
 * 自定義欄位處理
 * Created by macro on 2021/10/13.
 */
public class MemberExcelDataHandler extends ExcelDataHandlerDefaultImpl<Member> {

  @Override
  public Object exportHandler(Member obj, String name, Object value) {
    if("暱稱".equals(name)){
      String emptyValue = "暫未設定";
      if(value==null){
        return super.exportHandler(obj,name,emptyValue);
      }
      if(value instanceof String&&StrUtil.isBlank((String) value)){
        return super.exportHandler(obj,name,emptyValue);
      }
    }
    return super.exportHandler(obj, name, value);
  }

  @Override
  public Object importHandler(Member obj, String name, Object value) {
    return super.importHandler(obj, name, value);
  }
}
  • 然後修改Controller中的介面,呼叫MemberExcelDataHandler處理器的setNeedHandlerFields設定需要自定義處理的欄位,並呼叫ExportParamssetDataHandler設定自定義處理器;
/**
 * EasyPoi匯入匯出測試Controller
 * Created by macro on 2021/10/12.
 */
@Controller
@Api(tags = "EasyPoiController", description = "EasyPoi匯入匯出測試")
@RequestMapping("/easyPoi")
public class EasyPoiController {

    @ApiOperation(value = "匯出會員列表Excel")
    @RequestMapping(value = "/exportMemberList", method = RequestMethod.GET)
    public void exportMemberList(ModelMap map,
                                 HttpServletRequest request,
                                 HttpServletResponse response) {
        List<Member> memberList = LocalJsonUtil.getListFromJson("json/members.json", Member.class);
        ExportParams params = new ExportParams("會員列表", "會員列表", ExcelType.XSSF);
        //對匯出結果進行自定義處理
        MemberExcelDataHandler handler = new MemberExcelDataHandler();
        handler.setNeedHandlerFields(new String[]{"暱稱"});
        params.setDataHandler(handler);
        map.put(NormalExcelConstants.DATA_LIST, memberList);
        map.put(NormalExcelConstants.CLASS, Member.class);
        map.put(NormalExcelConstants.PARAMS, params);
        map.put(NormalExcelConstants.FILE_NAME, "memberList");
        PoiBaseView.render(map, request, response, NormalExcelConstants.EASYPOI_EXCEL_VIEW);
    }
}
  • 再次呼叫匯出介面,我們可以發現暱稱已經新增預設設定了。

總結

體驗了一波EasyPoi,它使用註解來操作Excel的方式確實非常好用。如果你想生成更為複雜的Excel的話,可以考慮下它的模板功能。

參考資料

專案官網:https://gitee.com/lemur/easypoi

專案原始碼地址

https://github.com/macrozheng...

本文 GitHub https://github.com/macrozheng/mall-learning 已經收錄,歡迎大家Star!

相關文章