首页 > 其他分享 >EasyExcel 导出,导入自定义表头,表头更名

EasyExcel 导出,导入自定义表头,表头更名

时间:2024-06-05 10:47:55浏览次数:14  
标签:head headMap 自定义 EasyExcel 表头 private class

一、场景

在同一个场景中导出的Excel 中的表头字段(title)存在不同的名称 (表头、标题),在导出时,要存在差异化,并且导出的模版要同时可以导出

二、方案

  • 在导出时,添加自定义的handler,对导出的字段进行处理,更换导出的字段名称
  • 在导入时,自定义需要获取的表头名称

三、代码示例

测试类

import java.util.*;

@Slf4j
class CustomCellWriteHandlerTest {

   @Data
   public static class DemoData {
       @ExcelProperty(value = "first")
       private String oldHeader1;
       @ExcelProperty(value = "second")
       private String oldHeader2;
       @ExcelProperty(value = "测试3")
       private String oldHeader3;
       @ExcelProperty(value = "测试4")
       private String oldHeader4;
   }

   private List<DemoData> demos = new ArrayList<>();

   private Map<String, String> headMap = new HashMap<>();
   private Map<String, String> readMap = new HashMap<>(); // 不需要考虑,测试数据
   private List<List<String>> head = new ArrayList<>(); // 自定义的导入请求头

   @BeforeEach
   public void init() {
       for (int i = 0; i < 3; i++) {
           DemoData demoData = new DemoData();
           demoData.setOldHeader1("first" + i);
           demoData.setOldHeader2("second" + i);
           demoData.setOldHeader3("测试3+" + i);
           demoData.setOldHeader4("测试4+" + i);
           demos.add(demoData);
       }

       headMap.put("oldHeader1", "firstChange");
       headMap.put("second", "secondChange");

       readMap.put("firstChange", "first");
       readMap.put("secondChange", "second");


       head.add(Collections.singletonList("firstChange"));
       head.add(Collections.singletonList("secondChange"));
       head.add(Collections.singletonList("测试3"));
//        head.add(Collections.singletonList("测试6"));
       head.add(Collections.singletonList("测试4"));
   }


   @Test
   void testCustomizeExportEasyExcel() {
       String filename = "output.xlsx";
       EasyExcel.write(filename, DemoData.class)
               .registerWriteHandler(new CustomCellWriteHandler(headMap))
               .sheet("Sheet1")
               .doWrite(demos);
   }

   @Test
   void testCustomizeImportListener() {
       String filename = "output.xlsx";
       CustomReadListener<DemoData> demoDataCustomReadListener = new CustomReadListener<>(readMap); // 使用常规的Listener就可以了,此处是测试用,可忽略
       EasyExcel.read(filename, DemoData.class, demoDataCustomReadListener)
               .head(head)
               .sheet().doRead();
       List<DemoData> list = demoDataCustomReadListener.getList();
       System.out.println(list);
   }
}

自定义的handler CustomCellWriteHandler


@AllArgsConstructor
@NoArgsConstructor
public class CustomCellWriteHandler implements CellWriteHandler {

   private Map<String, String> headMap = new HashMap<>(); // 传入需要进行表头替换的Map,以便在解析表头时可以进行替换
   @Override
   public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {

   }

   @Override
   public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

   }

   @Override
   public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

   }

   @Override
   public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
       // 如果是表头,可以更改表头的内容
       if (Boolean.TRUE.equals(isHead)) {
           if (headMap.containsKey(head.getFieldName())) {
               cell.setCellValue(headMap.get(head.getFieldName()));
           }
           if (headMap.containsKey(head.getHeadNameList().get(0))) {
               cell.setCellValue(headMap.get(head.getHeadNameList().get(0)));
           }
       }
   }
}

注意的点

- 在进行导入时
EasyExcel.read(filename, DemoData.class, demoDataCustomReadListener)
               .head(head)
               .sheet().doRead();
   			这段代码中head是我们自定义导入的表头,在read中还加上了DemoData.class 这个表头类
   			因为不加入表头类,读取的表头就是按照顺序读取的,对数据的表头顺序一致有非常高的要求
   			
- 使用DemoData.class 还有一个就是,在进行导入处理时,会根据表头,对导入的数据进行匹配,
这样在后续处理时数据会更干净,同时能够直接将结果数据,映射为我们想要的class类

- 在read中添加class 后,同时使用head 进行自定义表头,需要满足head的长度不大于class字段的总长度,
不然会在读取表头的时候就出现null的表头字段,会在数据写入时,抛出空指针异常

标签:head,headMap,自定义,EasyExcel,表头,private,class
From: https://www.cnblogs.com/herebug/p/18232503

相关文章

  • springboot如何去自定义端口
    springboot如何去自定义端口https://blog.csdn.net/m0_63102097/article/details/138584857 1.在application.properties文件中设置端口号:server.port=80802.在application.yml文件中设置端口号:   server:     port:80803.通过命令行参数指定端口号启动应用程序:jav......
  • nuxt3中环境变量env不生效(process.env打印不出来自定义变量)
    按理环境变量env配置比较简单。网上一搜一堆。但是我按网上配置后都打印不出来(process.env)后来发现在nuxt.config.ts里面配置的runtimeConfig会自动对应到环境变量上运行时配置在官网的迁移里面写了。猜测可能是我版本比较高(3.11.2)。网上配置失效环境变量配置//.env.deve......
  • 使用自定义数据训练 YOLOv10
    节前,我们星球组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、参加社招和校招面试的同学。针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。合集:持续火爆!!!《AIGC面试宝典》已圈粉无......
  • Maven实战: 创建自定义archetype
    在手动创建SpringBoot应用中,我们讲过手动创建SpringBoot工程是比较麻烦的,尤其是公司内部不有自定义扩展和集成的情况下。利用Maven的archetype:generate能基于项目模板生成功能,自定义模板能让整个创建过程自动化,这样既能大大降低创建和集成SpringBoot的复杂度,还能做到公司内部......
  • vue3 实现自定义指令封装 --- 通俗易懂
    1、局部自定义指令1.1 在<scriptsetup>定义组件内的指令,任何以v开头的驼峰式命名的变量都可以被用作一个自定义指令<template><div><h3>使用自定义指令</h3><div>##########################start局部自定义指令</div><div>我是一个input:......
  • 数据库初识、介绍、SQL语句的由来(库、表、记录表头、表单)、SQL语句基础(注释以及修
    【一】数据库初识【1】文件存储(1)基于内存保存一开始做员工系统是基于列表或字典(内存)来存储数据(2)文件操作在Python指令中学习文件操作,将一些数据都保存到了本地的文本文件中。因为先前学习了如何搭建TCP的客户端和服务端并且在这之中TCP服务端作为存储服务,TCP客户......
  • View->Bitmap缩放到自定义ViewGroup的任意区域(RectF方式绘制Bitmap)
    XML文件<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent&quo......
  • 博客园文章目录生成脚本v1.0:支持多级、过滤空行、可指定文章、自定义插入点
    使用说明:1.设置-申请JS权限,等待审核通过2.设置-页脚HTML代码,代码贴进去保存 样式说明:1.默认目录插到文章顶部,可以加入<divid="toc"></div>标签自定义插入位置。2.H1和H2是加粗体,其他的是正常体。自定义功能:catalogue(true):给所有文章生成目录catalogue(false):只......
  • idea设置自定义快捷键定义代码块
    自定义代码块常用的psvm,main,sout等就是系统预设的。我们可以自己添加自定义的代码块,并制定调用该代码块的缩写,这样在使用该代码块时,就无需手动填写,只需通过代码块缩写触发idea的自动补全即可,位置:Setting–>Editor–>LiveTemplates如下图 为了区分方便管理,你可以添加自己的模板......
  • 自定义FlutterFragment的初始化路由没有生效
    问题:在自定义FlutterFragment的configureFlutterEngine方法中初始化页面路由发现一直是'/'原因:当configureFlutterEngine方法被调用时,Flutter已经完成了初始化并设置了默认的初始路由(通常是'/')。在Android项目中,FlutterFragment在onAttach方法中创建FlutterEngine。在......