JAVA+POI实现大数据量excel表格的导入、导出

实际项目中经常会遇到excel导入、导出操作,数据量过大会导致内存溢出,自己封装了一个导入导出的工具类,包括用户模式、事件驱动模式两种导入导出,数据量较小是可以使用用户模式,数据量比较大使用事件驱动模式,实测事件驱动模式下导入导出百万数据量毫无压力。

下面介绍下事件驱动模式导入导出的用法:

一、事件驱动模式导入

1、定义导入实体类,对应excel表格每一行数据,需要与表格字段顺序一致(使用lombok插件,省去getter、setter方法)。

@Data
public class ImportVo {
  private String name;

  private String sex;

  private String email;

  private String age;
}

2、导入方法调用,解析本地文件,同时映射为定义的实体类(文件中单元格类型设置为文本格式)。

public void importExcel() throws Exception {
    ExcelHandler handler = new ExcelHandlerImpl();

    String path = "D:/test.xlsx";
    File file = new File(path);
    List<ImportVo> list = handler.saxImport(file, "sheet", ImportVo.class, true);

    List<User> userList = new ArrayList<>();
    Iterator<ImportVo> iterator = list.iterator();
    while (iterator.hasNext()) {
      ImportVo importVo = iterator.next();
      User user = new User();
      user.setName(importVo.getName());
      user.setSex(Integer.parseInt(importVo.getSex()));
      user.setEmail(importVo.getEmail());
      user.setAge(Double.parseDouble(importVo.getAge()));
      user.setCreateTime(new Date());

      userList.add(user);

      if (userList.size() == 10000) {
        userMapper.batchInsert(userList);

        userList.clear();
      }
    }
  }

二、事件驱动模式导出

1、定义导出实体类,@Header为导出列头显示的内容(使用lombok插件,省去getter、setter方法)。

@Data
public class ExportVo {
  @Header("姓名")
  private String name;

  @Header("性别")
  private int sex;

  @Header("邮箱")
  private String email;

  @Header("年龄")
  private double age;
}

2、分页填充数据,每次填充10000条数据,添加完所有数据后,写入本地文件。

public void export() throws Exception {
    // 导出到本地磁盘
    String path = "D:/test.xlsx";

    Workbook wb = new SXSSFWorkbook(1000);
    Sheet sheet = wb.createSheet("export_sheet");
    ExcelHandler handler = new ExcelHandlerImpl();

    List<ExportVo> dtoList = new ArrayList<>();

    PageInfo<User> pageInfo = findAll(1, 10000);

    fillSheet(sheet, handler, dtoList, pageInfo);

    while (pageInfo.isHasNextPage()) {
      pageInfo = findAll(pageInfo.getNextPage(), 10000);

      fillSheet(sheet, handler, dtoList, pageInfo);
    }

    File file = new File(path);
    OutputStream os = new FileOutputStream(file);
    wb.write(os);
  }


private void fillSheet(
      Sheet sheet, ExcelHandler handler, List<ExportVo> dtoList, PageInfo<User> pageInfo)
      throws Exception {
    dtoList.clear();
    for (User user : pageInfo.getList()) {
      ExportVo vo = new ExportVo();
      vo.setName(user.getName());
      vo.setSex(user.getSex());
      vo.setEmail(user.getEmail());
      vo.setAge(user.getAge());

      dtoList.add(vo);
    }
    handler.fillSheet(sheet, true, dtoList);
  }

3、不分页导出

public void exportNoPage() throws Exception {
    // 导出到本地磁盘
    String path = "D:/test.xlsx";

    ExcelHandler handler = new ExcelHandlerImpl();

    List<ExportVo> dtoList = new ArrayList<>();

    PageInfo<User> pageInfo = findAll(1, 1000000);
    for (User user:pageInfo.getList()) {
      ExportVo vo = new ExportVo();
      vo.setName(user.getName());
      vo.setSex(user.getSex());
      vo.setEmail(user.getEmail());
      vo.setAge(user.getAge());

      dtoList.add(vo);
    }

    Workbook wb = handler.exportXLSX("no_page",true,true,dtoList);

    File file = new File(path);
    OutputStream os = new FileOutputStream(file);
    wb.write(os);
  }

总结:这个是以POI为基础开发的一个工具集,难点在于事件驱动模式对Excel的解析,Excel2007以后都是用XML格式存储,所以解析就是对XML文件的处理,要了解XML的存储结构然后对不同的标签做不同的处理。

源码地址:https://github.com/yuwy691/PoiExcelHandler.git

如何查看Excel2007 XML存储结构:https://blog.csdn.net/yuwy691/article/details/86161227

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值