EasyExcel入门

news2024/9/8 23:14:54

目录

一、文章简介

二、概念

1.EasyExcel是什么?

2.EasyExcel 能用在哪里?

3.为什么要选用EasyExcel解析excel?

4.如何使用EasyExcel?

三、EasyExcel快速入门

1.环境搭建

2.简单写excel

代码示例

TestFileUtil

Employee

SimpleWrite

演示效果

3.简单读excel

代码示例

SimpleRead

演示效果

四、EasyExcel进阶操作

1.批量(重复)写数据

代码示例

ManyWrite

效果演示

2.按模版填充单个对象数据

代码示例

效果演示

3.按模版批量填充多个对象数据

代码示例

4.自定义监听器读海量(百万级别)数据并监控内存消耗

代码示例

EmployeeDao

EmployeeListener

MyRead

五、EasyExcel综合应用


阿里EasyExcel 即学即会:海量数据的导入导出

一、文章简介

主要讲解在java应用中如何利用EasyExcel技术完成对excel文件的导入和导出操作。

数据从excel------->数据库: 导入

数据从数据库-------->excel:导出

二、概念

1.EasyExcel是什么?

  • EasyExcel是一个基于Java的简单、省内存的读写Excel的阿里开源项目。

  • 在尽可能节约内存的情况下支持读写百M的Excel。

2.EasyExcel 能用在哪里?

项目中涉及到Excel文件,CVS文件大多数的读写操作,均可以使用。

3.为什么要选用EasyExcel解析excel?

4.如何使用EasyExcel?

阿里官方文档: EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 官网

三、EasyExcel快速入门

1.环境搭建

  • 创建maven工程

  • 引入相关坐标

    • <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>easyexcel</artifactId>
          <version>3.1.2</version>
      </dependency> 

  • 参考官方API完成功能

2.简单写excel

  • 编写模型类并加入注解

  • 编写获取测试数据的方法

  • 调用官方API完成写功能

  • 核心代码:

EasyExcel.write(fileName, DemoData.class).sheet("测试").doWrite(data(100000));
代码示例
TestFileUtil

获取代码路径的工具类

package com.ithiema.utils;
/*
    获取代码路径的工具类,可以获取到模块这一级的磁盘路径;
 */
public class TestFileUtil {
    public static String getPath() {
        return TestFileUtil.class.getResource("/").getPath().replace("classes/","");
    }
​
    public static void main(String[] args) {
        System.out.println(getPath());
    }
}
Employee

员工类

package com.ithiema.pojo;
​
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
​
import java.util.Date;
​
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
    @ExcelProperty("员工工号")
    private int id;
    @ExcelProperty("员工姓名")
    private String name;
    @ExcelProperty("员工工资")
    private double salary;
    @ExcelProperty("入职日期")
    private Date date;
}
​

SimpleWrite

easyexcel的简单写数据

package com.ithiema.write;
​
import com.alibaba.excel.EasyExcel;
import com.ithiema.pojo.Employee;
import com.ithiema.utils.TestFileUtil;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
​
/*
    练习easyexcel的简单写数据
 */
public class SimpleWrite {
​
    @Test
    public void testWrite(){
        String name = TestFileUtil.getPath() + "简单写数据" + System.currentTimeMillis() + ".xlsx";
        EasyExcel.write(name, Employee.class).sheet("我的快速入门").doWrite(data(12));
    }
​
​
    // 准备测试数据的方法
    private List<Employee> data(int i) {
        List<Employee> list = new ArrayList<>();
        for (int j = 1; j <= i; j++) {
            list.add(new Employee(j,"测试数据"+j,6.6*j,new Date()));
        }
        return list;
    }
}
演示效果

3.简单读excel

  • 编写模型类并加入注解

  • 监听器介绍

  • 调用官方API完成写功能

  • 核心代码:

EasyExcel.read(fileName, DemoData.class, new PageReadListener<DemoData>
(list -> System.out.println(list))).sheet().doRead();
代码示例
SimpleRead

快速入门,简单读

package com.ithiema.read;
​
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.ithiema.pojo.Employee;
import com.ithiema.utils.TestFileUtil;
import org.junit.Test;
​
import java.io.File;
​
/*
    快速入门,简单读
 */
public class SimpleRead {
    
    /**
     * 使用EasyExcel框架读取Excel文件
     *
     * 指定文件路径,数据模型类(Employee.class),以及一个读取监听器,用于处理读取到的每条数据。
     * 文件名通过TestFileUtil.getPath()获取相对路径,并拼接上特定的文件名。
     * 使用EasyExcel的read方法指定文件名、数据模型类和监听器,然后调用sheet().doRead()开始读取第一个工作表的数据。
     */
    @Test
    public void testRead(){
        // 构建文件路径
        String fileName  = "D:\\develop\\dev\\easyexcel-course\\easyExcel-heima\\QuickStart\\target\\test-简单写数据1722256409955.xlsx";
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
        // 这里每次会读取100条数据 然后返回过来 直接调用使用数据就行
        EasyExcel.read(fileName, Employee.class, new PageReadListener<Employee>(dataList -> {
            // 遍历并打印读取到的每个员工对象
            for (Employee employee : dataList) {
                System.out.println(employee);
            }
        })).sheet(0).doRead();
    }
    
}
​
演示效果

四、EasyExcel进阶操作

1.批量(重复)写数据

  • 编写模型类并加入注解

  • 调用官方API完成写功能

try (ExcelWriter writer = EasyExcel.write(fileName, DemoData.class).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet("测试表1").build();
            for (int i = 0; i < 3; i++) {
                ExcelWriter write = writer.write(data(100000), writeSheet);
            }
        }
代码示例
ManyWrite

进阶写数据

package com.ithiema.write;
​
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.ithiema.pojo.Employee;
import com.ithiema.utils.TestFileUtil;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
​
/*
    进阶写数据
 */
public class ManyWrite {
​
    /**
     * 批量写入Excel数据
     * 
     * 该方法创建一个Excel文件,然后分三次写入100条员工数据。
     * 使用EasyExcel框架简化了Excel文件的写入操作。
     */
    @Test
    public void testWrite(){
        // 构建文件名,包含批量写数据字样和当前时间戳,确保文件名的唯一性
        String name = TestFileUtil.getPath() + "批量写数据" + System.currentTimeMillis() + ".xlsx";
        // 与文件想关联的写对象 使用try-with-resources语句确保ExcelWriter资源在使用后能被正确关闭
        try (ExcelWriter writer = EasyExcel.write(name, Employee.class).build()) {
            // 准备一个表对象 设置写入的Sheet信息
            WriteSheet sheet = EasyExcel.writerSheet("批量写练习").build();
            // 循环三次,每次写入10000条员工数据
            // 利用writer向sheet表写数据
            for (int i = 1; i <= 3; i++) {
                writer.write(data(100), sheet);
            }
        }
    }
    
    
    // 准备测试数据的方法
    private List<Employee> data(int i) {
        List<Employee> list = new ArrayList<>();
        for (int j = 1; j <= i; j++) {
            list.add(new Employee(j,"测试数据"+j,6.6*j,new Date()));
        }
        return list;
    }
}
效果演示

上面写的数据格式不好看怎么办?

  • 利用阿里提供的模版写数据

  • 模版设置的样式新添加的数据会自动包含样式

2.按模版填充单个对象数据

  • 编写模型类并加入注解

  • 按要求编写模版文件

  • 调用官方API完成写功能

EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(fillData);
代码示例
效果演示

3.按模版批量填充多个对象数据

  • 编写模型类并加入注解

  • 按要求编写模版文件

  • 调用官方API完成写功能

try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
            WriteSheet writeSheet2 = EasyExcel.writerSheet("数据2").build();
            excelWriter.fill(data(300000), writeSheet);
            excelWriter.fill(data(300000), writeSheet2);
        }
代码示例
package com.ithiema.write;
​
import com.alibaba.excel.EasyExcel;
import com.ithiema.pojo.Employee;
import com.ithiema.utils.TestFileUtil;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
​
/*
    根据模版写数据
 */
public class FillWriter {
    
    /**
     * 使用EasyExcel框架通过模板填充数据至新Excel文件
     *
     * 此方法将从指定的模板文件读取样式和结构,然后填充20条数据(由data(20)方法提供)到名为"1025"的工作表中,
     * 并保存到新的Excel文件中,文件名中包含系统当前时间戳以确保唯一性。
     */
    @Test
    public void testFill(){
        // 模板文件的绝对路径
        String templateFileName = "D:\\develop\\dev\\easyexcel-course\\easyExcel-heima\\QuickStart\\target\\模板.xlsx";
        // 目标文件的绝对路径,包含时间戳确保文件名唯一
        String fileName = "D:\\develop\\dev\\easyexcel-course\\easyExcel-heima\\QuickStart\\target\\"+System.currentTimeMillis()+ "按照模版写数据.xlsx";
        // 使用EasyExcel框架,指定目标文件、模板文件和工作表名称进行数据填充
        EasyExcel.write(fileName).withTemplate(templateFileName).sheet("1025").doFill(data(20));
    }
    
    
    
    // 准备测试数据的方法
    private List<Employee> data(int i) {
        List<Employee> list = new ArrayList<>();
        for (int j = 1; j <= i; j++) {
            list.add(new Employee(j,"测试数据"+j,6.6*j,new Date()));
        }
        return list;
    }
}
 

4.自定义监听器读海量(百万级别)数据并监控内存消耗

  • 编写模型类并加入注解

  • 自定义监听器

  • 调用官方API完成写功能

EasyExcel.read(fileName, IndexOrNameData.class, new IndexOrNameDataListener()).sheet().doRead();
代码示例
EmployeeDao
package com.ithiema.dao;
​
import com.ithiema.pojo.Employee;
​
import java.util.List;
​
public class EmployeeDao {
    public void saveData(List<Employee> list){
        System.out.println("模拟保存数据..."+list.size());
    }
}
​
EmployeeListener
/**
 * EmployeeListener 类实现了 ReadListener 接口,用于处理 Excel 文件读取过程中的数据事件。
 * 主要功能是在读取每行数据时将其添加到一个列表中,当列表达到预设大小时批量保存数据到数据库,
 * 并在读取完成后处理剩余未达批次的数据。
 */
public class EmployeeListener implements ReadListener<Employee> {
​
    /**
     * 批量保存数据的阈值,默认为 100 条记录。
     */
    private int count = 100;
​
    /**
     * 数据访问对象,用于与数据库交互,执行数据保存操作。
     */
    private EmployeeDao dao;
​
    /**
     * 临时存储读取数据的列表,达到预设大小后清空并批量保存。
     */
    private List<Employee> list = new ArrayList<>(count);
​
    /**
     * 构造函数,初始化数据访问对象。
     *
     * @param dao 数据访问对象,用于数据的持久化操作。
     */
    public EmployeeListener(EmployeeDao dao) {
        this.dao = dao;
    }
​
    /**
     * 计数器,用于监控批量保存次数,每 100 批次调用一次垃圾回收。
     */
    int c = 0;
​
    /**
     * 当解析一行数据时调用此方法。
     * 将读取到的 Employee 对象添加到 list 中,当 list 达到预设大小时,调用 dao 的 saveData 方法批量保存数据,
     * 并重新初始化 list。
     *
     * @param employee       解析得到的 Employee 对象。
     * @param analysisContext 分析上下文,包含解析过程中的相关信息。
     */
    @Override
    public void invoke(Employee employee, AnalysisContext analysisContext) {
        list.add(employee);
        if(list.size() >= count){
            dao.saveData(list);
            list = new ArrayList<>(count);
            c++;
            if(c % 100 == 0){
                System.gc(); // 每 100 批次调用一次垃圾回收,优化内存使用。
            }
        }
    }
​
    /**
     * 在所有数据解析完成后调用此方法。
     * 处理剩余未达批次的数据,即当读取完成时 list 中可能还存在未保存的数据,此时将它们全部保存到数据库。
     *
     * @param analysisContext 分析上下文,包含解析过程中的相关信息。
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if(list.size() > 0){
            dao.saveData(list); // 保存剩余数据。
        }
    }
}
MyRead
package com.ithiema.read;
​
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.ithiema.EmployeeListener.EmployeeListener;
import com.ithiema.dao.EmployeeDao;
import com.ithiema.pojo.Employee;
import com.ithiema.utils.TestFileUtil;
import org.junit.Test;
​
/*
    使用自定义监听器读数据
 */
public class MyRead {
​
    // 读单表
    @Test
    public void testRead(){
        String filename = TestFileUtil.getPath() + "3万.xlsx";
        ExcelReader reader = EasyExcel.read(filename, Employee.class,new EmployeeListener(new EmployeeDao())).build();
        ReadSheet sheet = EasyExcel.readSheet().build();
        reader.read(sheet);
    }
​
    @Test
    public void testRead3(){
        String filename = TestFileUtil.getPath() + "批量写数据1669108667435.xlsx";
        EasyExcel.read(filename, Employee.class, new EmployeeListener(new EmployeeDao())).sheet().doRead();
    }
}
​

五、EasyExcel综合应用

  1. 环境搭建

  2. 实现文件导入功能(采用异步上传并使用遮罩层)

  3. 实现文件导出功能(采用同步下载并解决文件名中文乱码)

代码gitee地址:

EasyExcel: 阿里EasyExcel学习记录

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

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

相关文章

C++(week14): C++提高:(二)C++11线程库

文章目录 一、线程1.C11线程库的概述2.构造函数3.线程启动: 线程入口函数的传递方式4.线程终止5.线程状态6.获取线程id&#xff1a;get_id() 二、互斥锁1.什么是互斥锁2.头文件3.常用函数接口 三、lockguard与unique_lock1.lock_guard2.unique_lock(1)概念(2)函数接口 3.原子数…

Python脚本:使用PyPDF2给一个PDF添加上页数/总页数标签

一、实现代码 import PyPDF2 from PyPDF2 import PdfWriter from PyPDF2.generic import AnnotationBuilder# 指定输入和输出pdf pdf_path rC:\Users\ASUS\Desktop\temp\xxxx.pdf out_path rC:\Users\ASUS\Desktop\temp\xxxx2.pdf# 创建 PdfWriter 对象 writer PdfWriter()…

Python转换Excel文件为SVG文件

SVG&#xff08;Scalable Vector Graphics&#xff09;是一种基于XML的矢量图像格式。这种格式在Web开发和其他图形应用中非常流行&#xff0c;提供了一种高效的方式来呈现复杂的矢量图形。如果我们需要在网页中嵌入Excel表格&#xff0c;或是直接使用Excel工作表制作网页&…

基于元神系统编写“清屏”程序

1. 背景 本文介绍了基于元神系统开发软件的操作流程&#xff0c;并详细介绍了“清空屏幕”程序的编写以及测试结果。 2. 方法 &#xff08;1&#xff09;编写程序 在元神系统0.4版的基础上&#xff0c;用FASM汇编语言进行软件开发。假设屏幕为80列25行的文本显示模式&#…

【更新2022】各省农业科技活动经费(RD)测算 1999-2022 无缺失

各省农业科技活动经费&#xff08;R&D&#xff09;测算数据在农业经济学、政策研究和农村发展规划等领域的论文研究中具有重要应用价值。首先&#xff0c;这些数据可以用于分析不同省份在农业科技投入上的差异及其对农业生产力和产出的影响&#xff0c;帮助揭示不同地区农业…

Node.js版本管理工具之NVM

目录 一、NVM介绍二、NVM的下载安装1、NVM下载2、卸载旧版Node.js3、安装 三、NVM配置及使用1、设置nvm镜像源2、安装Node.js3、卸载Node.js4、使用或切换Node.js版本5、设置全局安装路径和缓存路径 四、常用命令技术交流 博主介绍&#xff1a; 计算机科班人&#xff0c;全栈工…

坐牢十八天 20240729(IO)

一.笔记 1. 有关系统时间的函数 1> 有关时间的函数 #include <time.h> time_t time(time_t *tloc); 功能&#xff1a;获取系统时间&#xff0c;从1970年1月1日0时0分0秒&#xff0c;到目前累计的秒数 参数&#xff1a;用于接收的秒数 返回值&#xff1a;秒数使…

【每日刷题】Day89

【每日刷题】Day89 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 102. 二叉树的层序遍历 - 力扣&#xff08;LeetCode&#xff09; 2. 155. 最小栈 - 力扣&#xff0…

Open3D 计算点云质心

目录 一、概述 1.1原理 1.2实现步骤 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云深度学习案例汇总&#xff08;长期更新&#xff09;-CSDN博客 一、概述 1.1原理 在Open3D中&am…

成为git砖家(8): 使用 git log 查询范围内的 commit

文章目录 1. 查询 git log 的文档2. 不带任何参数: git log 啥意思&#xff1f;3. git log 最主要功能是什么&#xff1f;4. git log <commit1>..<commit2> 什么意思5. 查看最近n次commit6. References 1. 查询 git log 的文档 git help log --web市面上针对 git …

从善如流之您最亲近人之善,肯出力之象-下学而上达

您最亲近人之善&#xff0c;肯出力之象&#xff0c;就是那个爬&#xff0c;甚至于跪倒在地上&#xff0c;抹那个下水井子。这或许就是那个马云大佬讲过的&#xff0c;就是从您最近距离&#xff0c;身边的人学习。人家为啥做的好&#xff0c;出色&#xff1f;而且您是一母同胞之…

太坑了!RabbitMQ+PHP开发的辛酸经历

博主介绍&#xff1a;全网粉丝10w、CSDN合伙人、华为云特邀云享专家&#xff0c;阿里云专家博主、星级博主&#xff0c;51cto明日之星&#xff0c;热爱技术和分享、专注于Java技术领域 &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅…

设计模式:模板方法模式:封装不变,扩展可变

目录 一、模板方法模式的定义与结构 二、模板方法模式的优点 三、模板方法模式的示例 示例一&#xff1a; 示例二&#xff1a; 四、总结 在软件开发中&#xff0c;设计模式是解决常见问题的可复用方案。其中&#xff0c;模板方法模式是一种行为型设计模式&#xff0c;它在不…

lora微调Qwen模型全流程

LoRA 微调 Qwen 模型的技术原理概述 LoRA&#xff08;Low-Rank Adaptation&#xff09;是一种用于大模型高效微调的方法。通过对模型参数进行低秩分解和特定层的微调&#xff0c;LoRA 能在保持模型性能的前提下显著减少训练所需的参数量和计算资源。接下来是对 LoRA 微调 Qwen…

Matlab编程资源库(9)数据插值与曲线拟合

一、一维数据插值 在MATLAB中&#xff0c;实现这些插值的函数是interp1&#xff0c;其调用格式为&#xff1a; Y1interp1(X,Y,X1,method) 函数根据X,Y的值&#xff0c;计算函数在X1处的值。X,Y是两个等长的已知向量&#xff0c;分别描述采样点和样本值&#xff0c;X1是一个向量…

【机器学习基础】初探机器学习

【作者主页】Francek Chen 【专栏介绍】⌈Python机器学习⌋ 机器学习是一门人工智能的分支学科&#xff0c;通过算法和模型让计算机从数据中学习&#xff0c;进行模型训练和优化&#xff0c;做出预测、分类和决策支持。Python成为机器学习的首选语言&#xff0c;依赖于强大的开…

vue项目引入live2d保姆级教程--web端、多种方法

一、自建live2d运行 1、选择SDK——live2d Cubism SDK &#xff08;1&#xff09;链接&#xff1a;Live2D Cubism SDK | Live2D Cubism 打开网站&#xff0c;它长这样&#xff1a; &#xff08;2&#xff09;选择web &#xff0c;到下个页面 &#xff08;3&#xff09;下…

Power Tower

Problem - D - Codeforces 牛客和codeforce都有 递归处理l,r&#xff0c;终点是lr && mod1 用扩展欧拉定理 // Problem: D. Power Tower // Contest: Codeforces - Codeforces Round 454 (Div. 1, based on Technocup 2018 Elimination Round 4) // URL: https://c…

Linux基础操作指令

Linux的操作特点&#xff1a;纯命令行&#xff08;虽然也有图形化界面&#xff0c;但主要是工程师使用&#xff0c;意义不大&#xff09; windows的操作特点&#xff1a;图形化界面&#xff08;也有纯命令行的形式&#xff0c;但其更贴近大众&#xff0c;命令行学习成本高&…