EasyExcel简单实例

news2024/12/23 15:04:50

EasyExcel简单实例

  • 准备工作
  • 场景一:读取 Student 表
    • 需求1:简单读取
    • 需求2:读取到异常信息时不中断
    • 需求3:读取所有的sheet工作表
    • 需求4:读取指定的sheet工作表
    • 需求5:从指定的行开始读取
  • 场景二:写入 Student 表
    • 需求1:简单写入
    • 需求2:写入指定列
    • 需求3:指定写入列的名称和顺序
    • 需求4:写入多级表头
    • 需求5:重复写入
    • 需求6:往多个工作簿写入相同数据
    • 需求7:往多个工作簿写入不同数据

准备工作

导入easyExcel依赖,注意版本:

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.1</version>
        </dependency>

场景一:读取 Student 表

需求1:简单读取

源表:
在这里插入图片描述

1. 编写实体类
可以使用 @ExcelProperty 指定数据封装为实体类对象的规则,后面可以跟index 和 列名(二选一);
若不加注解则按照默认封装规则: ①根据 Excel 列与实体类属性的顺序②根据 Excel 列的单元格式与对象字段类型匹配。

@Data
public class Student {
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("年级")
    private String grade;
    @ExcelProperty("年龄")
    private int age;
}

2. 监听器
invoke():每读取一行就执行的方法,每一行数据会被封装成一个 student 对象(invoke方法的第一个参数);
doAfterAllAnalysed():读取结束后执行的方法;

class studentListener implements ReadListener<Student> {
    int i=1;

    @Override
    public void invoke(Student student, AnalysisContext context) {
        System.out.println("读取到第 "+(i++)+" 行:"+student);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        System.out.println("\nxlsx文件读取结束");
    }
}

3. 测试类
read():读取workbook工作簿,传入文件路径、实体类、监听器;
sheet():选定读取的工作表,默认读取第一个;
doRead():执行读操作;

public class easyExcelTest {
    @Test
    public void readTest() {
        String filePath = "C:\\Users\\liziq\\Desktop\\student.xlsx";
        EasyExcel.read(filePath,
                        Student.class,
                        new studentListener()).
                sheet().
                doRead();
    }
}

打印效果:
在这里插入图片描述

需求2:读取到异常信息时不中断

源表:
当出现了不符合数据类型的数据时,希望不中断读取
在这里插入图片描述
1. 实体类:
不变;
2. 监听器:
只需要调整监听器,在监听器加入 onException()方法;

class studentListener implements ReadListener<Student> {
    int i = 1;

    @Override
    public void invoke(Student student, AnalysisContext context) {
        System.out.println("读取到第 " + (i++) + " 行:" + student);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        System.out.println("\nxlsx文件读取结束");
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        System.out.println("读取异常:"+exception);
    }
}

3. 测试类:
不变;

打印效果:
异常数据被打印,且不中断读取;
在这里插入图片描述

需求3:读取所有的sheet工作表

源表:
此时多个sheet都有数据;
在这里插入图片描述

1. 实体类
不变;
2. 监听器
不变;
3. 测试类
将sheet().doRead改为 doReadAll()

public class easyExcelTest {
    @Test
    public void readTest() {
        String filePath = "C:\\Users\\liziq\\Desktop\\student.xlsx";
        EasyExcel.read(filePath,
                        Student.class,
                        new studentListener()).
                doReadAll();
    }
}

效果:
读取到了两个sheet的数据:
在这里插入图片描述

需求4:读取指定的sheet工作表

源表:
此时多个sheet都有数据;
在这里插入图片描述

1. 实体类
不变;
2. 监听器
不变;
3. 测试类
在sheet()中传递指定sheet的index索引或者名称即可:

public class easyExcelTest {
    @Test
    public void readTest() {
        String filePath = "C:\\Users\\liziq\\Desktop\\student.xlsx";
        EasyExcel.read(filePath,
                        Student.class,
                        new studentListener()).
                sheet("Sheet2").
                doRead();

        EasyExcel.read(filePath,
                        Student.class,
                        new studentListener()).
                sheet("Sheet1").
                doRead();
    }
}

效果:
此时先指定读取sheet2,再读取sheet1;
在这里插入图片描述

需求5:从指定的行开始读取

源表:
假设此时有多行表头,内容需要从第3行开始读取;
在这里插入图片描述

1. 实体类
不变;
2. 监听器
不变;
3. 测试类
使用 headRowNumber(),参数中填写开始读取的行数;(默认从第2行开始读取,即headRowNumber()默认参数是索引1);
此时读取的内容要从第3行开始,索引为2,所以填入headRowNumber()的参数为2!

public class easyExcelTest {
    @Test
    public void readTest() {
        String filePath = "C:\\Users\\liziq\\Desktop\\student.xlsx";
        EasyExcel.read(filePath,
                        Student.class,
                        new studentListener()).
                sheet("Sheet1").
                headRowNumber(2).
                doRead();
    }
}

效果:
在这里插入图片描述

场景二:写入 Student 表

需求1:简单写入

1. 实体类
需要比读取excel多添加实体类的构造函数;

@Data
public class Student {
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("年级")
    private String grade;
    @ExcelProperty("年龄")
    private int age;
    
    public Student(){}

    public Student(String name, String grade, int age) {
        this.name = name;
        this.grade = grade;
        this.age = age;
    }
}

2. 模拟建数据的类
将每一行数据封装为Student对象,并放入一个List集合中;

class CreateData{
    public static List<Student> create(){
        List<Student> datas = Arrays.asList(
                new Student("张三","一年级",23),
                new Student("里斯","一年级",19),
                new Student("王五","一年级",22),
                new Student("赵六","一年级",21)
        );
        return datas;
    }
}

3. 测试类
写的时候会自动将实体类的属性作为excel表的表头;
sheet()的参数为写入的工作表;
doWrite()的参数为要写入的数据,要求格式为Collection集合类型;

  • 写法1
public class easyExcelTest {
    @Test
    public void writeTest() {
        String filePath = "C:\\Users\\liziq\\Desktop\\student.xlsx";
        EasyExcel.write(filePath,
                        Student.class).
                sheet("学生表1").
                doWrite(CreateData.create()); // doWrite()的参数为 Collection 集合
    }
  • 写法2:
    适合写多个sheet;
public class easyExcelTest {
    @Test
    public void writeTest() {
        String filePath = "C:\\Users\\liziq\\Desktop\\student.xlsx";
        try(ExcelWriter excelWriter=EasyExcel.write(filePath,Student.class).build()){
            WriteSheet writeSheet=EasyExcel.writerSheet("学生表2").build();
            excelWriter.write(CreateData.create(),writeSheet);
        }
    }

效果:
成功生成指定sheet表的数据!
在这里插入图片描述

需求2:写入指定列

  • 方法1:注解排除某列
    不写哪列就在对应的属性加上 @ExcelIgnore 属性;
    在这里插入图片描述

  • 方法2:给 excludeColumnFieldNames() 传入不包含的列
    注意:set中方的列明是实体类的属性名,而不是表格中的列名!
    在这里插入图片描述

  • 方法3:给 includeColumnFieldNames() 传入所有要写的列
    在这里插入图片描述

效果:
年龄age一列没有写入excel;
在这里插入图片描述

需求3:指定写入列的名称和顺序

1. 实体类
同样使用 @ExcelProperty 注解来指定写入列的名称和索引!
注意:顺序 index是从0开始的;
在这里插入图片描述

2. 模拟建数据的类
不变;
3. 测试类
不变;
效果:
在这里插入图片描述

需求4:写入多级表头

目标样式:
此时有多级表头;
在这里插入图片描述

  1. 实体类
    @ExcelProperty 注解中对表头进行分级!上层表头相同的属性就会归到一块!
    在这里插入图片描述
    2. 模拟建数据的类
    不变;
    3. 测试类
    不变;
    效果:
    在这里插入图片描述

需求5:重复写入

1. 实体类
不变;
2. 模拟建数据的类
不变;
3. 测试类
使用循环来实现重复写入;

public class easyExcelTest {
    @Test
    public void writeTest() {
        String filePath = "C:\\Users\\liziq\\Desktop\\student.xlsx";
        try (ExcelWriter excelWriter = EasyExcel.write(filePath, Student.class).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet("学生表1").build();
            for (int i = 0; i < 3; i++) {
                excelWriter.write(CreateData.create(), writeSheet);
            }
        }
    }
}

效果:
重复写入了3次;
在这里插入图片描述

需求6:往多个工作簿写入相同数据

1. 实体类
不变;
2. 模拟建数据的类
不变;
3. 测试类
使用循环来实现重复写入;

public class easyExcelTest {
    @Test
    public void writeTest() {
        String filePath = "C:\\Users\\liziq\\Desktop\\student.xlsx";
        try (ExcelWriter excelWriter = EasyExcel.write(filePath, Student.class).build()) {
            for (int i = 1; i <= 3; i++) {
                WriteSheet writeSheet = EasyExcel.writerSheet("学生表"+i).build();
                excelWriter.write(CreateData.create(), writeSheet);
            }
        }
    }
}

效果:
三个sheet都有相同的数据;
在这里插入图片描述

需求7:往多个工作簿写入不同数据

此时要在不同的sheet写入 student 和 teacher两个不同的表!
1. 实体类
新增 Teacher 实体类;

@Data
public class Teacher {
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("科目")
    private String subject;
    @ExcelProperty("年龄")
    private int age;

    public Teacher(){}

    public Teacher(String name, String subject, int age) {
        this.name = name;
        this.subject = subject;
        this.age = age;
    }
}

2. 模拟建数据的类
新增教师数据;

class CreateData {
    public static List<Student> createStudent() {
        List<Student> datas = Arrays.asList(
                new Student("张三", "一年级", 23),
                new Student("里斯", "一年级", 19),
                new Student("王五", "一年级", 22),
                new Student("赵六", "一年级", 21)
        );
        return datas;
    }

    public static List<Teacher> createTeacher() {
        List<Teacher> datas = Arrays.asList(
                new Teacher("张老师", "政治", 41),
                new Teacher("李老师", "高数", 42),
                new Teacher("王老师", "线代", 39),
                new Teacher("赵老师", "英语", 40)
        );
        return datas;
    }
}

3. 测试类
建立不同的sheet对象来写入;

public class easyExcelTest {
    @Test
    public void writeTest() {
        String filePath = "C:\\Users\\liziq\\Desktop\\student.xlsx";
        // 此时 EasyExcel.write() 的参数不传入实体类.class
        try (ExcelWriter excelWriter = EasyExcel.write(filePath).build()) {
            //1. 创建不同的 sheet
            WriteSheet studentSheet = EasyExcel.writerSheet("学生表").head(Student.class).build();
            WriteSheet teacherSheet = EasyExcel.writerSheet("教师表").head(Teacher.class).build();
            //2. 向不同的sheet写入数据
            excelWriter.write(CreateData.createStudent(), studentSheet);
            excelWriter.write(CreateData.createTeacher(), teacherSheet);
        }
    }
}

效果:
在两个sheet分别写入了不同的数据;
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

《Vue2 进阶知识》动态挂载组件之Vue.extend + vm.$mount

前言 目前工作还是以 Vue2 为主&#xff0c;今早有人提问 如何动态挂载组件&#xff1f; 话说很久很久以前就实现过&#xff0c;今天再详细的整理一下此问题&#xff01; 开始 动态组件如下&#xff0c;是个简单的例子&#xff1a; 但请注意这里给了个 id"test2"…

探索义乌购API接口:引领全球小商品交易新篇章,赋能商家无限可能

义乌购API接口技术详解 一、引言 义乌购作为全球最大的小商品集散中心&#xff0c;为全球的商家和消费者提供了丰富的商品资源和交易服务。义乌购API接口作为其开放平台的重要组成部分&#xff0c;为开发者提供了一系列的API接口&#xff0c;使得第三方开发者能够通过编程方式…

05- OpenCV:图像操作和图像混合

目录 一、图像操作 1、读写图像 2、读写像素 3、修改像素值 4、Vec3b与Vec3F 5、相关的代码演示 二、图像混合 1、理论-线性混合操作 2、相关API(addWeighted) 3、代码演示&#xff08;完整的例子&#xff09; 一、图像操作 1、读写图像 &#xff08;1&#xff09;…

vue 公众号开发,调用jssdk封装

vue 公众号开发&#xff0c;经常会使用到 转发朋友&#xff0c;朋友圈&#xff0c;调用扫一扫等功能&#xff0c;这时就要使用微信的 jssdk 微信jssdk传送门 1. 安装jssdk 插件 (jweixin-module) npm install jweixin-module --save 2. 封装方法 utils/jwx.js let jweixin…

【好书推荐】驾驭科技浪潮的新型人才,要学点心理学

“2023年&#xff0c;是疯狂的一年&#xff0c;是世界终于开始认真对待AI的一年。” Sam Altman在社交平台写到。 回顾今年&#xff0c;年初Chat GPT横空出圈&#xff0c;其超强的理解能力、深度学习能力、人机对话的流畅性和智能度&#xff0c;让世界为之折服。 很快&#…

消息开始事件message start event

一&#xff1a;bpmn 二&#xff1a;java repositoryService.createDeployment().name("消息事件流程").addClasspathResource("bpmn/msg_event_process.bpmn").deploy(); identityService.setAuthenticatedUserId("huihui"); ProcessInstance p…

转专业(UPC练习)

题目描述 根据教育部的规定&#xff0c;大学生进校后符合条件的可申请转专业。在校本科生在完成大学一年级课程&#xff0c;进入二年级之前&#xff0c;符合以下条件之一者&#xff0c;可以申请转专业&#xff1a;&#xff08;1&#xff09;在某一学科方面确有特长的学生&#…

通义千问Qwen-72B-Chat基于PAI的低代码微调部署实践

作者&#xff1a;熊兮、求伯、一耘 引言 通义千问-72B&#xff08;Qwen-72B&#xff09;是阿里云研发的通义千问大模型系列的720亿参数规模模型。Qwen-72B的预训练数据类型多样、覆盖广泛&#xff0c;包括大量网络文本、专业书籍、代码等。Qwen-72B-Chat是在Qwen-72B的基础上…

three.js 关键帧动画

效果&#xff1a; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div><div class"box-right"…

【架构】API接口安全防护救命的11招

前言 如何保证接口的安全性? 根据多年的工作经验,给大家介绍一下保证接口安全的一些小技巧,希望对你会有所帮助。 1 参数校验 保证接口安全的第一步,也是最重要的一步,需要对接口的请求参数做校验。 如果我们把接口请求参数的校验做好了,真的可以拦截大部分的无效请求…

使用paho.mqtt.embedded-c和openssl实现MQTT的单向认证功能

1、背景 由于项目有需求在一个现有的产品上增加MQTT通信的功能&#xff0c;且出于安全考虑&#xff0c;MQTT要走TLS&#xff0c;采用单向认证的方式。 2、方案选择 由于是在现有的产品上新增功能&#xff0c;那么为了减少总的成本&#xff0c;故选择只动应用软件的来实现需求。…

设置若依Token过期时间

方法一&#xff1a;设置永不过期&#xff0c;有安全隐患&#xff0c;不建议使用 redisCache.setCacheObject(userKey, loginUser); 方法二&#xff1a;修改application.yml

Flutter组件GridView使用介绍

介绍 GridView 是 Flutter 中用于创建网格布局的滚动小部件。它可以创建多列布局&#xff0c;并且每个网格单元可以包含一个小部件。 GridView 提供了几种构造函数来创建不同类型的网格布局&#xff1a; GridView&#xff1a;最通用的构造函数&#xff0c;完全自定义网格布局…

vs报错TypeError: Cannot read property ‘parseComponent‘ of undefined(已解决)

目录 错误分析&#xff1a; 解决方案&#xff1a; 1.卸载 vue-template-compiler&#xff1a; 2.查看项目中已经安装的 Vue 的版本。 3.安装特定版本的 vue-template-compiler&#xff1a; 4.现在重新运行一下&#xff0c;成功&#xff01; 错误分析&#xff1a; 这是因…

练习接口测试第一步骤

最近一段时间学了Python语言&#xff0c;重新学了 Java&#xff0c;js&#xff0c;html语言&#xff0c;CSS&#xff0c;linux&#xff0c;一堆测试工具&#xff1b;唉&#xff5e; 在接触接口测试过程中补了很多课&#xff0c; 终于有点领悟接口测试的根本&#xff1b; 偶是…

在ubuntu上检查内存使用情况的九种方法

在 Ubuntu 中&#xff0c;可以通过 GUI(图形用户界面)和命令行使用多种方法来监视系统的内存使用情况&#xff0c;监视 Ubuntu 服务器上的内存使用情况并不复杂&#xff1b;了解已使用和可用的内存量对于故障排除和优化服务器性能至关重要&#xff0c;因为内存对系统 I/O 速度至…

008-关于FPGA/ZYNQ直接处理图像传感器数据输出的若干笔记(裸板采集思路)

文章目录 前言一、图像传感器厂商二、图像传感器的参数解析三、图像传感器中的全局曝光和卷帘曝光四、处理传感器图像数据流程1.研究当前图像传感器输出格式2.FPGA处理图像数据 总结 前言 最近也是未来需要考虑做的一件事情是&#xff0c;如何通过FPGA/ZYNQ去做显微镜图像观测…

VUE2/3:element ui table表格的显隐列(若依框架)

若依框架自带一个组件&#xff0c;封装了关于表格&#xff0c;展示和隐藏表格列的功能&#xff1b; 使用效果就是这样的&#xff0c;在表格上面&#xff0c;三个框&#xff0c;从左到右分别是隐藏上面搜索&#xff0c;刷新列表&#xff0c;和显隐列的功能&#xff1b; 一、下面…

基于 Spring Boot 支付宝沙箱支付(Java 版本)

基于 Spring Boot 支付宝沙箱支付&#xff08;Java 版本&#xff09; 步骤第一步&#xff1a;使用支付宝账户登录&#xff0c;打开控制台&#xff0c;进入沙箱环境第二步&#xff1a;配置内网穿透账号第三步&#xff1a;引入支付宝 SDK第四步&#xff1a; 配置 SpringBoot第五步…