java 读取exc

admin 102 0
Java读取Excel文件常用Apache POI和EasyExcel库,Apache POI支持xls/xlsx格式,通过Workbook、Sheet、Row、Cell对象遍历数据;EasyExcel采用SAX模式读取,内存占用更低,适合大数据量,需引入依赖,处理文件流异常,循环读取单元格内容并转为业务对象,适用于数据导入、报表生成等场景,需注意版本兼容性和性能优化。

Java读取Excel文件的实用指南与代码示例

在数据处理和业务系统中,Excel文件凭借其通用性和易用性,已成为数据存储与交换的重要载体,Java作为企业级开发的主流语言,经常需要实现Excel文件的读取功能,例如批量导入数据、报表解析、历史数据迁移等,本文将详细介绍Java中读取Excel文件的两种主流方式——基于Apache POI和阿里巴巴EasyExcel,并提供具体代码示例,帮助开发者快速上手。

常用Java读取Excel库对比

在Java生态中,处理Excel文件的开源库主要有以下两种,各有特色:

特性 Apache POI EasyExcel(阿里开源)
支持格式 .xls(HSSF)、.xlsx(XSSF) .xls.xlsx.csv
内存占用 较高(尤其处理大文件时) 极低(基于SAX模式,流式读取)
功能丰富度 强(支持复杂格式、图表、公式等) 适中(聚焦核心读写,注解简化开发)
性能表现 中等,大文件处理容易OOM 优秀,百万级数据稳定运行
学习成本 中等(需熟悉HSSF/XSSF API) 较低(注解+监听器模式,代码简洁)
社区支持 成熟,文档丰富 活跃,阿里官方维护

选择建议

  • 小文件(<10MB)或需处理复杂格式(如公式、图表、宏)时,优先选择Apache POI;
  • 大文件(>50MB)或追求高性能开发,推荐EasyExcel;
  • 新项目或注重开发效率,建议使用EasyExcel。

使用Apache POI读取Excel

Apache POI是Java操作Office文档的经典库,支持Excel的读写,本文以最新稳定版(POI 5.2.5)为例,介绍读取.xlsx(Excel 2007+)和.xls(Excel 2003)文件的方法。

环境准备

在Maven项目的pom.xml中添加依赖:

<dependencies>
    <!-- POI核心依赖 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.5</version>
    </dependency>
    <!-- OOXML支持(.xlsx格式) -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.5</version>
    </dependency>
    <!-- 日期处理支持 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-lite</artifactId>
        <version>5.2.5</version>
    </dependency>
</dependencies>

读取.xlsx文件(XSSFWorkbook)

.xlsx基于Open XML格式,使用XSSFWorkbook类操作,以下示例读取Excel中的所有数据并打印:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
public class PoiReadExcel {
    public static void main(String[] args) {
        String filePath = "data.xlsx"; // Excel文件路径
        try (FileInputStream fis = new FileInputStream(filePath);
             Workbook workbook = new XSSFWorkbook(fis)) {
            // 获取第一个Sheet页
            Sheet sheet = workbook.getSheetAt(0);
            // 遍历每一行(跳过标题行)
            for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
                Row row = sheet.getRow(rowNum);
                if (row == null) continue;
                // 遍历每一个单元格
                for (int cellNum = 0; cellNum < row.getLastCellNum(); cellNum++) {
                    Cell cell = row.getCell(cellNum);
                    if (cell == null) continue;
                    // 根据单元格类型获取值
                    String value = getCellValueAsString(cell);
                    System.out.print(value + "\t");
                }
                System.out.println();
            }
        } catch (IOException e) {
            System.err.println("读取Excel失败:" + e.getMessage());
            e.printStackTrace();
        }
    }
    // 将单元格值转换为字符串(兼容不同类型)
    private static String getCellValueAsString(Cell cell) {
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                // 处理数字(避免整数变成科学计数法)
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    // 处理整数和小数
                    double numericValue = cell.getNumericCellValue();
                    return numericValue % 1 == 0 ? 
                        String.valueOf((long) numericValue) : 
                        String.valueOf(numericValue);
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            case BLANK:
                return "";
            default:
                return "";
        }
    }
}

读取.xls文件(HSSFWorkbook)

.xls是Excel 97-2003格式,使用HSSFWorkbook类,代码结构与.xlsx类似,只需将XSSFWorkbook替换为HSSFWorkbook

// 替换workbook的创建方式
Workbook workbook = new HSSFWorkbook(fis);

POI读取注意事项

  1. 资源管理WorkbookFileInputStream必须使用try-with-resources关闭,避免内存泄漏;
  2. 单元格类型:Excel单元格可能为字符串、数字、日期等,需通过getCellType()判断类型后处理;
  3. 空值处理:需判断RowCell是否为null,避免空指针异常;
  4. 日期格式:使用DateUtil.isCellDateFormatted()判断是否为日期格式;
  5. 性能优化:大文件时考虑使用SXSSFWorkbook(流式API)减少内存占用。

使用EasyExcel读取Excel(推荐)

EasyExcel是阿里巴巴开源的Excel处理工具,通过SAX模式(流式读取)解决了POI内存占用高的问题,尤其适合大文件读取,其核心优势是注解映射监听器模式,代码更简洁,性能更优越。

环境准备

Maven依赖(EasyExcel 3.3.2):

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

定义数据模型(注解映射)

通过@ExcelProperty注解将Excel列与Java对象属性绑定:

import com.alibaba.excel.annotation.ExcelProperty;
import java.util.Date;
public class UserData {
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("年龄")
    private Integer age;
    @ExcelProperty("生日")
    private Date birthday;
    @ExcelProperty("邮箱")
    private String email;
    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    public Date getBirthday() { return birthday; }
    public void setBirthday(Date birthday) { this.birthday = birthday; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

监听器模式读取数据

EasyExcel使用监听器模式实现流式读取,内存占用极低:

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.ArrayList;
import java.util.List;
public class EasyExcelReadDemo {
    public static void main(String[] args) {
        String fileName = "user_data.xlsx";
        // 直接读取到List
        List<UserData> dataList = EasyExcel.read(fileName)
                .head(UserData.class)
                .sheet()
                .doReadSync();
        System.out.println("读取到的数据量:" + dataList.size());
        dataList.forEach(System.out::println);
        // 使用监听器模式(推荐大文件

标签: #Excel #POI #解析