编程语言
739
使用 EasyExcel 导出 Excel 时,有时会遇到如下情况:
- 既要根据模板填充某些 sheet
- 又要根据业务写入某些 sheet
EasyExcel 官方没有提供这样的示例,经过自己的研究和实验,得到了如下步骤:
-
定义导出文件名
String fileName = "测试.xlsx"; -
获取模板文件
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> -
定义填充页数据
@Data public class FillData { private String name; private double number; }FillData fillData = new FillData(); fillData.setName("张三"); fillData.setNumber(5.2); -
定义业务页数据
@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); -
定义写入器
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFile).build(); -
定义填充页 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); } }
-
定义业务页 sheet
WriteSheet writeSheet1 = EasyExcel.writerSheet("Sheet1").head(BusinessData.class).build(); -
填充数据
excelWriter.fill(fillData, writeSheet0);注意:这里一定要传入对象,不能传入列表,否则填充的内容会变为空白。
-
写入数据
excelWriter.write(businessDataList, writeSheet1); -
关闭写入器
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
广告