杰瑞科技汇

Java读取Excel有哪些常用方法?

主流方法概览

方法 主要库 优点 缺点 适用场景
Apache POI poi, poi-ooxml 功能最强大,支持所有新旧Excel格式(.xls, .xlsx),社区活跃,文档丰富。 依赖库较大,内存消耗高(特别是处理大文件时),API相对繁琐。 传统的、功能需求全面的Excel操作,尤其是处理.xls格式。
EasyExcel easyexcel 阿里巴巴开源,内存占用极低(基于SAX模型),性能好,API简单易用。 相对POI较新,社区和生态不如POI庞大。 现代首选,尤其适合处理大数据量的Excel文件,或对内存敏感的应用。
JExcelApi jxl 轻量级,API简单,只支持旧版.xls格式。 已停止更新多年,不支持.xlsx格式,功能有限。 简单的旧版Excel读取任务,且项目依赖要求极轻量。
OpenCSV + Apache POI opencsv, poi 专门处理CSV格式,可以与POI结合使用。 本质上是处理CSV,并非原生Excel格式。 读取或写入CSV(逗号分隔值)文件。

Apache POI (功能最全面)

Apache POI是Java操作Office文档的“老牌”和“标准”库,它支持.xls(HSSF)和.xlsx(XSSF)格式。

Java读取Excel有哪些常用方法?-图1
(图片来源网络,侵删)

添加Maven依赖

在你的pom.xml文件中添加以下依赖:

<!-- 用于处理 .xlsx 格式 (Office 2007+) -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.5</version> <!-- 建议使用最新稳定版 -->
</dependency>
<!-- 用于处理 .xls 格式 (Office 97-2003) -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.5</version>
</dependency>

代码示例 (读取 .xlsx 文件)

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
public class PoiExcelReader {
    public static void main(String[] args) {
        String filePath = "path/to/your/file.xlsx"; // 替换为你的Excel文件路径
        try (FileInputStream fis = new FileInputStream(filePath);
             Workbook workbook = new XSSFWorkbook(fis)) { // 根据文件类型选择 XSSFWorkbook 或 HSSFWorkbook
            // 获取第一个工作表
            Sheet sheet = workbook.getSheetAt(0);
            // 遍历每一行 (从0开始)
            for (Row row : sheet) {
                // 遍历每一列
                for (Cell cell : row) {
                    // 根据单元格类型获取值
                    switch (cell.getCellType()) {
                        case STRING:
                            System.out.print(cell.getStringCellValue() + "\t");
                            break;
                        case NUMERIC:
                            // 处理日期和数字
                            if (DateUtil.isCellDateFormatted(cell)) {
                                System.out.print(cell.getDateCellValue() + "\t");
                            } else {
                                System.out.print(cell.getNumericCellValue() + "\t");
                            }
                            break;
                        case BOOLEAN:
                            System.out.print(cell.getBooleanCellValue() + "\t");
                            break;
                        case FORMULA:
                            System.out.print(cell.getCellFormula() + "\t");
                            break;
                        default:
                            System.out.print("UNKNOWN\t");
                    }
                }
                System.out.println(); // 换行
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

POI的内存问题

POI在读取.xlsx文件时,默认会将整个文件加载到内存中,如果文件很大(比如几百MB),很容易导致OutOfMemoryError,为了解决这个问题,POI提供了SXSSFWorkbook(流式API),它会在内存中只保留一定数量的行,其余的会临时写入磁盘。


EasyExcel (高性能,推荐)

EasyExcel是阿里巴巴开源的一个项目,它解决了POI的内存问题,在读取大文件时表现优异,API也更简洁。

添加Maven依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version> <!-- 建议使用最新稳定版 -->
</dependency>

代码示例 (读取 .xlsx 文件)

EasyExcel的核心思想是监听器模式,你定义一个监听器,EasyExcel在读取每一行数据时,会回调监听器中的方法。

Java读取Excel有哪些常用方法?-图2
(图片来源网络,侵删)

第一步:创建数据模型(实体类)

import com.alibaba.excel.annotation.ExcelProperty;
// @ExcelProperty注解用于指定Excel中的列名
public class DemoData {
    @ExcelProperty("标题1")
    private String string;
    @ExcelProperty("标题2")
    private Double doubleData;
    @ExcelProperty("标题3")
    private Integer integer;
    // 必须要有无参构造函数
    public DemoData() {
    }
    // Getters and Setters
    public String getString() { return string; }
    public void setString(String string) { this.string = string; }
    public Double getDoubleData() { return doubleData; }
    public void setDoubleData(Double doubleData) { this.doubleData = doubleData; }
    public Integer getInteger() { return integer; }
    public void setInteger(Integer integer) { this.integer = integer; }
    @Override
    public String toString() {
        return "DemoData{" +
                "string='" + string + '\'' +
                ", doubleData=" + doubleData +
                ", integer=" + integer +
                '}';
    }
}

第二步:创建监听器

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.ArrayList;
import java.util.List;
// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取new,然后里面用到spring可以构造方法传进去
public class DemoDataListener extends AnalysisEventListener<DemoData> {
    // 可以通过实例变量来存储读取到的数据
    private List<DemoData> dataList = new ArrayList<>();
    /**
     * 这个每一条数据解析都会来调用
     * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(DemoData data, AnalysisContext context) {
        System.out.println("解析到一条数据:" + data);
        dataList.add(data);
    }
    /**
     * 所有数据解析完成了 都会来调用
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也可以保存数据到数据库
        System.out.println("所有数据解析完成!");
        System.out.println("总共解析了 " + dataList.size() + " 条数据。");
    }
    public List<DemoData> getDataList() {
        return dataList;
    }
}

第三步:编写主程序进行读取

import com.alibaba.excel.EasyExcel;
import java.util.List;
public class EasyExcelReaderDemo {
    public static void main(String[] args) {
        String fileName = "path/to/your/file.xlsx"; // 替换为你的Excel文件路径
        // 需要指定读用哪个class去读,然后读取第一个sheet
        DemoDataListener listener = new DemoDataListener();
        EasyExcel.read(fileName, DemoData.class, listener).sheet().doRead();
        // 读取完成后,可以从监听器中获取数据
        List<DemoData> dataList = listener.getDataList();
        // ... 对dataList进行后续操作
    }
}

如何选择?

场景 推荐方法 理由
新项目,对性能和内存有要求 EasyExcel API简单,性能好,内存占用低,是现代Java应用处理Excel的首选。
需要处理非常复杂的Excel格式 Apache POI POI功能最全面,能处理各种复杂的样式、图表、公式等。
项目是旧系统,已经在用POI Apache POI 继续使用现有技术栈,避免引入新的依赖和风险,对于大文件,可以考虑升级到SXSSFWorkbook
只是处理简单的.xls文件 JExcelApiPOI 如果追求极简,可以用JExcelApi,如果功能可能扩展,用POI更稳妥。
处理CSV文件 OpenCSV 专门为CSV设计,非常高效。
  • 如果你是新手或正在启动一个新项目,强烈推荐使用 EasyExcel,它的学习曲线更平缓,并且在处理大数据量时表现无与伦比。
  • 如果你需要兼容旧系统或处理POI独有的复杂功能Apache POI 是不二之选。

希望这个详细的解释能帮助你选择最适合你项目的方法!

Java读取Excel有哪些常用方法?-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇