• Java如何用EasyExcel插件对Excel进行数据导入和数据导出


    EasyExcel是一个阿里巴巴开源的excel处理框架,它以使用简单、节省内存著称。在解析Excel时,EasyExcel没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。这种一行一行的解析模式,使得EasyExcel在处理大数据量的Excel文件时,性能非常高效。

    本文先展示示例,后对EasyExcel做些简单介绍。

    一、EasyExcel的示例

    本文简单介绍EasyExcel的使用,使用xlsx文件读入。

    导入依赖

    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>easyexcelartifactId>
        <version>3.3.1version>
    dependency>
    <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
        <version>1.18.20version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    创建实体类

    @Data
    // 行高
    @HeadRowHeight(15)
    // 行宽
    @ColumnWidth(20)
    public class ExcelEntity implements Serializable {
    	
    	// @ExcelProperty(index = 0, value = "data")  列顺序
    	@ExcelProperty("用户姓名")
        private Integer name;
        
    	// @ExcelIgnore 不生效
        @ExcelProperty("用户工号")
        private String userId;
        
        @ExcelProperty("用户权限")
        private String role;
        
        @ExcelProperty("用户部门")
        private Integer part;
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    数据导入和导出

    实现一个数据例子:将Excel文件中(初始sheet)所有用户部门的人员进行分类,导出到原Excel的(调整sheet)。这个例子是读取一个Excel的sheet表格

    origin表格

    首先创建Excel表格,新建一个origin的sheet。新建一个Listener监听器,用于逐行读取数据。

    public class TestDataListener extends AnalysisEventListener<TestExcelEntity>{
    	
    	private List<TestExcelEntity> list = new ArrayList<>();
    
    	@Override
    	public void invoke(TestExcelEntity data, AnalysisContext context) {
    		System.out.println(data);  // 可以看到每一行的数据
    		list.add(data);
    	}
    
    	@Override
    	public void doAfterAllAnalysed(AnalysisContext context) {
    		System.out.println("WriterExcelEntity All data analyzed");
    	}
    
    	public List<TestExcelEntity> getList() {
    		return list;
    	}
    
    	public void setList(List<TestExcelEntity> list) {
    		this.list = list;
    	}	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    新建执行代码

    public class Test {
    	public static void main(String[] args) throws FileNotFoundException {
    
            // 利用监听器读取Excel文件
            TestDataListener testDataListener = new TestDataListener();
            String path = "C:\\Users\\Desktop\\test.xlsx";
            ExcelReader excelReader = EasyExcel.read(path, TestExcelEntity.class, testDataListener).build();
            ReadSheet esgReadSheet = EasyExcel.readSheet(0, "origin").build();
            excelReader.read(esgReadSheet);
            excelReader.finish();
            
            List<TestExcelEntity> greenBondEntities = testDataListener.getList();
    
            // 对获取到的数据进行排序,并转换成 Map 数据格式
            greenBondEntities.sort((u1, u2) -> u1.getRole().compareTo(u2.getRole()));
            Map<String, List<TestExcelEntity>> map =
                    greenBondEntities.stream().collect(Collectors.groupingBy(TestExcelEntity::getRole));
    
            // 根据业务操作
            List<TestExcelEntity> res = new ArrayList<>();
            map.entrySet().stream().forEach(entry -> {
                List<TestExcelEntity> list = entry.getValue();
                for (int i = 0; i < list.size(); i++) {
                    TestExcelEntity test = new TestExcelEntity();
                    if (i == 0) {
                        test.setRole(list.get(i).getRole());
                        test.setName(list.get(i).getName());
                        test.setUserId(list.get(i).getUserId());
                        test.setPart(list.get(i).getPart());
                    } else {
                        test.setName(list.get(i).getName());
                        test.setUserId(list.get(i).getUserId());
                        test.setPart(list.get(i).getPart());
                    }
                    res.add(test);
                }
            });
    
            EasyExcel.write("C:\\Users\\Desktop\\res.xlsx", TestExcelEntity.class)
                    .sheet(0,"update")
                    .doWrite(res);
        }
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    导出后的Excel如下图所示:
    update表格
    如果想要读取多个sheet表格:

    // 读取多条sheet
    @Test
    public void read() {
    	TestDataListener testDataListener = new TestDataListener();
    	String path = "C:\\Users\\Desktop\\test.xlsx";
    	ExcelReader excelReader = EasyExcel.read(path, TestExcelEntity.class, testDataListener).build();
        List<ReadSheet> sheets = excelReader.excelExecutor().sheetList();
    
        for (ReadSheet sheet : sheets) {
            String sheetName = sheet.getSheetName();
            System.out.println(sheetName);
            ReadSheet readSheet = EasyExcel.readSheet(sheetName).build();
            excelReader.read(readSheet);
        }
    
        excelReader.finish();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    二、EasyExcel的作用

    • 高效性能 :EasyExcel在处理大型Excel文件时具有出色的性能。它采用了基于流的读写方式,能够快速处理大量数据,显著提高了读写效率。同时,EasyExcel针对大数据量处理进行了优化,提供了 分批读写内存优化 等策略,保证了处理大型Excel文件时的 高效性稳定性
    • 简洁易用 :EasyExcel提供了简洁而强大的API,可以轻松地读取、写入和操作Excel文件,减少了繁琐的操作和代码量。
    • 低内存占用 :与传统的Excel文件读取方式相比,EasyExcel显著降低了内存占用。它采用基于 事件驱动 的模型,通过 回调函数 来处理每一行数据,而不是一次性将整个文件读入内存。这种流式的处理方式极大地节省了内存资源,使得处理大文件时更加稳定可靠。
    • 支持多种格式和复杂操作 :EasyExcel支持多种Excel文件格式,包括 .xls.xlsx.xlsm 等,使得它在处理不同版本的Excel文件时具有更大的灵活性。同时,它还支持处理复杂的Excel表格,包括合并单元格、样式、图表等,满足各种复杂场景的需求。
    • 强大的扩展性 :EasyExcel提供了丰富的扩展接口,开发者可以根据自己的需求轻松定制Excel文件的读写操作,满足各种复杂场景的需求。比如支持自定义转换器,使得数据格式的处理更为灵活。

    EasyExcel在处理Excel文件时具有高效、简洁、低内存占用、支持多种格式和复杂操作以及强大的扩展性等优点,这使得它在 大数据量Excel操作场景下成为一个非常不错的选择。然而,也需要注意到,虽然EasyExcel有很多优点,但它可能还需要额外引入依赖包,这可能会增加项目的复杂度。因此,在选择是否使用EasyExcel时,需要综合考虑项目的具体需求和实际情况。

    三、EasyExcel的注解

    • @ExcelProperty :这是用于指定Java对象中的字段与Excel表格中的 列的映射关系 的注解。通过设置该注解的 value 属性,可以指定列名。设置 index 属性,可以指定列名的序号,从而实现字段与列的对应关系。
    • @ExcelIgnore :这个注解用于指定Java对象中的字段在Excel中的读写操作中被忽略。当需要在Excel文件中忽略某个字段时,可以在该字段上添加此注解。
    • @ContentFontStyle :用于设置字体样式。
    • @ContentLoopMerge :用于合并单元格。
    • @ContentRowHeight :用于设置 行高
    • @ContentStyle :用于设置内容格式。
    • @HeadFontStyle :用于定制标题字体格式。
    • @HeadRowHeight :用于设置 标题行行高
    • @HeadStyle :用于设置标题样式。
    • @ColumnWidth :用于设置 列宽
    • @DateTimeFormat :日期格式化。
    • @NumberFormat :数字格式化。
  • 相关阅读:
    【Linux】第十四章 多线程(生产者消费者模型+POSIX信号量)
    汽车标定技术(五)--基于模型开发如何生成完整的A2L文件(1)
    ubuntu22.04 ssh 连不上
    【ubuntu】修改系统及硬件时间
    前端开箱即用的中后台管理模版,建议收藏
    思维,序列和
    Activiti工作流引擎学习笔记
    【腾讯云云上实验室-向量数据库】TAI时代的数据枢纽-向量数据库 VectorDB
    第十章 设置结构化日志记录(二)
    【Redis(10)】Redis单机性能调优思路
  • 原文地址:https://blog.csdn.net/Reggie97/article/details/137779748