EasyExcel 填充+写入

天航星
• 阅读 723

使用 EasyExcel 导出 Excel 时,有时会遇到如下情况:

  • 既要根据模板填充某些 sheet
  • 又要根据业务写入某些 sheet

EasyExcel 官方没有提供这样的示例,经过自己的研究和实验,得到了如下步骤:

  1. 定义导出文件名

    String fileName = "测试.xlsx";
  2. 获取模板文件

    InputStream templateFile = ResourceUtil.getResourceObj("templates/template.xlsx").getStream();

    此时读取的模板文件默认为压缩文件,是不能在后续进行填充的,所以需要在 pom.xml 中进行配置:

    <build>
     <plugins>
         <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-resources-plugin</artifactId>
             <version>2.6</version>
             <configuration>
                 <!-- 配置不需要压缩的文件 -->
                 <nonFilteredFileExtensions>
                     <nonFilteredFileExtension>xls</nonFilteredFileExtension>
                     <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
                 </nonFilteredFileExtensions>
             </configuration>
         </plugin>
     </plugins>
    </build>
  3. 定义填充页数据

    @Data
    public class FillData {
     private String name;
     private double number;
    }
    FillData fillData = new FillData();
    fillData.setName("张三");
    fillData.setNumber(5.2);
  4. 定义业务页数据

    @Data
    public class BusinessData {
     @ExcelProperty("字符串标题")
     private String string;
     @ExcelProperty("日期标题")
     private Date date;
     @ExcelProperty("数字标题")
     private Double doubleData;
     /**
      * 忽略这个字段
      */
     @ExcelIgnore
     private String ignore;
    }
    BusinessData businessData = new BusinessData();
    businessData.setString("测试");
    businessData.setDate(new Date());
    businessData.setDoubleData(1.0);
    List<BusinessData> businessDataList = Collections.singletonList(businessData);
  5. 定义写入器

    ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFile).build();
  6. 定义填充页 sheet

    WriteSheet writeSheet0 = EasyExcel.writerSheet().registerWriteHandler(new CustomTemplateSheetStrategy("动态命名sheet")).build();

    这里使用了 CustomTemplateSheetStrategy

    之所以要使用该拦截器,是因为填充时默认是只能取模板定义的 sheet 名称作为填充页的 sheet 名称,但业务中往往是需要动态命名 sheet 的,所以使用拦截器进行拦截处理后命名。

CustomTemplateSheetStrategy代码如下:

import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;

/**
 * 自定义模板导出sheet拦截器
 * 
 * @author 天航星
 * @date 2024-07-03 13:48
 */
public class CustomTemplateSheetStrategy implements SheetWriteHandler {

    private Integer sheetNo;

    private String sheetName;

    public CustomTemplateSheetStrategy(String sheetName) {
        this.sheetName = sheetName;
    }

    public CustomTemplateSheetStrategy(Integer sheetNo, String sheetName) {
        this.sheetNo = sheetNo;
        this.sheetName = sheetName;
    }

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

    }

    /**
     * 功能:动态修改模板中sheet的名称
     * sheet创建完成后调用
     * @param writeWorkbookHolder
     * @param writeSheetHolder
     */
    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

        if (sheetName == null) {
            return;
        }
        if (sheetNo == null) {
            sheetNo = 0;
        }
        writeWorkbookHolder.getCachedWorkbook().setSheetName(sheetNo, sheetName);
    }
}
  1. 定义业务页 sheet

    WriteSheet writeSheet1 = EasyExcel.writerSheet("Sheet1").head(BusinessData.class).build();
  2. 填充数据

    excelWriter.fill(fillData, writeSheet0);

    注意:这里一定要传入对象,不能传入列表,否则填充的内容会变为空白。

  3. 写入数据

    excelWriter.write(businessDataList, writeSheet1);
  4. 关闭写入器

    excelWriter.finish();

    注意:这里必须要关闭写入器,不然写入的文件为空。

根据以上步骤即可以填充+写入的方式导出 Excel,以下是完整代码:

import cn.hutool.core.io.resource.ResourceUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.sevnce.pop.customer.handler.CustomTemplateSheetStrategy;
import lombok.Data;
import org.junit.jupiter.api.Test;
import java.io.InputStream;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 测试用例
 *
 * @author 天航星
 * @date 2024-07-03 10:55
 */
public class TestDemo {

    @Data
    public class FillData {

        /**
         * 名称
         */
        private String name;

        /**
         * 数字
         */
        private double number;
    }

    @Data
    public class BusinessData {

        @ExcelProperty("字符串标题")
        private String string;

        @ExcelProperty("日期标题")
        private Date date;

        @ExcelProperty("数字标题")
        private Double doubleData;

        /**
         * 忽略这个字段
         */
        @ExcelIgnore
        private String ignore;
    }

    @Test
    public void test() {

        // 定义导出文件名
        String fileName = "测试.xlsx";
        // 获取模板文件
        InputStream templateFile = ResourceUtil.getResourceObj("templates/template.xlsx").getStream();
        // 定义填充页数据
        FillData fillData = new FillData();
        fillData.setName("张三");
        fillData.setNumber(5.2);
        // 定义业务页数据
        BusinessData businessData = new BusinessData();
        businessData.setString("测试");
        businessData.setDate(new Date());
        businessData.setDoubleData(1.0);
        List<BusinessData> businessDataList = Collections.singletonList(businessData);
        // 定义写入器
        ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFile).build();
        // 定义填充页 sheet
        WriteSheet writeSheet0 = EasyExcel.writerSheet().registerWriteHandler(new CustomTemplateSheetStrategy("动态命名sheet")).build();
        // 定义业务页 sheet
        WriteSheet writeSheet1 = EasyExcel.writerSheet("Sheet1").head(BusinessData.class).build();
        // 填充数据
        excelWriter.fill(fillData, writeSheet0);
        // 写入数据
        excelWriter.write(businessDataList, writeSheet1);
        // 关闭写入器
        excelWriter.finish();
    }
}

环境:

  • JDK:1.8.0_202
  • SpringBoot:2.7.17
  • EasyExcel:3.3.2
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
java根据模板导出pdf
转载<https://www.cnblogs.com/wangpeng00700/p/8418594.html(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fwangpeng00700%2Fp%2F8418594.html)\java根据模板
Wesley13 Wesley13
3年前
JAVA POI导出EXCEL 动态表头、多级表头、动态数据
导出Excel文件是业务中经常遇到的需求,以下是经常遇到的一些问题:1,导出中文文件名乱码Stringfilename"sheet1";response.setCharacterEncoding("UTF8");response.setContentType("application/octetstream");response.
Stella981 Stella981
3年前
Python format 用法详解
一、填充字符串1\.位置print("hello{0},thisis{1}.".format("world","python"))根据位置下标进行填充print("hello{},thisis{}.".format("world","python"))根据顺序自动填充
Stella981 Stella981
3年前
EasyExcel写入百万级数据到多sheet
EasyExcel是什么?快速、简单避免OOM的java处理Excel工具一、项目需求    从mongo库中查询数据,导出到excel文件中。但是动态导出的excel有多少列、列名是什么、有多少sheet页都需要动态获取。所以生成的excel也必须是动态生成,不能通过注解配置对象映射。而且写入的数据量,有可能达到100W级,使用传统的PO
Stella981 Stella981
3年前
EasyExcel简介
一Excel导入导出的应用场景1数据导入减轻录入工作量2数据导出统计信息归档3数据传输异构系统之间数据传输二EasyExcel简介1官方网站https://github.com/alibaba
Wesley13 Wesley13
3年前
UTF
  最近工作中需要将一些数据写入CSV文件中,并要使用Excel打开进行查看。测试时发现,导出的CSV文件用Excel打开后,中文字符全部是乱码。写入CSV文件的是UTF8编码的数据,文件在Linux中查看是没有问题的,在Windows上用Excel打开却有乱码。在查阅资料后发现,windows系统中文本文档的编码格式用BOM来指定,在文件的开头要写入字符
Stella981 Stella981
3年前
EasyExcel引入
好久没更了,都在有道云上面记录,没时间搬过来。easyexcel是最近项目做优化涉及的一个改善点吧。简介        导出是后台管理系统的常用功能,当数据量特别大的时候会内存溢出和卡顿页面,曾经自己封装过一个导出,POI百万级大数据量EXCEL导出采用了分批查询数据来避免内存溢出和使用SXSSFWorkbook方式缓存数据到文件上以解决
Stella981 Stella981
3年前
SpringBoot整合easyexcel实现Excel的导出
在一般不管大的或者小的系统中,各家的产品都一样,闲的无聊的时候都喜欢让我们这些程序员导出一些数据出来供他观赏,非说这是必须需求,非做不可,那么我们就只能苦逼的哼哧哼哧的写bug喽。之前使用POI导出excel需要自己先去创建excel文件,还要创建sheet,写表头,操作起来确实很麻烦,针对产品这种随心而欲的需求我们能不能快速的做完这样一个产品看起来挺简
Stella981 Stella981
3年前
Excel导出(适合初学者)
这里有两个版本\,第一个是我自己写的一个导入导出,另一个是不知道复制哪位大佬的,这已经不重要了,重点是自己看懂会用就可以Excel导出步骤:生成Excel文档新建Sheet新建Row新建Cell单元格写单元格数据版本一:这个适合刚开始学习Excel导出,代码简洁易懂package
Easter79 Easter79
3年前
SpringBoot整合easyexcel实现Excel的导出
在一般不管大的或者小的系统中,各家的产品都一样,闲的无聊的时候都喜欢让我们这些程序员导出一些数据出来供他观赏,非说这是必须需求,非做不可,那么我们就只能苦逼的哼哧哼哧的写bug喽。之前使用POI导出excel需要自己先去创建excel文件,还要创建sheet,写表头,操作起来确实很麻烦,针对产品这种随心而欲的需求我们能不能快速的做完这样一个产品看起来挺简
天航星
天航星
Lv1
天河有尽后为涯 星海无边前作岸
文章
8
粉丝
0
获赞
0