easyexcel使用模板填充excel坑点总结

news2025/4/21 21:47:25

1.单层map设置值是{属性},那使用两层map进行设置值,是不是可以使用{属性.属性},以为取出map里字段只用{属性}就可以设置值,那再加个.就可以从里边map取出对应属性,没有两层map写法
填充得到的文件打开报错 was empty (zero bytes long)

Map<String, Map<String, String>> map = new HashMap<>();
    Map<String, String> map1 = new HashMap<>();
    map1.put("name", "张三");
    map1.put("age", "18");
    HashMap<String, String> map2 = new HashMap<>();
    map2.put("name", "李四");
    map2.put("age", "19");
    map.put("obj1", map1);
    map.put("obj2", map2);
    ExcelWriter excelWriter = EasyExcel.write(EXCEL_OUPUT_FILE_PATH)
        .withTemplate(TEMPLATE_FILE_PATH).build(); // 构建ExcelWriter对象 整个文件对象
    WriteSheet sheet1 = EasyExcel.writerSheet("Sheet1").build(); // 构建sheet对象
    excelWriter.fill(map, sheet1); //将操作的sheet和数据填充到ExcelWriter对象中

2.尝试使用map包对象写法,想着反正是.,那里面是对象就可以使用了吧,填充后文件还是报文件 was empty (zero bytes long)

public static final String EXCEL_OUPUT_FILE_PATH = "templateOutput/template1Output.xlsx";
  public static final String TEMPLATE_FILE_PATH = "excelTemplate/template1.xlsx";

  static class Person {

    public String name;
    public String age;
  }

  public static void main(String[] args) {
    Map<String, Person> map = new HashMap<>();
    Map<String, String> map1 = new HashMap<>();
    Person person = new Person();
    person.name = "张三";
    person.age = "18";
    map1.put("name", "张三");
    map1.put("age", "18");
    HashMap<String, String> map2 = new HashMap<>();
    Person person1 = new Person();
    person1.name = "李四";
    person1.age = "19";
    map2.put("name", "李四");
    map2.put("age", "19");
    map.put("obj1", person);
    map.put("obj2", person1);
    ExcelWriter excelWriter = EasyExcel.write(EXCEL_OUPUT_FILE_PATH)
        .withTemplate(TEMPLATE_FILE_PATH).build(); // 构建ExcelWriter对象 整个文件对象
    WriteSheet sheet1 = EasyExcel.writerSheet("Sheet1").build(); // 构建sheet对象
    excelWriter.fill(map, sheet1); //将操作的sheet和数据填充到ExcelWriter对象中

  }

3.使用创建EasyWriter和WriteSheet对象,直接使用
EasyExcel.write(filePath).withTemplate(excelTemplate).sheet(0).doFill(excelDataMap);

EasyExcel.write(filePath).withTemplate(excelTemplate).sheet(1).doFill(excelDataMap);

对两个sheet进行填充,只有最后一个sheet设置了值。
应该创建EasyWriter和WriterSheet对象进行设置值

正确写法:

Map<String, String> excelDataMap = new HashMap();
ExcelWriter excelWriter = EasyExcel.write(filePath).withTemplate(asInputStream).build();
WriteSheet sheet1 = EasyExcel.writerSheet(0).build();
WriteSheet sheet2 = EasyExcel.writerSheet(0).build();
excelWriter.fill(sheet1, excelDataMap);
excelWriter.fill(sheet2, excelDataMap);
excelWriter.finish();

4.使用,没有告诉excelwriter对象,结束导入,导致生成的excel文件打不开,报was empty (zero bytes long)。应该在写入完成后调用

excelWriter.finish();

完整用法:

Map<String, String> excelDataMap = new HashMap();
ExcelWriter excelWriter = EasyExcel.write(filePath).withTemplate(asInputStream).build();
WriteSheet sheet1 = EasyExcel.writerSheet(0).build();
WriteSheet sheet2 = EasyExcel.writerSheet(0).build();
excelWriter.fill(sheet1, excelDataMap);
excelWriter.fill(sheet2, excelDataMap);
excelWriter.finish();

5.由于我需要将模版文件的某些sheet复制多个形成新的模版,但又不想多产生一个模版文件,我将输出文件和文件和模版文件都设置成一个

ExcelWriter excelWriter = EasyExcel.write(TEMPLATE_FILE_PATH).withTemplate(TEMPLATE_FILE_PATH)
        .build();

报错Exception in thread "main" com.alibaba.excel.exception.ExcelGenerateException: Create workbook failure
    at com.alibaba.excel.context.WriteContextImpl.<init>(WriteContextImpl.java:98)
    at com.alibaba.excel.write.ExcelBuilderImpl.<init>(ExcelBuilderImpl.java:36)
    at com.alibaba.excel.ExcelWriter.<init>(ExcelWriter.java:36)
    at com.alibaba.excel.write.builder.ExcelWriterBuilder.build(ExcelWriterBuilder.java:114)
    at org.example.demotask.util.EasyexcelUtils.main(EasyexcelUtils.java:60)
Caused by: org.apache.poi.EmptyFileException: The supplied file was empty (zero bytes long)

复制模版里的sheet形成新的模版赋值导出写法:

Map<String, String> map = new HashMap();
      Map<String, Map<String, String>> lotMap = new HashMap();
      //获取的模板文件位置
      String excelTemplate = "path";
      FileInputStream fileInputStream = new FileInputStream(excelTemplate);
      InputStream templateStream = fileInputStream;
      Workbook workbook = WorkbookFactory.create(templateStream);
      List<String> fatherSheet = Lists.newArrayList("Sheet1");
      ArrayList<String> lotNames = new ArrayList<>(lotMap.keySet());
       //复制sheet
      for (String cloneSheet : fatherSheet) {
        for (String lotName : lotNames) {
            //根据要复制的sheet名拿到要复制的sheet
          Sheet templateSheet = workbook.getSheet(cloneSheet);
          Sheet newSheet = workbook.cloneSheet(workbook.getSheetIndex(templateSheet));
          int newSheetIndex = workbook.getSheetIndex(newSheet);  // 获取新克隆的 sheet 索引
            //设置复制的sheet名
          workbook.setSheetName(newSheetIndex, cloneSheet + "(" + lotName + ")");
        }
      }
       //新建内存输出流,作为新的模版文件输出
      ByteArrayOutputStream ops = new ByteArrayOutputStream();
      workbook.write(ops);
      ops.flush();
      byte[] byteArray = ops.toByteArray();
      ops.close();
      workbook.close();
      //使用新的文件的字节流作为模板文件输入
      InputStream asInputStream = new ByteArrayInputStream(byteArray);
      // 原文件流后续已不使用,此处关闭
      templateStream.close();
      ops.close();
      ExcelWriter excelWriter = EasyExcel.write("D:\\newnewnewFormat111.xlsx").withTemplate(asInputStream).build();
      WriteSheet mainSheet = EasyExcel.writerSheet("Sheet1").build();
      excelWriter.fill(map, mainSheet);
      for (String lotName : lotNames) {
        WriteSheet sheet = EasyExcel.writerSheet("Sheet1(" + lotName + ")").build();
        excelWriter.fill(lotMap.get(lotName), sheet);
      }
       //重要 使用excelWriter写入完一定要调用finish方法,不然文件打不开
      excelWriter.finish();

总结:
1.使用Map类型进行填充只有能普通类型
2.模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
3. {} 代表普通变量 {.} 代表是list的变量 {前缀.} 前缀可以区分不同的list

WriteSheet writeSheet = EasyExcel.writerSheet().build();
              List<String> list1 = new ArrayList<>();
              list1.add("张三");
              list1.add("李四");
              ArrayList<String> list2 = new ArrayList<>();
              list2.add("11");
              list2.add("22");
               //设置列表展开方向,默认垂直
            FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
            // 如果有多个list 模板上必须有{前缀.} 这里的前缀就是 data1,然后多个list必须用 FillWrapper包裹
            excelWriter.fill(new FillWrapper("data1", list1), fillConfig, writeSheet);
            excelWriter.fill(new FillWrapper("data2", list1), writeSheet);

4.使用ExcelWriter进行sheet写入时完成时,最好调用ExcelWriter对象的finish()方法,不然可能出现文件损坏的情况

5.模版文件路径不要跟输出文件路径,如果不想输出临时的模版文件,可以将产生新的写入内存流,然后将内存流的字节数据写入字节输入流作为模板输入
 

    String excelTemplate = "path";
      FileInputStream fileInputStream = new FileInputStream(excelTemplate);
      InputStream templateStream = fileInputStream;
      Workbook workbook = WorkbookFactory.create(templateStream);
      List<String> fatherSheet = Lists.newArrayList("Sheet1");
      ArrayList<String> lotNames = new ArrayList<>(lotMap.keySet());
       //复制sheet
      for (String cloneSheet : fatherSheet) {
        for (String lotName : lotNames) {
            //根据要复制的sheet名拿到要复制的sheet
          Sheet templateSheet = workbook.getSheet(cloneSheet);
          Sheet newSheet = workbook.cloneSheet(workbook.getSheetIndex(templateSheet));
          int newSheetIndex = workbook.getSheetIndex(newSheet);  // 获取新克隆的 sheet 索引
            //设置复制的sheet名
          workbook.setSheetName(newSheetIndex, cloneSheet + "(" + lotName + ")");
        }
      }
       //新建内存输出流,作为新的模版文件输出
      ByteArrayOutputStream ops = new ByteArrayOutputStream();
      workbook.write(ops);
      ops.flush();
      byte[] byteArray = ops.toByteArray();
      ops.close();
      workbook.close();
      //使用新的文件的字节流作为模板文件输入
      InputStream asInputStream = new ByteArrayInputStream(byteArray);
      // 原文件流后续已不使用,此处关闭
      templateStream.close();
      ops.close();
      ExcelWriter excelWriter = EasyExcel.write("D:\\newnewnewFormat111.xlsx").withTemplate(asInputStream).build();

6.使用EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(map);进行填充会出现只有最后一个sheet填充成功,如果想对多个sheet进行填充,要使用ExcelWriter对象操作数据和sheet对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2339684.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C# LINQ基础知识

简介 LINQ(Language Integrated Query)&#xff0c;语言集成查询&#xff0c;是一系列直接将查询功能集成到 C# 语言的技术统称。使用LINQ表达式可以对数据集合进行过滤、排序、分组、聚合、串联等操作。 例子&#xff1a; public class Person {public int Id;public string…

GCoNet+:更强大的团队协作 Co-Salient 目标检测器 2023 GCoNet+(翻译)

摘要 摘要&#xff1a;本文提出了一种新颖的端到端群体协作学习网络&#xff0c;名为GCoNet&#xff0c;它能够高效&#xff08;每秒250帧&#xff09;且有效地识别自然场景中的共同显著目标。所提出的GCoNet通过基于以下两个关键准则挖掘一致性表示&#xff0c;实现了共同显著…

QT常见输入类控件及其属性

Line Edit QLineEdit用来表示单行输入框&#xff0c;可以输入一段文本&#xff0c;但是不能换行 核心属性&#xff1a; 核心信号 信号 说明 void cursorPositionChanged(int old,int new) 当鼠标移动时发出此型号&#xff0c;old为先前位置&#xff0c;new为新位置 void …

Few-shot medical image segmentation with high-fidelity prototypes 论文总结

题目&#xff1a;Few-shot medical image segmentation with high-fidelity prototypes&#xff08;高精确原型&#xff09; 论文&#xff1a;Few-shot medical image segmentation with high-fidelity prototypes - ScienceDirect 源码&#xff1a;https://github.com/tntek/D…

如何使用Node-RED采集西门子PLC数据通过MQTT协议实现数据交互并WEB组态显示

需求概述 本章节主要实现一个流程&#xff1a;使用纵横智控的EG网关通过Node-red&#xff08;可视化编程&#xff09;采集PLC数据&#xff0c;并通过MQTT协议和VISION&#xff08;WEB组态&#xff09;实现数据交互。 以采集西门子PLC为例&#xff0c;要采集的PLC的IP、端口和点…

【cocos creator 3.x】速通3d模型导入, 模型创建,阴影,材质使用,模型贴图绑定

1、右键创建平面&#xff0c;立方体 2、点击场景根节点&#xff0c;shadows勾选enabled3、点击灯光&#xff0c;shadow enabled勾选 4、点击模型&#xff0c;勾选接收阴影&#xff0c;投射阴影&#xff08;按照需要勾选&#xff09; 5、材质创建 6、选中节点&#xff0c;找…

驱动开发硬核特训 · Day 15:电源管理核心知识与实战解析

在嵌入式系统中&#xff0c;电源管理&#xff08;Power Management&#xff09;并不是“可选项”&#xff0c;而是实际部署中影响系统稳定性、功耗、安全性的重要一环。今天我们将以 Linux 电源管理框架 为基础&#xff0c;从理论结构、内核架构&#xff0c;再到典型驱动实战&a…

【零基础】基于DeepSeek-R1与Qwen2.5Max的行业洞察自动化平台

自动生成行业报告,通过调用两个不同的大模型(DeepSeek 和 Qwen),完成从行业趋势分析到结构化报告生成的全过程。 完整代码:https://mp.weixin.qq.com/s/6pHi_aIDBcJKw1U61n1uUg 🧠 1. 整体目的与功能 该脚本实现了一个名为 ReportGenerator 的类,用于: 调用 DeepSe…

C 语言联合与枚举:自定义类型的核心解析

目录 1.联合体 1.1联合体的声明与创建 1.2联合体在内存中的存储 1.3相同成员的结构体与内存比较 1.4联合体内存空间大小的计算 1.5联合体的应用 2.枚举类型 2.1枚举变量的声明 2.2枚举变量的优点 2.3枚举的使用 上篇博客中&#xff0c;我们通过学习了解了C语言中一种自…

基于Canal+Spring Boot+Kafka的MySQL数据变更实时监听实战指南

前期知识背景 binlog 什么是binlog 它记录了所有的DDL和DML(除 了数据查询语句)语句&#xff0c;以事件形式记录&#xff0c;还包含语句所执行的消耗的时间&#xff0c;MySQL 的二进制日志是事务安全型的。一般来说开启二进制日志大概会有1%的性能损耗。 binlog分类 MySQL Bi…

MySQL运维三部曲初级篇:从零开始打造稳定高效的数据库环境

文章目录 一、服务器选型——给数据库一个舒适的家二、系统调优——打造高性能跑道三、MySQL配置——让数据库火力全开四、监控体系——数据库的体检中心五、备份恢复——数据安全的最后防线六、主从复制——数据同步的艺术七、安全加固——守护数据长城 引言&#xff1a;从小白…

【MySQL】MySQL的基础语法及其语句的介绍

1、基础语法 mysql -h【主机名】 -u【用户名】 -p //登录MySQL exit或quit; //退出MySQL show database; //查看MySQL下的所有数据库 use 【数据库名】; //进入数据库 show tables; //查看数据库下的所有表名 *MySQL的启动和关闭 &am…

【计算机视觉】三维视觉项目 - Colmap二维图像重建三维场景

COLMAP 3D重建 项目概述项目功能项目运行方式1. 环境准备2. 编译 COLMAP3. 数据准备4. 运行 COLMAP 常见问题及解决方法1. **编译问题**2. **运行问题**3. **数据问题** 项目实战建议项目参考文献 项目概述 COLMAP 是一个开源的三维重建软件&#xff0c;专注于 Structure-from…

ALSA架构学习2(驱动MAX98357A)

1 前言和环境 之前其实写过两篇&#xff0c;一篇是讲ALSA&#xff0c;一篇是I2S。 ALSA架构学习1&#xff08;框架&#xff09;_alsa框架学习-CSDN博客 总线学习5--I2S_max98357接喇叭教程-CSDN博客 在ALSA那篇的结尾&#xff0c;也提了几个小练习。比如&#xff1a; ### 4…

数据结构*集合框架顺序表-ArrayList

集合框架 常见的集合框架 什么是顺序表 顺序表是一种线性表数据结构&#xff0c;它借助一组连续的存储单元来依次存储线性表中的数据元素。一般情况下采用数组存储。 在数组上完成数据的增删查改。 自定义简易版的顺序表 代码展示&#xff1a; public interface IArray…

VMware Workstation 保姆级 Linux(CentOS) 创建教程(附 iso)

文章目录 一、下载二、创建 一、下载 CentOS-7.9-x86_64-DVD-2009.iso 二、创建 VMware Workstation 保姆级安装教程(附安装包) VMware Workstation 保姆级安装教程(附安装包) VMware Workstation 保姆级安装教程(附安装包)

软考-信息系统项目管理师-2 信息技术发展

总结思维导图 云计算(掌握) (3)多租户和访问控制管理访问控制管理是云计算应用的核心问题之一云计算访问控制的研究主要集中在云计算访问控制模型、基于ABE密码体制的云计算访问控制、云中多租户及虚拟化访问控制研究云中多租户及虚拟化访问控制是云计算的典型特征。 大数据(…

Spring Boot JPA 开发之Not an entity血案

项目状况介绍 项目环境 JDK 21Spring Boot 3.4.3Hibernate: 6.6.13.Final项目描述 因为是微服务架构,项目层级如下 project-parent project-com project-A … project-X 其中: project-parent定义依赖库的版本project-com 定义了一些公用的方法和配置,包括持久层的配置。…

HTMLCSS实现轮播图效果

这段代码实现了一个具有自动轮播、手动切换功能的图片轮播图&#xff0c;并且配有指示器&#xff08;小圆点&#xff09;来显示当前图片位置。轮播图可通过左右箭头按钮进行手动切换&#xff0c;也能自动定时切换&#xff0c;当鼠标悬停在轮播图上时&#xff0c;自动轮播会暂停…

嵌入式学习——opencv图像库编程

环境配置 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和图像处理库&#xff0c;广泛用于各种计算机视觉任务&#xff0c;如图像处理、视频分析、人脸识别、物体检测、机器学习等。它提供了丰富的函数和工具&#xff0c;用于处理…