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

news2024/9/20 10:56:03

在这里插入图片描述

文章目录

    • 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<>();
            
            @Override
            public void invoke(UserData data, AnalysisContext context) {
                dataList.add(data);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                // Process the dataList or persist it to the database
                dataList.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 {
    
    @Autowired
    private UserRepository userRepository;
    
    @Override
    public 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 {

    @Autowired
    private 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 {

    @Autowired
    private UserService userService;

    public void importUserData(String fileName) {
        EasyExcel.read(fileName, UserData.class, new AnalysisEventListener<UserData>() {
            @Override
            public void invoke(UserData userData, AnalysisContext context) {
                // Save user data to the database
                userService.save(userData);
            }

            @Override
            public 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> {

    @Override
    public Class supportJavaTypeKey() {
        return Date.class;
    }

    @Override
    public CellData<?> convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
        // Format the date as a string
        String formattedDate = DateUtils.formatDate(value, "yyyy-MM-dd");
        return new CellData<>(formattedDate);
    }

    @Override
    public Date convertToJavaData(CellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
        // Parse the date string back to Date object
        return 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() {
        // 初始化 WriteCellStyle
        this.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());
    }

    @Override
    protected void initCellStyle(CellStyle cellStyle, CellData cellData) {
        // Apply custom cell style
        cellStyle.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")
        );

        // 创建 ExcelWriter
        ExcelWriterBuilder writerBuilder = EasyExcel.write("demo.xlsx");
        writerBuilder.registerWriteHandler(new CustomCellStyleStrategy());

        // 创建 Sheet
        WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();

        // 写入数据
        EasyExcel.write("demo.xlsx")
                .registerWriteHandler(new CustomCellStyleStrategy())
                .sheet("Sheet1")
                .doWrite(data);
    }
}

业务开发示例

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

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

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

public class FinancialReportCellStyleStrategy extends AbstractCellStyleStrategy {

    @Override
    protected 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);
    }
}

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

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

相关文章

Directory Opus 添加管理员获得所有权右键菜单

Directory Opus 添加管理员获得所有权右键菜单 在windows的资源管理器中添加管理员获得所有权的右键菜单很容易,通过注册表就可以了. 但是在Directory Opus需要另外的操作方式, 点击设置->文件类型: 选择运行DOpus函数,因为我的资源管理器已经有这个右键了,就选这个: …

营运管理系统应用架构设计

集中营运系统2020年1月《银行业集中营运规范(JR/T0173-2020号)》标准由全国金融标准化技术委员会审查通过,并由中国人民银行作为银发〔2020〕10号文件正式发布。集中运营的建设核心应该围绕多元化作业和运营能力共享两大方面服务。集中营运的系统建设方向如图10-01所示。 图…

ARP协议分析

目录 实验设备和环境 实验记录 1、ARP报文分析 &#xff08;1&#xff09;建立实验拓扑 &#xff08;2&#xff09;设置抓包接口 &#xff08;3&#xff09;启动设备&#xff0c;开始抓包 &#xff08;4&#xff09;协议分析 ARP代理 &#xff08;1&#xff09;建立实…

如何科学设定短信群发频率

在利用短信群发作为营销策略时&#xff0c;平衡好发送频率至关重要。过于频繁的短信可能招致客户反感甚至被屏蔽&#xff0c;而发送不足则可能导致品牌信息被遗忘。因此&#xff0c;精准把握短信群发频率&#xff0c;是提升客户体验与品牌记忆度的关键。以下是几个常见行业短信…

YOLOv5改进 | 模块融合 | C3融合可变形自注意力模块【模块缝合】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录&#xff1a; 《YOLOv5入门 改…

豆瓣评分8.7!Python pandas创始人亲码的数据分析入门手册!

在众多解释型语言中&#xff0c;Python最大的特点是拥有一个巨大而活跃的科学计算社区。进入21世纪以来&#xff0c;在行业应用和学术研究中采用python进行科学计算的势头越来越猛。 近年来&#xff0c;由于Python有不断改良的库(主要是pandas)&#xff0c;使其成为数据处理任…

原神单机版【无脑一键搭建】纯单机*非私服*稳定版*

版本介绍 版本3.7、4.0、4.0、4.4、4.5、4.6稳定版【过分追新并不稳&#xff0c;合理才完美】 独家原神&#xff0c;游戏内自带剧情任务&#xff0c;完美仿官&#xff0c;一比一完美复制&#xff01; 已经拥有完美剧情、任务、副本、卡池、深渊、全物品、和全部功能和皮肤。 …

【漏洞复现】微商城系统 goods SQL注入漏洞

声明&#xff1a;本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动&#xff0c;将与本文档的作者或发布者无关。 一、漏洞描述 微商城是基于微信这一广受欢迎的社交平台的商业应用&#xff0c;利用微信的广泛用户基础和快速传播特性&…

安泰ATA-7015高压放大器在机器人测试中的应用研究

随着机器人技术的快速发展&#xff0c;机器人在各个领域的应用日益广泛。然而&#xff0c;要确保机器人能够稳定、准确地完成各种任务&#xff0c;就需要对其进行严格的测试和评估。在机器人测试过程中&#xff0c;高压放大器作为一种关键的测试设备&#xff0c;发挥着不可替代…

dll文件丢失最简单的修复方法——电脑丢失dll文件一键修复

在日常使用Windows操作系统的过程中&#xff0c;DLL文件由于各种原因丢失或损坏是一个非常常见的问题。这可能导致软件运行不稳定或无法启动等问题&#xff0c;给用户带来诸多不便。尽管手动寻找并替换相应的DLL文件是一个可行的解决方案&#xff0c;但对于大多数用户而言&…

Linux修改密码出现 “passwd: Authentication token manipulation error”

文章目录 1. 问题现象2. 解决方法 1. 问题现象 修改密码出现&#xff1a; passwd: Authentication token manipulation error。 passwd root2. 解决方法 1.查看文件的扩展信息。 lsattr 命令用于显示文件的扩展属性&#xff0c;包括文件的特殊标志位。 /etc/passwd 是一个…

Java语言程序设计——篇十五(3)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 欢迎大家&#xff1a;这里是我的学习笔记、总结知识的地方&#xff0c;喜欢的话请三连&#xff0c;有问题可以私信&#x1f333;&#x1f333;&…

设备巡检系统

在现代工业生产和各类设施管理中&#xff0c;设备的稳定运行至关重要。而凡尔码设备巡检系统的出现&#xff0c;为确保设备的可靠运转提供了强大的助力。 传统的纸质设备巡检容易作假、统计不及时、汇总困难、容易丢失、记录样式不丰富。而凡尔码设备巡检平台有着多种功能&…

考电工证,学历证丢了为什么能报名?

在面对学历证书遗失的情况下&#xff0c;许多人可能会感到焦虑和无助。幸运的是&#xff0c;如果你确认自己具有初中及以上学历&#xff0c;即使学历证书不慎丢失&#xff0c;仍有几种方法可以证明你的教育背景。以下是三种可行的替代方案&#xff1a; 户口本个人页拍照 首先&a…

PXE-Kickstart高效批量装机

文章目录 PXE高效批量网络装机安装顺序PXE批量装机部署优点基本部署过程 具体过程pxe---批量安装Kickstart---无人值守安装 实操pxe部分一、安装TFTP 服务二、修改TFTP服务的配置文件三、启用 TFTP服务四、安装DHCP服务五、修改DHCP服务的配置文件六、启用DHCP服务七、准备 Lin…

五套随机小姐姐短视频引流网站源码+最新API

简介&#xff1a; 五套随机小姐姐短视频引流网站源码最新API 运行环境 PHP 图片&#xff1a; 本文网址&#xff1a;https://www.songshuan.com/live-2741.html 转载请声明来自&#xff1a;松栓源码网 - 五套随机小姐姐短视频引流网站源码最新API

详解线索分层的目的、维度与创新实践

线索分层是一个系统性的过程&#xff0c;旨在更有效地管理、跟踪和利用线索资源。这一过程可以借鉴多种策略和方法&#xff0c;特别是在用户运营和市场营销中。 1、线索分层的目的 线索分层的主要目的是根据线索的不同特征或成熟度&#xff0c;将其分类管理&#xff0c;以便更…

OpenAI gym and Python threading

题意&#xff1a;OpenAI Gym 和 Python 线程处理 问题背景&#xff1a; I am working on a variation of A3C/ACER and I have several workers, each running on its own thread. I am using OpenAI gym environments. 我正在开发 A3C/ACER 的一个变体&#xff0c;并且有多个…

为什么Redis6.0引入了多线程?

2020年5月份&#xff0c;Redis正式推出了6.0版本&#xff0c;这个版本中有很多重要的新特性&#xff0c;其中多线程特性引起了广泛关注。 但是&#xff0c;需要提醒大家的是&#xff0c;Redis 6.0中的多线程&#xff0c;也只是针对处理网络请求过程采用了多线程&#xff0c;而数…

C++竞赛初阶L1-13-第五单元-循环嵌套(29~30课)537: T456456 质因数分解

题目内容 已知正整数 n 是两个不同的质数的乘积&#xff0c;试求出较大的那个质数。 输入格式 输入只有一行&#xff0c;包含一个正整数 n&#xff08;6<n<109&#xff09;。 输出格式 输出只有一行&#xff0c;包含一个正整数 p&#xff0c;即较大的那个质数。 样例…