easyPoi导出多sheet页(干货)

一、需求来源:

        最新需求需要将一组数据分多个sheet页导出,每个sheet数据为1000。然后查询了网上的一些文章,发现没有自己想要的,就只能自己去看easyPoi的api文档。最终找到了解决的方法

二、导出效果:

导出的数据如上图所示,每个sheet页有一千条数据

三、代码思路:

        3.1:easypoi的api示例

        

/**
     * 根据Map创建对应的Excel(一个excel 创建多个sheet)
     *
     * @param list 多个Map key title 对应表格Title key entity 对应表格对应实体 key data
     *             Collection 数据
     * @return
     */
    public static Workbook exportExcel(List<Map<String, Object>> list, ExcelType type) {
        Workbook workbook = getWorkbook(type, 0);
        for (Map<String, Object> map : list) {
            ExcelExportService service = new ExcelExportService();
            ExportParams params = (ExportParams) map.get("title");
            params.setType(type);
            service.createSheet(workbook,params,
                    (Class<?>) map.get("entity"), (Collection<?>) map.get("data"));
        }
        return workbook;
    }
  3.2:easypoi的api解析

如上图说是我们可以看到有三个参数

1. title:对应表格title

2. entity:对应表格对应实体

3. data:导出的数据

4. type:类型有两种 : HSSF 和 XSSF

对于type这个类型大概解释一下,详细需要去阅读相关文章

用JavaPOI导出Excel时,我们需要考虑到Excel版本及数据量的问题。针对不同的Excel版本,要采用不同的工具类,如果使用错了,会出现错误信息。JavaPOI导出Excel有三种形式,他们分别是1.HSSFWorkbook  2.XSSFWorkbook  3.SXSSFWorkbook。

HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls;

XSSFWorkbook:是操作Excel2007后的版本,扩展名是.xlsx;

第一种:HSSFWorkbook

poi导出excel最常用的方式;但是此种方式的局限就是导出的行数至多为65535行,超出65536条后系统就会报错。此方式因为行数不足七万行所以一般不会发生内存不足的情况(OOM)。

第二种:XSSFWorkbook

这种形式的出现是为了突破HSSFWorkbook的65535行局限。其对应的是excel2007(1048576行,16384列)扩展名为“.xlsx”,最多可以导出104万行,不过这样就伴随着一个问题---OOM内存溢出,原因是你所创建的book sheet row cell等此时是存在内存的并没有持久化。

四、代码示例:

      1.首先将需要导出的字段加上@Excel注解


@Data
public class OrderExportVo {

    @Excel(name = "店铺名")
    private String shopName;

    @Excel(name = "物流单号",width = 20)
    @ApiModelProperty(value = "发货单号")
    private String logisticsNo;

    @Excel(name = "订单号",width = 20)
    @ApiModelProperty(value = "订单号")
    private String orderNum;
}

2.进行代码编写

 CompletableFuture.runAsync(() -> {
            //查询出所有的订单的数据
            List<Order> orderList = orderService.getOrderList(user);
            //将数据进行按照1000个拆分(拆分数据自己定义)
            List<List<Order>> partition = Lists.partition(orderList, 1000);
            // 多个sheet配置参数
            List<Map<String, Object>> sheetsList = new ArrayList<>();
            AtomicInteger atomicInteger = new AtomicInteger();
            partition.forEach(exportList -> {
                //将分割的数据赋值
                List<OrderExportVo> orderExportVoList = new ArrayList<>();
                for (Order order : exportList) {
                    OrderExportVo orderExportVo = new OrderExportVo();
                    BeanUtil.copyProperties(order,orderExportVo);
                    orderExportVoList.add(orderExportVo);
                }
                String sheetName = "sheet" + atomicInteger.addAndGet(1);
                Map<String, Object> exportMap = Maps.newHashMap();
                ExportParams exportParams = new ExportParams(null, sheetName, ExcelType.HSSF);
                // 以下3个参数为API中写死的参数名 分别是sheet配置/导出类(注解定义)/数据集
                exportMap.put("title", exportParams);
                exportMap.put("entity", OrderExportVo.class);
                exportMap.put("data", orderExportVoList);
                // 加入多sheet配置列表
                sheetsList.add(exportMap);
            });
            Workbook workbook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);
            String filePath = filePluginFactory.filePlugin().getFilePath(workbook);
            System.out.println(filePath);
        });

2.1:首先查询出自己需要的数据,然后通过工具类切割数组,分成1000个一组。

2.2:然后进行循环,将需要导出的数据进行赋值,然后将这个数据复制到对应的sheet中。

2.3:我这边采取的异步导出,最后获取到Workbook,然后上传到阿里云

四、待完善问题:

一次性查询数据量太大,所以后续需要优化成分批次查询,将每个批次查询的结果放入到对应的sheet里面;(TODO)

  • 24
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果要使用 easypoi 导出多个 sheet 并且处理大量数据,可以采用以下步骤: 1. 创建一个 Workbook 对象,并设置每个 sheet 的数据源和样式。可以使用 easypoi 提供的工具类来创建和设置样式。 2. 将每个 sheet 添加到 Workbook 中。 3. 如果数据量较大,可以采用分查询的方式,每次查询一部分数据,然后将数据添加到对应的 sheet 中。 4. 在导出时设置文件名和响应头,将 Workbook 输出到响应流中。 下面是一个示例代码,可以参考一下: ``` @RequestMapping("/export") public void export(HttpServletResponse response) { Workbook workbook = new SXSSFWorkbook(); // 导出第一个 sheet Sheet sheet1 = workbook.createSheet("Sheet1"); List<Data1> data1List = getData1List(); setSheet1Data(sheet1, data1List); // 导出第二个 sheet Sheet sheet2 = workbook.createSheet("Sheet2"); List<Data2> data2List = getData2List(); setSheet2Data(sheet2, data2List); // 设置响应头 response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment;filename=test.xlsx"); // 输出到响应流中 try { workbook.write(response.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } } private void setSheet1Data(Sheet sheet, List<Data1> data1List) { // 设置表头样式 CellStyle headerStyle = ExcelStyleUtil.getHeaderStyle(sheet.getWorkbook()); // 设置表格数据样式 CellStyle dataStyle = ExcelStyleUtil.getDataStyle(sheet.getWorkbook()); // 设置表头 Row headerRow = sheet.createRow(0); headerRow.createCell(0).setCellValue("字段1"); headerRow.createCell(1).setCellValue("字段2"); headerRow.createCell(2).setCellValue("字段3"); for (Cell cell : headerRow) { cell.setCellStyle(headerStyle); } // 添加数据 int rowIndex = 1; for (Data1 data1 : data1List) { Row row = sheet.createRow(rowIndex++); row.createCell(0).setCellValue(data1.getField1()); row.createCell(1).setCellValue(data1.getField2()); row.createCell(2).setCellValue(data1.getField3()); for (Cell cell : row) { cell.setCellStyle(dataStyle); } } } private void setSheet2Data(Sheet sheet, List<Data2> data2List) { // 设置表头样式 CellStyle headerStyle = ExcelStyleUtil.getHeaderStyle(sheet.getWorkbook()); // 设置表格数据样式 CellStyle dataStyle = ExcelStyleUtil.getDataStyle(sheet.getWorkbook()); // 设置表头 Row headerRow = sheet.createRow(0); headerRow.createCell(0).setCellValue("字段1"); headerRow.createCell(1).setCellValue("字段2"); headerRow.createCell(2).setCellValue("字段3"); for (Cell cell : headerRow) { cell.setCellStyle(headerStyle); } // 添加数据 int rowIndex = 1; for (Data2 data2 : data2List) { Row row = sheet.createRow(rowIndex++); row.createCell(0).setCellValue(data2.getField1()); row.createCell(1).setCellValue(data2.getField2()); row.createCell(2).setCellValue(data2.getField3()); for (Cell cell : row) { cell.setCellStyle(dataStyle); } } } ``` 其中,`ExcelStyleUtil` 是一个工具类,用来设置表格样式,可以根据需要自行实现。`SXSSFWorkbook` 是一个针对大量数据的 Workbook 实现,可以避免内存溢出的问题。在实际应用中,可以根据具体需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值