乐趣区

关于java:SpringBoot实现Excel导入导出好用到爆POI可以扔掉了

在咱们平时工作中常常会遇到要操作 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!

退出移动版