使用EasyPoi导入、导出excel

前言

springboot版本:2.6.2

一、集成

在SpringBoot中集成EasyPoi非常简单,只需添加如下一个依赖即可,真正的开箱即用!

<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-spring-boot-starter</artifactId>
    <version>4.4.0</version>
</dependency>
复制代码

使用

接下来介绍下EasyPoi的使用,以会员信息和订单信息的导入导出为例,分别实现下简单的单表导出和具有关联信息的复杂导出。

简单导出

我们以会员信息列表导出为例,使用EasyPoi来实现下导出功能,看看是不是够简单!

  • 首先创建一个会员对象Member,封装会员信息;
package com.example.pojo;

import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.sql.Date;

/**
 * 购物会员
 * 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 {
    @Autowired
    private EasyPoiService easyPoiService;

    @ApiOperation(value = "导出会员列表Excel")
    @RequestMapping(value = "/exportMemberList", method = RequestMethod.GET)
    public void exportMemberList(ModelMap modelMap,
                                 HttpServletRequest request,
                                 HttpServletResponse response) {
        modelMap = easyPoiService.exportMemberExcel(modelMap);

        PoiBaseView.render(modelMap, request, response, NormalExcelConstants.EASYPOI_EXCEL_VIEW);
    }
}
复制代码
  • 对应的service及serviceImpl EasyPoiService:
package com.example.service;

import com.example.pojo.Member;
import org.springframework.ui.ModelMap;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

public interface EasyPoiService {

    /**
     * 导出会员excel数据
     * @param modelMap
     * @return
     */
    ModelMap exportMemberExcel(ModelMap modelMap);
}
复制代码

EasyPoiServiceImpl:

package com.example.service.impl;

import cn.afterturn.easypoi.entity.vo.NormalExcelConstants;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.example.pojo.Member;
import com.example.pojo.Order;
import com.example.pojo.Product;
import com.example.service.EasyPoiService;
import com.example.util.LocalJsonUtil;
import com.example.util.MemberExcelDataHandler;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@Service("easyPoiService")
public class EasyPoiServiceImpl implements EasyPoiService {

    @Override
    public ModelMap exportMemberExcel(ModelMap modelMap) {

        List<Member> memberList = LocalJsonUtil.getListFromJson("json/members.json", Member.class);
                ExportParams params = new ExportParams("会员列表", "会员列表", ExcelType.XSSF);
                modelMap.put(NormalExcelConstants.DATA_LIST, memberList);
                modelMap.put(NormalExcelConstants.CLASS, Member.class);
                modelMap.put(NormalExcelConstants.PARAMS, params);
                modelMap.put(NormalExcelConstants.FILE_NAME, "memberList");

        return modelMap;
    }
}
复制代码
  • LocalJsonUtil工具类,可以直接从resources目录下获取JSON数据并转化为对象,例如此处使用的members.json
package com.example.util;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;

import java.nio.charset.Charset;
import java.util.List;

/**
 * 从本地获取JSON数据的工具类
 * Created by macro on 2021/10/16.
 */
public class LocalJsonUtil {

    /**
     * 从指定路径获取JSON并转换为List
     * @param path json文件路径
     * @param elementType List元素类型
     */
    public static  <T> List<T> getListFromJson(String path, Class<T> elementType) {
        ClassPathResource resource = new ClassPathResource(path);
        String jsonStr = IoUtil.read(resource.getStream(), Charset.forName("UTF-8"));
        JSONArray jsonArray = new JSONArray(jsonStr);
        return JSONUtil.toList(jsonArray, elementType);
    }
}
复制代码

  • 下载完成后,查看下文件,一个标准的Excel文件已经被导出了。

简单导入

导入功能实现起来也非常简单,下面以会员信息列表的导入为例。

  • 在Controller中添加会员信息导入的接口,这里需要注意的是使用@RequestPart注解修饰文件上传参数,否则在Swagger中就没法显示上传按钮了;
/**
 * 这里需要注意的是使用@RequestPart注解修饰文件上传参数,
 * 否则在Swagger中就没法显示上传按钮了;
 * @param file
 * @return
 */
@ApiOperation("从Excel导入会员列表")
@RequestMapping(value = "/importMemberList", method = RequestMethod.POST)
@ResponseBody
public ResponseResult importMemberList(@RequestPart("file") MultipartFile file) throws Exception {
    List<Member> memberList = easyPoiService.importMemberExcel(file);

    return ResponseResult.ok().data(memberList);
}
复制代码
  • 在service和serviceImpl添加对应的实现 service:
/**
 * 导入会员excel数据
 * @param file
 * @return
 */
List<Member> importMemberExcel(MultipartFile file) throws Exception;
复制代码

serviceImpl:

@Override
public List<Member> importMemberExcel(MultipartFile file) throws Exception {
    ImportParams importParams = new ImportParams();
    importParams.setTitleRows(1);
    importParams.setHeadRows(1);

    List<Member> list = ExcelImportUtil.importExcel(
            file.getInputStream(),
            Member.class, importParams);

    return list;
}
复制代码
  • 然后在Swagger中测试接口,选择之前导出的Excel文件即可,导入成功后会返回解析到的数据。

复杂导出

当然EasyPoi也可以实现更加复杂的Excel操作,比如导出一个嵌套了会员信息和商品信息的订单列表,下面我们来实现下!

  • 首先添加商品对象Product,用于封装商品信息;
package com.example.pojo;

import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;

/**
 * 商品
 * 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就是我们需要导出的嵌套订单数据;
package com.example.pojo;

import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelCollection;
import cn.afterturn.easypoi.excel.annotation.ExcelEntity;

import lombok.Data;
import lombok.EqualsAndHashCode;

import java.sql.Date;
import java.util.List;

/**
 * 订单
 * 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方法排除掉;
@ApiOperation(value = "导出订单列表Excel")
@RequestMapping(value = "/exportOrderList", method = RequestMethod.GET)
public void exportOrderList(ModelMap modelMap,
                            HttpServletRequest request,
                            HttpServletResponse response) {
    modelMap = easyPoiService.exportOrderExcel(modelMap);
    PoiBaseView.render(modelMap, request, response, NormalExcelConstants.EASYPOI_EXCEL_VIEW);
}
复制代码

在service和serviceImpl中添加对应实现

service:

/**
 * 导出订单excel数据
 * @param modelMap
 * @return
 */
ModelMap exportOrderExcel(ModelMap modelMap);
复制代码

serviceImpl:

@Override
public ModelMap exportOrderExcel(ModelMap modelMap) {
    List<Order> orderList = getOrderList();
    ExportParams exportParams = new ExportParams("订单列表", "订单列表", ExcelType.XSSF);
    //导出时排除一些字段
    exportParams.setExclusions(new String[]{"ID", "出生日期", "性别"});
    modelMap.put(NormalExcelConstants.DATA_LIST, orderList);
    modelMap.put(NormalExcelConstants.CLASS, Order.class);
    modelMap.put(NormalExcelConstants.PARAMS, exportParams);
    modelMap.put(NormalExcelConstants.FILE_NAME, "orderList");

    return modelMap;
}

private List<Order> getOrderList() {
    List<Order> orderList = LocalJsonUtil.getListFromJson("json/orders.json", Order.class);
    List<Product> productList = LocalJsonUtil.getListFromJson("json/products.json", Product.class);
    List<Member> memberList = LocalJsonUtil.getListFromJson("json/members.json", Member.class);
    for (int i = 0; i < orderList.size(); i++) {
        Order order = orderList.get(i);
        order.setMember(memberList.get(i));
        order.setProductList(productList);
    }
    return orderList;
}
复制代码
  • 在Swagger中访问接口测试,导出订单列表对应Excel;

  • 下载完成后,查看下文件,EasyPoi导出复杂的Excel也是很简单的!

自定义处理

如果你想对导出字段进行一些自定义处理,EasyPoi也是支持的,比如在会员信息中,如果用户没有设置昵称,我们添加下暂未设置信息。

  • 我们需要添加一个处理器继承默认的ExcelDataHandlerDefaultImpl类,然后在exportHandler方法中实现自定义处理逻辑;
package com.example.util;

import cn.afterturn.easypoi.handler.impl.ExcelDataHandlerDefaultImpl;
import cn.hutool.core.util.StrUtil;
import com.example.pojo.Member;

/**
 * 自定义字段处理
 * 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设置自定义处理器;
@Override
public ModelMap exportMemberExcel(ModelMap modelMap) {
    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);
    modelMap.put(NormalExcelConstants.DATA_LIST, memberList);
    modelMap.put(NormalExcelConstants.CLASS, Member.class);
    modelMap.put(NormalExcelConstants.PARAMS, params);
    modelMap.put(NormalExcelConstants.FILE_NAME, "memberList");

    return modelMap;
}
复制代码
  • 再次调用导出接口,我们可以发现昵称已经添加默认设置了。

总结

体验了一波EasyPoi,它使用注解来操作Excel的方式确实非常好用。如果你想生成更为复杂的Excel的话,可以考虑下它的模板功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值