Java EasyExcel利用填充模版动态生成多个sheet页

 更新时间:2023年12月12日 09:22:56   作者:小王博客基地  
这篇文章主要为大家详细介绍了Java EasyExcel如何利用填充模版动态生成多个sheet页,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

一、前言

今天收到一个导出Excel的需求,这种需求经常做,看到模版还是是有点复杂的有头有行,一般的导出是不好做,使用模板填充比较简单! 另外还有一个需求小编是第一次见,所以来记录一下,为后来人铺路!

需求:导出有单子的头信息和一些多个行信息,前端可以多选,多个放在一个excel里的sheet中

明白了需求我们技术选型,现在基本都是EasyExcel用的比较多,今天使用的版本为:3.1.5,低版本已经不维护,建议使用高点的版本哈!

在这里先说一下,EasyExcel单独是无法实现一个模版动态填充多个sheet页,所以我们使用POI来帮忙复制sheet页即可!

二、准备工作

1. 阉割版效果图

我简化了一些功能,自己做了一个简单的模板,但是功能都是有的,大致如下图所示:

多个就使用合同号作为sheet名称,每个里面也会有多个行垂直填充即可!

2. 填充模版

3. 导入依赖

中间使用了Hutool来获取流,很多公司不让使用Hutool的,大家自己选择,不使用可以用:

  • Spring的ResourceUtils.getFile()
  • JDK的new File()

本次使用Hutool的ClassPathResource

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.5</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.4</version>
</dependency>

4. 导出实体

/**
 * @author wangzhenjun
 * @date 2023/7/4 17:09
 */
@Data
public class TestExcel {

    private String contractNo;

    private String address;
    
	private String dateTime;

    private List<Item> itemList;

    @Data
    public static class Item{

        private String name;

        private BigDecimal price;
    }
}

三、实战代码

为了方便直接写在Controller里了,大家不要学习哈,业务的处理还是要在service里写!

整体思路:

使用POIXSSFWorkbook 来根据要导出的个数来进行复制sheet页,名称为合同号

将复制好的sheet页转换成字节数组,然后再通过输入流的方式读取字节数组中的数据。

EasyExcel 将使用输入流中的模板数据生成 Excel 数据,并将生成的 Excel 文件写入到 HttpServletResponse 的输出流中,以便将其发送给客户端进行下载或其他处理。

创建一个 WriteSheet 对象,并将其与上面复制的sheet页名称关联,就可以往里面填充数据了!

如果有这种list多个行填充的并且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true

不加的话会把你后面的内容给覆盖了!

但是这个就会把所有数据放到内存 会很耗内存!

用完记得把流关闭哈!

@SneakyThrows
@GetMapping("/excel")
public void excel (HttpServletResponse response){
    int size = 2;
    List<TestExcel> testExcels = new ArrayList<>();
    for (int i = 0; i < size; i++) {
        TestExcel testExcel = new TestExcel();
        testExcel.setContractNo("HT07040" + (i + 1));
        testExcel.setAddress("青岛" + i + "号基地");
        testExcel.setDateTime("2023-07-05");
        testExcels.add(testExcel);
        List<TestExcel.Item> itemList = new ArrayList<>();
        for (int j = 0; j < size; j++) {
            TestExcel.Item item = new TestExcel.Item();
            item.setName("商品" + (j + 1));
            item.setPrice(new BigDecimal("188").multiply(new BigDecimal(j + 1)));
            itemList.add(item);
        }
        testExcel.setItemList(itemList);
    }
    response.setCharacterEncoding("utf-8");
    String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
    response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    ClassPathResource classPathResource = new ClassPathResource("template" + File.separator + "测试.xlsx");
    InputStream stream = classPathResource.getStream();
    // 把excel流给这个对象,后续可以操作
    XSSFWorkbook workbook = new XSSFWorkbook(stream);
    // 设置模板的第一个sheet的名称,名称我们使用合同号
    workbook.setSheetName(0, testExcels.get(0).getContractNo());
    for (int i = 1; i < size; i++) {
        // 剩余的全部复制模板sheet0即可
        workbook.cloneSheet(0, testExcels.get(i).getContractNo());
    }
    // 把workbook写到流里
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    workbook.write(baos);
    byte[] bytes = baos.toByteArray();
    stream = new ByteArrayInputStream(bytes);
    ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(stream).build();

    for (TestExcel testExcel : testExcels) {
        WriteSheet writeSheet = EasyExcel.writerSheet(testExcel.getContractNo()).build();
        // list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).direction(WriteDirectionEnum.VERTICAL).build();
        excelWriter.fill(testExcel, writeSheet);
        excelWriter.fill(new FillWrapper("item", testExcel.getItemList()), fillConfig, writeSheet);
    }
    excelWriter.finish();
    baos.close();
    stream.close();
}

四、总结

这样就完成了,主要的难点是复制sheet页,多行填充在EasyExcel官网都是有的,还有一些我这边没有用到的东西,大家可以根据自己的需求去找找看!

到此这篇关于Java EasyExcel利用填充模版动态生成多个sheet页的文章就介绍到这了,更多相关Java EasyExcel生成多个sheet内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java判断字符串是否是整数或者浮点数的方法

    Java判断字符串是否是整数或者浮点数的方法

    今天小编就为大家分享一篇Java判断字符串是否是整数或者浮点数的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • mybatis自动生成@Table、@Column、@Id注解的方法

    mybatis自动生成@Table、@Column、@Id注解的方法

    这篇文章主要介绍了mybatis自动生成@Table、@Column、@Id注解的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • java SpringBoot自定义注解,及自定义解析器实现对象自动注入操作

    java SpringBoot自定义注解,及自定义解析器实现对象自动注入操作

    这篇文章主要介绍了java SpringBoot自定义注解,及自定义解析器实现对象自动注入操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • IDEA中配置多个版本的JDK的实现示例

    IDEA中配置多个版本的JDK的实现示例

    IDEA可以配置多个JDK,根据需要使用不同版本的,本文就来介绍一下IDEA中配置多个版本的JDK的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Java应用程序的CPU使用率飙升原因详细分析

    Java应用程序的CPU使用率飙升原因详细分析

    这篇文章主要介绍了Java应用程序的CPU使用率飙升原因详细分析,在 Java 中,我们使用 JVM 进行线程调度,所以一般来说,线程的调度有两种模式:分时调度和抢占式调度,线程和进程在阻塞或者等待时,都不会使用 CPU 资源,需要的朋友可以参考下
    2024-01-01
  • java实现操作系统中的最佳置换Optimal算法

    java实现操作系统中的最佳置换Optimal算法

    这篇文章主要介绍了java实现操作系统中的最佳置换Optimal算法 ,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • 一文带你学会规则引擎Drools的应用

    一文带你学会规则引擎Drools的应用

    Drools 就是一个开源的业务规则引擎,可以很容易地与 spring boot 应用程序集成,这篇文章就来和大家详细聊聊Drools的具体应用,需要的可以参考一下
    2023-03-03
  • RestTemplate发送form-data请求上传rul资源文件及对象参数方式

    RestTemplate发送form-data请求上传rul资源文件及对象参数方式

    这篇文章主要介绍了RestTemplate发送form-data请求上传rul资源文件及对象参数方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • SpringBoot通过自定义注解实现配置类的自动注入的实现

    SpringBoot通过自定义注解实现配置类的自动注入的实现

    本文主要介绍了SpringBoot通过自定义注解实现配置类的自动注入的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Java设计模式之观察者模式observer pattern详解

    Java设计模式之观察者模式observer pattern详解

    这篇文章主要介绍了Java设计模式之观察者模式observer pattern详解,当一个对象发生数据变化时,通知其他相关的一系列对象,接受到通知的对象根据该对象的变化进行相应处理以响应变化的过程,需要的朋友可以参考下
    2023-12-12

最新评论