使用Java从Excel读取值

2025/04/13

1. 概述

对于Microsoft Excel文件来说,从不同的单元格读取值可能会有些棘手;Excel文件是按行和单元格组织的电子表格,其中可以包含字符串、数字、日期、布尔值甚至公式值。Apache POI是一个库,提供了一整套工具来处理不同的Excel文件和值类型

在本教程中,我们将重点学习如何处理Excel文件、遍历行和单元格,以及如何使用正确的方式读取每个单元格的值类型。

2. Maven依赖

让我们首先将Apache POI依赖添加到pom.xml:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.3.0</version>
</dependency>

可以在Maven Central找到最新版本的poi-ooxml

3. Apache POI概述

层次结构从工作簿开始,它代表整个Excel文件,每个文件可以包含一个或多个工作表,这些工作表是行和单元格的集合。根据Excel文件的版本,HSSF是表示旧版Excel文件(.xls)的类的前缀,而XSSF则用于表示最新版本(.xlsx)。因此,我们有:

  • XSSFWorkbook和HSSFWorkbook类代表Excel工作簿
  • Sheet接口代表Excel工作表
  • Row接口表示行
  • Cell接口代表单元格

3.1 处理Excel文件

首先,我们打开要读取的文件,并将其转换为FileInputStream进行进一步处理。FileInputStream的构造函数会抛出java.io.FileNotFoundException异常,因此我们需要将其封装在try-catch块中,并在最后关闭该流:

public static void readExcel(String filePath) {
    File file = new File(filePath);
    try {
        FileInputStream inputStream = new FileInputStream(file);
        // ...
        inputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

3.2 遍历Excel文件

成功打开InputStream后,就可以创建XSSFWorkbook并遍历每个工作表的行和单元格了。如果我们知道工作表的确切数量或特定工作表的名称,我们可以分别使用XSSFWorkbook的getSheetAt(int index)和getSheet(String sheetName)方法。

由于我们想要读取任何类型的Excel文件,我们将使用3个嵌套的for循环遍历所有工作表,一个用于工作表,一个用于每个工作表的行,最后一个用于每个工作表的单元格

为了本教程的目的,我们仅将数据打印到控制台:

FileInputStream inputStream = new FileInputStream(file);
Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream);
for (Sheet sheet : baeuldungWorkBook) {
    // ...
}

然后,为了遍历工作表的行,我们需要找到从工作表对象中获取的第一行和最后一行的索引:

int firstRow = sheet.getFirstRowNum();
int lastRow = sheet.getLastRowNum();
for (int index = firstRow + 1; index <= lastRow; index++) {
    Row row = sheet.getRow(index);
}

最后,我们对单元格执行相同的操作。此外,在访问每个单元格时,我们可以选择传递一个MissingCellPolicy值,该值基本上告诉POI当单元格值为空或null时应返回什么。MissingCellPolicy枚举包含三个枚举值:

  • RETURN_NULL_AND_BLANK
  • RETURN_BLANK_AS_NULL
  • CREATE_NULL_AS_BLANK

单元格迭代的代码如下:

for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) {
    Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
    // ...
}

3.3 读取Excel中的单元格值

正如我们之前提到的,Microsoft Excel的单元格可以包含不同类型的值,因此区分不同单元格值类型并使用适当的方法提取值非常重要。以下是所有值类型的列表:

  • NONE
  • NUMERIC
  • STRING
  • FORMULA
  • BLANK
  • BOOLEAN
  • ERROR

我们将重点介绍4种主要的单元格值类型:NUMERIC、STRING、BOOLEAN和FORMULA,其中最后一种包含前三种类型的计算值。

让我们创建一个辅助方法,它基本上会检查每个值的类型,并根据类型使用适当的方法来访问该值。它也可以把单元格值当作字符串,并使用相应的方法进行检索。

有两点值得注意;首先,日期值存储为数字值,并且如果单元格的值类型为FORMULA,我们需要使用getCachedFormulaResultType()而不是getCellType()方法来检查公式的计算结果

public static void printCellValue(Cell cell) {
    CellType cellType = cell.getCellType().equals(CellType.FORMULA)
            ? cell.getCachedFormulaResultType() : cell.getCellType();
    if (cellType.equals(CellType.STRING)) {
        System.out.print(cell.getStringCellValue() + " | ");
    }
    if (cellType.equals(CellType.NUMERIC)) {
        if (DateUtil.isCellDateFormatted(cell)) {
            System.out.print(cell.getDateCellValue() + " | ");
        } else {
            System.out.print(cell.getNumericCellValue() + " | ");
        }
    }
    if (cellType.equals(CellType.BOOLEAN)) {
        System.out.print(cell.getBooleanCellValue() + " | ");
    }
}

现在,我们需要做的就是在单元格循环中调用printCellValue方法即可。以下是完整代码片段:

// ...
for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) {
    Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
    printCellValue(cell);
}
// ...

4. 总结

在本文中,我们展示了一个使用Apache POI读取Excel文件和访问不同单元格值的示例项目。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章