详细讲解Java使用EasyExcel函数来操作Excel表(附实战)

news2024/11/15 21:44:54

目录

  • 前言
  • 1. EasyExcel类
  • 2. 原理分析
  • 3. demo
  • 4. 实战

前言

前阵时间好奇下载Excel,特意学习实战了该功能:详细讲解Java使用HSSFWorkbook函数导出Excel表(附实战)
现在发觉还有个EasyExcel也可专门用来读写Excel表

1. EasyExcel类

添加相应的依赖包

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

EasyExcel 是一个基于 Java 的开源工具,用于简化 Excel 文件的读写操作。

具有易用性、高性能、低内存消耗的特点。

以下是 EasyExcel 的一些主要函数和用法:(本身有读和写的两种操作)

2. 原理分析

本身该函数通过继承EasyExcelFactory函数,主要在EasyExcelFactory函数中实现。

一、对于read函数主要通过流操作获取。

在这里插入图片描述

对于EasyExcel.read 方法中常用的一个read函数如下:

EasyExcel.read(fileName, head, readListener).sheet().doRead();

大致三个参数如下:

  • fileName:Excel 文件的路径或输入流。
  • head:Excel 表头对应的实体类,定义了 Excel 表的结构。
  • readListener:数据读取的监听器,定义了数据读取的逻辑。

二、 Excel 表头的实体类:

在读取 Excel 文件时,需要定义一个实体类来映射 Excel 表头,每个字段对应一个表头列。这个实体类用于指定数据在 Java 对象中的存储结构。

public class ExcelData {
    private String name;
    private Integer age;
    // 其他字段...

    // 省略 getter 和 setter 方法
}

三、数据读取监听器:

EasyExcel 提供了 AnalysisEventListener 类来处理 Excel 数据的读取。

需要继承该类,并实现 invoke 方法来处理每一行数据的读取逻辑,以及doAfterAllAnalysed 方法来处理所有数据解析完成后的逻辑。

public class ExcelDataListener extends AnalysisEventListener<ExcelData> {

    @Override
    public void invoke(ExcelData data, AnalysisContext context) {
        // 处理每一行数据的逻辑
        System.out.println("Read data: " + data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 所有数据解析完成后的逻辑
    }
}

四、Excel 写入:

EasyExcel 也提供了写入 Excel 文件的功能。

可以使用 EasyExcel.write 方法来配置写入参数,然后调用 sheet 方法指定写入的 sheet,最后调用 doWrite 方法执行写入操作。

EasyExcel.write(fileName, head).sheet("Sheet1").doWrite(dataList);

大致的参数如下:

  • fileName:写入的 Excel 文件路径。
  • head:Excel 表头对应的实体类。
  • dataList:要写入的数据列表。dataList 应该是一个 List,其中的元素是实体类的对象

五、Excel 写入监听器:

写入 Excel 文件时进行一些额外的处理,可以使用写入监听器 WriteHandler

public class ExcelWriteHandler implements WriteHandler {

    @Override
    public void sheet(int sheetNo, Sheet sheet) {
        // 对每个 sheet 进行处理的逻辑
    }

    @Override
    public void row(int rowNum, Row row) {
        // 对每一行进行处理的逻辑
    }

    @Override
    public void cell(int cellNum, Cell cell) {
        // 对每个单元格进行处理的逻辑
    }
}

在写入 Excel 文件时,通过 excelWriter.registerWriteHandler(new ExcelWriteHandler()) 注册写入监听器即可。

3. demo

假设创建的实体类如下:

import lombok.Data;

@Data
@NoArgsConstructor
public class ExcelData {
	private String name;
	private Integer age;
	private String occupation;
	// 其他字段...

	// 省略 getter 和 setter 方法

	public ExcelData(String name, Integer age, String occupation) {
		this.name = name;
		this.age = age;
		this.occupation = occupation;
	}
}

写入Excel的函数:

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;

import java.util.ArrayList;
import java.util.List;

public class test1 {

	public static void main(String[] args) {
		String fileName = "d:\\xxx\\测试.xlsx"; // 替换成实际的文件路径

		// 准备要写入的数据
		List<ExcelData> dataList = initData();

//		// 写入 Excel 文件
//		ExcelWriter excelWriter = EasyExcel.write(fileName, ExcelData.class).build();
//		// 创建写入的 sheet
//		WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();
//		// 写入数据
//		excelWriter.write(dataList, writeSheet);

		//与上面同理
		EasyExcel.write(fileName, ExcelData.class).sheet("模板").doWrite(dataList);

		System.out.println("Excel 写入完成!");
	}

	// 初始化要写入的数据
	private static List<ExcelData> initData() {
		List<ExcelData> dataList = new ArrayList<>();
		dataList.add(new ExcelData("John", 25, "Engineer"));
		dataList.add(new ExcelData("Alice", 30, "Manager"));
		dataList.add(new ExcelData("Bob", 28, "Developer"));
		// 添加更多数据...

		return dataList;
	}
}

最后截图如下:

在这里插入图片描述

读取函数的功能:

在这之前需要加一个监听器:

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

import java.util.Map;

public class ExcelListen extends AnalysisEventListener<ExcelData> {

	@Override
	public void invoke(ExcelData data, AnalysisContext context) {
		// 数据处理逻辑,可以将数据存储到数据库或进行其他操作
		System.out.println("Read data: " + data);
	}

	@Override
	public void doAfterAllAnalysed(AnalysisContext context) {
		// 所有数据解析完成后的操作
	}
}

其读写的函数如下:

import com.alibaba.excel.EasyExcel;

public class test1 {

	public static void main(String[] args) {
		String fileName = "d:\\xx\\测试.xlsx"; // 替换成实际的文件路径

		// 使用 EasyExcel 读取 Excel 文件
		EasyExcel.read(fileName, ExcelData.class, new ExcelListen()).sheet().doRead();
	}

}

截图如下:

在这里插入图片描述

4. 实战

对于实战中,多数是结合springboot以及数据库中,主要将其Excel中导入到界面中,同时也保存在数据库中!

关联数据库Entity的类如下:

@Data
@TableName("xx")
@ApiModel(value = "Info对象", description = "Info对象")
public class Info{

	@ApiModelProperty(value = "设备编号")
	@ExcelProperty("设备编号")
	private String equipmentNo;
}

对应的监听类函数如下:(对于监听类的函数实际看个人数据库补充即可!以下只是给个模板)

public class InfoDataListener extends AnalysisEventListener<Info> {

	/**
	 * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
	 */
	private static final int BATCH_COUNT = 5;

	List<Info> list = new ArrayList<Info>();

	private IInfoService infoService;

	private IInfoRunningDataService infoRunningDataService;

	//其他

	public InfoDataListener(IInfoService infoService) {
		this.infoService = infoService;
	}
	
	//弄构造函数
	public InfoDataListener(IInfoService infoService,
							//其他) {
		this.infoService = infoService;
		//其他
	}

	/**
	 * 这个每一条数据解析都会来调用
	 *
	 * @param info            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
	 * @param analysisContext
	 */
	@Override
	public void invoke(Info info, AnalysisContext analysisContext) {
		list.add(info);
		// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
		if (list.size() > BATCH_COUNT) {
			saveData();
			// 存储完成清理 list
			list.clear();
		}
	}

	/**
	 * 所有数据解析完成了 都会来调用
	 *
	 * @param analysisContext
	 */
	@Override
	public void doAfterAllAnalysed(AnalysisContext analysisContext) {
		// 这里也要保存数据,确保最后遗留的数据也存储到数据库
		saveData();
	}


	/**
	 * 除了保持自己本身,还要保存运行数据表,
	 * xxx
	 */
	public void saveData() {
		infoService.saveBatch(list);
		ArrayList<InfoRunningData> infoRunningDatas = new ArrayList<InfoRunningData>();
		// 其他数据一块
		list.stream().forEach(info ->{
			InfoRunningData infoRunningData = new InfoRunningData();
			infoRunningData.setInfoId(info.getId());
			infoRunningDatas.add(infoRunningData);

			//其他数据一并处理
		});


		infoRunningDataService.saveBatch(infoRunningDatas);
		//其他数据一并处理
	}
}

controller函数:

@PostMapping("/importExcel")
@ResponseBody
public R upload(MultipartFile file) throws IOException {
	EasyExcel.read(file.getInputStream(), Info.class, new InfoDataListener(infoService,
		infoxxService,infoyyService	)).sheet().doRead();
//		EasyExcel.read(file.getInputStream(),Info.class,new InfoDataListener(infoService)).sheet().doRead();
	return R.success("导入成功");
}

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

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

相关文章

张驰咨询:如何战胜实施精益生产培训的常见难题?

精益生产又称作“Lean Manufacturing”或“Lean Production”&#xff0c;它是一种强调消除生产过程中一切形式的浪费&#xff0c;注重流程优化以提升整体效能的管理哲学。源自丰田生产系统&#xff08;Toyota Production System&#xff09;&#xff0c;精益生产培训目标在于最…

MyBatis分页机制深度解析

前言 在企业项目的数据库操作中&#xff0c;分页查询是一个常见需求&#xff0c;尤其当数据量庞大时。MyBatis 作为 我们Java 开发者的持久层框架&#xff0c;为分页提供了灵活的支持。 本篇文章我们将深入探讨 MyBatis 的分页机制&#xff0c;使我们在实际开发项目中运用自如…

【C++高阶(九)】C++类型转换以及IO流

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; C高阶 1. 前言2. C语言类型转换的方式3. C的强制…

Flask登陆后登陆状态及密码的修改和处理

web/templates/common 是统一布局 登录成功 后flask框架服务器默认由login.html进入仪表盘页面index.html(/),该页面的设置在 (web/controllers/user/index.py)&#xff0c;如果想在 该仪表盘页面 将 用户信息 展示出来&#xff0c;就得想办法先获取到 当前用户的 登陆状态。…

11、基于LunarLander登陆器的A2C强化学习(含PYTHON工程)

11、基于LunarLander登陆器的A2C强化学习&#xff08;含PYTHON工程&#xff09; LunarLander复现&#xff1a; 07、基于LunarLander登陆器的DQN强化学习案例&#xff08;含PYTHON工程&#xff09; 08、基于LunarLander登陆器的DDQN强化学习&#xff08;含PYTHON工程&#xff…

thinkcmf 文件包含 x1.6.0-x2.2.3 已亲自复现

thinkcmf 文件包含 x1.6.0-x2.2.3 CVE-2019-16278 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 漏洞名称 漏洞描述 ThinkCMF是一款基于PHPMYSQL开发的中文内容管理框架&#xff0c;底层采用ThinkPHP3.2.3构建。ThinkCMF提出灵活的应用机制&a…

Elasticsearch中复制一个索引数据到新的索引中

问题 我有时候&#xff0c;需要调试一个已经存在的ES索引&#xff0c;需要从已有的索引复制数据到新的索引中去。 解决 这里我借助一个GUI工具&#xff0c;来解决这个问题&#xff0c;底层它是使用Reindex的API实现索引数据复制的。利用Reindex API搞不定这个事情&#xff0…

高德地图_公共交通路径规划API,获取两地点之间的驾车里程和时间

import pandas as pd import requests import jsondef get_dis_tm(origin, destination,city,cityd):url https://restapi.amap.com/v3/direction/transit/integrated?key xxx #这里就是需要去高德开放平台去申请key,请在xxxx位置填写,web服务APIlink {}origin{}&desti…

Laravel的知识点

1.{{ }} 是在 HTML 中内嵌 PHP 的 Blade 语法标识符&#xff0c;表示包含在该区块内的代码都将使用 PHP 来编译运行。 2.两种写法 3.return void 在这段注释中&#xff0c;"return void" 表示该函数或方法没有返回值。这意味着它执行某些操作或任务&#xff0c;但…

基于Java SSM框架实现县小吃门店连锁点餐订餐系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现县小吃门店连锁点餐订餐系统演示 摘要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 沙县小吃点餐系统&#xff0c;主要的模块包括实现管理员&#xff1b;个人中心、用户管…

根据commitID删除某一次提交

1.查看提交历史 git log --prettyoneline2.找到需要删除的那个commit,然后找到上次提交的commitID 比如想要删除下面这一条 我们找到上次提交的commitID 3.执行rebase git rebase -i efa11da0a684977bf8ac047ebb803e2ded2063a4 进入编辑状态显示如下 将需要删除的那个提交前…

基于Elemnet-plus 封装的功能表格,基本囊括element-plus 官网表格的所有使用场景

前言 这是一个多用途的基于element-plus 封装的表格组件&#xff0c;基本上elemnet-plus 官网涉及到的使用场景&#xff0c;都可以&#xff0c;而且使用上来说会简单许多&#xff0c;配置上类似与vxe-table 的使用&#xff0c;下面逐一展示各种场景的使用方式&#xff0c;基本上…

<JavaEE> TCP 的通信机制(三) -- 滑动窗口

目录 TCP的通信机制的核心特性 四、滑动窗口 1&#xff09;什么是滑动窗口&#xff1f; 2&#xff09;滑动窗口的作用是什么&#xff1f; 3&#xff09;批量传输出现丢包如何处理&#xff1f; 1> 接收端ACK丢包 2> 发送端数据包丢包 4&#xff09;适用性 TCP的通…

主动学习如何解决数据标注的难题?主动学习和弱监督学习有何区别?

机器学习的成功与否取决于数据标注的质量和数量。利用主动学习的机器学习技术能加快模型训练的进度和减少数据获取的资金投入。依靠主动学习来得到有价值的数据&#xff0c;以便机器模型从中学习。如果一个模型被具有价值的数据加以训练&#xff0c;它将以较少的人工标注和更短…

安防视频监控系统EasyCVR实现H.265视频在3秒内起播的注意事项

可视化云监控平台/安防视频监控系统EasyCVR视频综合管理平台&#xff0c;采用了开放式的网络结构&#xff0c;可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力&#xff0c;同时…

ZETA落地合肥、宜城南方水泥,纵行科技携手中才邦业助力水泥企业数智化管理

近日&#xff0c;合肥南方水泥、宜城南方水泥落地ZETA预测性维护方案&#xff0c;通过在水泥厂内搭建ZETA网络&#xff0c;并在B类及C类主辅机设备上安装ZETA系列端智能传感器&#xff0c;进行数据采集和监测设备运行状态、以及早期故障警报和诊断&#xff0c;实现水泥生产设备…

PHP的Laravel加一个小页面出现问题(whereRaw的用法)

1.权限更新问题 因为是已经有样例了所以html和php页面很快写出来了 然后就是页面写完了路由不知道在哪写&#xff0c;后来想起来之前有要开权限来着&#xff0c;试了一下&#xff0c;还是不行&#xff0c;不过方向是对了 这是加的路由&#xff0c;不过需要在更新一下权限 这…

零基础刷代码随想录【Day1】|| 二分查找,移除元素

我的个人主页&#xff1a;☆光之梦☆的博客_CSDN博客-C语言基础语法&#xff08;超详细&#xff09;领域博主 欢迎各位 &#x1f44d;点赞 ⭐收藏 &#x1f4dd;评论 我的专栏&#xff1a;C语言基础语法&#xff08;超详细&#xff09;_☆光之梦☆的博客-CSDN博客&#xff08;这…

Ubuntu安装K8S(1.28版本,基于containrd)

原文网址&#xff1a;Ubuntu安装K8S(1.28版本&#xff0c;基于containrd&#xff09;-CSDN博客 简介 本文介绍Ubuntu安装K8S的方法。 官网文档&#xff1a;这里 1.安装K8S 1.让apt支持SSL传输 sudo apt-get update sudo apt-get -y install apt-transport-https ca-certi…

【算法与数据结构】860、LeetCode柠檬水找零

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题的思路比较简单&#xff0c;首先要保存收到的零钱&#xff0c;其次计算找零&#xff0c;最后分解找…