当前位置: 首页 > news >正文

【JAVA】阿里巴巴 EasyExcel:高效的Excel处理解决方案

在这里插入图片描述

文章目录

    • EasyExcel
      • 1. EasyExcel 简介
        • 1.1 主要特点
        • 1.2 依赖配置
      • 2. EasyExcel 核心功能
        • 2.1 写入 Excel 文件
        • 2.2 读取 Excel 文件
      • 3. 业务开发示例
        • 3.1 用户数据导出
        • 3.2 用户数据导入
      • 4. 进阶用法
        • 4.1 自定义转换器
        • 4.2 自定义格式

更多相关内容可查看

附官网地址:https://easyexcel.opensource.alibaba.com/docs/current/api/

EasyExcel

在现代企业的业务处理中,Excel 文件常常被用来进行数据交换、报告生成和数据分析等任务。然而,处理 Excel 文件可能会变得十分复杂,特别是当数据量很大时。阿里巴巴的 EasyExcel 提供了一个高效、简便的解决方案,用于处理大规模的 Excel 文件。本博客将详细介绍 EasyExcel 的特性、使用方法,并提供具体的业务开发示例和代码。

1. EasyExcel 简介

EasyExcel 是阿里巴巴开源的一个 Java 库,旨在提高 Excel 文件处理的性能。它是基于 POI 的封装,主要用于简化 Excel 文件的读写操作,并且在处理大数据量时表现出色。

1.1 主要特点
  • 高性能:能够处理百万级数据而不占用大量内存。
  • 易用性:提供简单易用的 API,降低使用门槛。
  • 支持大数据量:通过逐行读取和写入,避免一次性加载全部数据到内存中。
  • 注解驱动:通过注解配置简化代码编写,增强可读性。
1.2 依赖配置

要使用 EasyExcel,需要在 Maven 或 Gradle 配置相应的依赖。

Maven 依赖:

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

Gradle 依赖:

implementation 'com.alibaba:easyexcel:3.0.6'

2. EasyExcel 核心功能

EasyExcel 提供了读写 Excel 文件的基本功能,我们将通过以下示例来深入了解。

2.1 写入 Excel 文件

使用 EasyExcel 写入 Excel 文件非常简单。首先,我们需要定义一个数据模型,并通过注解配置 Excel 文件的表头。

示例数据模型:

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import java.util.Date;public class UserData {@ExcelProperty("用户ID")private Long id;@ExcelProperty("用户姓名")private String name;@ExcelProperty("创建时间")@DateTimeFormat("yyyy-MM-dd HH:mm:ss")private Date createTime;// Getters and Setters
}

写入 Excel 文件代码示例:

import com.alibaba.excel.EasyExcel;import java.util.ArrayList;
import java.util.Date;
import java.util.List;public class ExcelWriteExample {public static void main(String[] args) {String fileName = "user_data.xlsx";List<UserData> dataList = new ArrayList<>();dataList.add(new UserData(1L, "Alice", new Date()));dataList.add(new UserData(2L, "Bob", new Date()));EasyExcel.write(fileName, UserData.class).sheet("用户数据").doWrite(dataList);}
}
2.2 读取 Excel 文件

读取 Excel 文件同样直观。我们需要定义一个监听器来处理每一行的数据。

示例数据模型(与写入示例相同):

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import java.util.Date;public class UserData {@ExcelProperty("用户ID")private Long id;@ExcelProperty("用户姓名")private String name;@ExcelProperty("创建时间")@DateTimeFormat("yyyy-MM-dd HH:mm:ss")private Date createTime;// Getters and Setters
}

读取 Excel 文件代码示例:

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.ArrayList;
import java.util.List;public class ExcelReadExample {public static void main(String[] args) {String fileName = "user_data.xlsx";EasyExcel.read(fileName, UserData.class, new AnalysisEventListener<UserData>() {private List<UserData> dataList = new ArrayList<>();@Overridepublic void invoke(UserData data, AnalysisContext context) {dataList.add(data);}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// Process the dataList or persist it to the databasedataList.forEach(System.out::println);}}).sheet().doRead();}
}

3. 业务开发示例

让我们通过一个实际的业务场景来展示 EasyExcel 的应用。例如,假设我们需要处理一个用户数据的导入导出功能,其中包括从 Excel 文件中读取用户数据并保存到数据库中,或将数据库中的用户数据导出到 Excel 文件中。

3.1 用户数据导出

我们需要从数据库中获取用户数据,然后将其导出到 Excel 文件中。假设我们有一个用户服务类 UserService 和对应的数据库访问层 UserRepository

用户数据服务:

import java.util.List;public interface UserService {List<UserData> getAllUsers();
}

用户数据实现:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserRepository userRepository;@Overridepublic List<UserData> getAllUsers() {return userRepository.findAll();}
}

导出功能实现:

import com.alibaba.excel.EasyExcel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class UserDataExporter {@Autowiredprivate UserService userService;public void exportUserData() {List<UserData> users = userService.getAllUsers();String fileName = "exported_user_data.xlsx";EasyExcel.write(fileName, UserData.class).sheet("用户数据").doWrite(users);}
}
3.2 用户数据导入

同样,我们需要实现一个从 Excel 文件中读取用户数据并保存到数据库中的功能。

导入功能实现:

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.event.AnalysisEventListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class UserDataImporter {@Autowiredprivate UserService userService;public void importUserData(String fileName) {EasyExcel.read(fileName, UserData.class, new AnalysisEventListener<UserData>() {@Overridepublic void invoke(UserData userData, AnalysisContext context) {// Save user data to the databaseuserService.save(userData);}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// Optional: Log completion or further processing}}).sheet().doRead();}
}

4. 进阶用法

除了基本的读写功能,EasyExcel 还提供了一些进阶用法,例如支持不同的数据格式、自定义转换器等。

4.1 自定义转换器

我们可以实现自定义转换器来处理特殊的数据格式,例如将日期格式化为特定的字符串格式。

自定义日期格式转换器:

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.DateUtils;
import java.util.Date;public class CustomDateConverter implements Converter<Date> {@Overridepublic Class supportJavaTypeKey() {return Date.class;}@Overridepublic CellData<?> convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {// Format the date as a stringString formattedDate = DateUtils.formatDate(value, "yyyy-MM-dd");return new CellData<>(formattedDate);}@Overridepublic Date convertToJavaData(CellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {// Parse the date string back to Date objectreturn DateUtils.parseDate(cellData.getStringValue(), "yyyy-MM-dd");}
}

在数据模型中使用自定义转换器:

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;public class UserData {@ExcelProperty("用户ID")private Long id;@ExcelProperty("用户姓名")private String name;@ExcelProperty("创建时间")@DateTimeFormat("yyyy-MM-dd")private Date createTime;// Getters and Setters
}
4.2 自定义格式

基础概念

在 EasyExcel 中,设置单元格格式主要涉及以下几个类和接口:

  • WriteCellStyle:用于定义写操作中的单元格样式。
  • ReadCellStyle:用于定义读操作中的单元格样式。
  • AbstractCellStyleStrategy:抽象类,通过继承这个类可以实现自定义的单元格样式策略。

自定义单元格格式示例

以下是一个如何设置单元格字体、颜色和边框的示例。我们将创建一个自定义的 AbstractCellStyleStrategy,来定义写入 Excel 文件时的单元格样式。

import com.alibaba.excel.write.style.AbstractCellStyleStrategy;
import com.alibaba.excel.write.style.cell.WriteCellStyle;
import org.apache.poi.ss.usermodel.*;public class CustomCellStyleStrategy extends AbstractCellStyleStrategy {private final WriteCellStyle writeCellStyle;public CustomCellStyleStrategy() {// 初始化 WriteCellStylethis.writeCellStyle = new WriteCellStyle();Font font = writeCellStyle.getFont();font.setFontName("Arial");font.setFontHeightInPoints((short) 12);font.setColor(IndexedColors.BLUE.getIndex());CellStyle cellStyle = writeCellStyle.getCellStyle();cellStyle.setFont(font);cellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);cellStyle.setBorderBottom(BorderStyle.THIN);cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());cellStyle.setBorderLeft(BorderStyle.THIN);cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());cellStyle.setBorderRight(BorderStyle.THIN);cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());cellStyle.setBorderTop(BorderStyle.THIN);cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());}@Overrideprotected void initCellStyle(CellStyle cellStyle, CellData cellData) {// Apply custom cell stylecellStyle.cloneStyleFrom(this.writeCellStyle.getCellStyle());}
}

使用自定义单元格格式

在编写 Excel 文件时,将自定义单元格格式应用到数据写入的过程中。以下代码演示如何使用 CustomCellStyleStrategy 来设置 Excel 文件的样式。

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;import java.util.Arrays;
import java.util.List;public class EasyExcelDemo {public static void main(String[] args) {// 创建数据List<List<String>> data = Arrays.asList(Arrays.asList("Name", "Age", "City"),Arrays.asList("Alice", "30", "New York"),Arrays.asList("Bob", "25", "Los Angeles"));// 创建 ExcelWriterExcelWriterBuilder writerBuilder = EasyExcel.write("demo.xlsx");writerBuilder.registerWriteHandler(new CustomCellStyleStrategy());// 创建 SheetWriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();// 写入数据EasyExcel.write("demo.xlsx").registerWriteHandler(new CustomCellStyleStrategy()).sheet("Sheet1").doWrite(data);}
}

业务开发示例

在实际业务开发中,自定义单元格格式可能用于以下场景:

  • 财务报表:需要突出显示特定的数值或计算结果(例如,利润或亏损)。
  • 数据导出:生成的报告需要特定的格式以便于阅读和分析。
  • 统计报告:数据表格中的不同部分需要不同的样式以区分重要信息。

例如,在财务报表中,可以通过不同颜色突出显示负数和正数。或在销售数据中,通过字体加粗来标记重点销售人员。

public class FinancialReportCellStyleStrategy extends AbstractCellStyleStrategy {@Overrideprotected void initCellStyle(CellStyle cellStyle, CellData cellData) {if (cellData.getStringValue().startsWith("-")) {cellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());} else {cellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());}cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【java】RuoYi-Vue前后端分离版本-登陆请求流程解析
  • OpenAI推出GPT-4o微调功能
  • Nuitka 打包 exe 软件步骤
  • JSON, YAML, XML, CSV交互可视化
  • 设计模式六大原则(一)--单一职责原则
  • 一站式NVR模组解决方案:基于海思 3520D芯片的完整源码与系统集成
  • 基于Python的机器学习系列(7):多元逻辑回归
  • GT IP中的Sequence Max Skew
  • Git入门 -- 分支
  • 基于人工智能、三维视觉、混合现实等技术的智慧能源开源了
  • 使用SSMS连接和查询 SQL Server 实例
  • 基于深度学习的环境感知系统
  • 设计模式-结构型模式(第五章)
  • 【C++】01背包问题暴力,记忆,动态规划解法
  • 算法笔记|Day26贪心算法IV
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • Angular 4.x 动态创建组件
  • Cookie 在前端中的实践
  • Create React App 使用
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • JS字符串转数字方法总结
  • KMP算法及优化
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • NSTimer学习笔记
  • ubuntu 下nginx安装 并支持https协议
  • 对JS继承的一点思考
  • 跨域
  • 前端之React实战:创建跨平台的项目架构
  • 三分钟教你同步 Visual Studio Code 设置
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 推荐一个React的管理后台框架
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 字符串匹配基础上
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • $GOPATH/go.mod exists but should not goland
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (LeetCode) T14. Longest Common Prefix
  • (第三期)书生大模型实战营——InternVL(冷笑话大师)部署微调实践
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (含笔试题)深度解析数据在内存中的存储
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转)原始图像数据和PDF中的图像数据
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .NET 5种线程安全集合
  • .NET BackgroundWorker
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .net使用excel的cells对象没有value方法——学习.net的Excel工作表问题
  • /etc/fstab和/etc/mtab的区别
  • ?