如何在 Java 中使用 Apache POI读取 Excel 文件

x33g5p2x  于2021-10-16 转载在 Java  
字(5.6k)|赞(0)|评价(0)|浏览(532)

Excel 文件(电子表格)被世界各地的人们广泛用于与表格数据的组织、分析和存储相关的各种任务。

由于 excel 文件如此普遍,当我们需要从 excel 文件中读取数据或生成 excel 格式的报告时,我们开发人员经常会遇到用例。

在本文中,我将向您展示如何使用名为 Apache POI 的非常简单但功能强大的开源库在 Java 中读取 Excel 文件。

在下一篇文章中,您将学习如何使用 Apache POI 创建和写入 excel 文件。

让我们开始吧!

依赖

首先,我们需要添加所需的依赖项,以便在我们的项目中包含 Apache POI。如果使用 maven,则需要在 pom.xml 文件中添加以下依赖项 -

maven

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</dependency>

gradle

如果您使用 gradle,那么您可以将以下内容添加到您的 build.gradle 文件中

compile "org.apache.poi:poi:3.17"
compile "org.apache.poi:poi-ooxml:3.17"

第一个依赖项 poi 用于处理旧的 Microsoft 二进制文件格式的 excel。这些文件格式具有 .xls 扩展名。

第二个依赖项 poi-ooxml 用于处理较新的基于 XML 的文件格式。这些文件格式具有 .xlsx 扩展名。

我们将阅读的示例 Excel 文件

以下是我们将在代码中读取的示例 Excel 文件。它是使用 Google 表格创建的,并具有 .xlsx 扩展名。

请注意,尽管示例文件是基于 XML 的较新文件格式 (.xlsx)。我们将编写的代码适用于两种类型的文件格式 - .xls.xlsx

Apache POI 术语

Apache POI excel 库围绕以下四个关键接口——

工作簿: 工作簿是电子表格的高级表示。
1.
工作表: 一个工作簿可能包含许多工作表。我们在上一节中查看的示例 excel 文件有两张表 - EmployeeDepartment
1.
**行:**顾名思义,它代表电子表格中的一行。
1.
单元格: 单元格代表电子表格中的一列。

HSSF 和 XSSF 实现 -

Apache POI 库由上述所有接口的两种不同实现组成。

HSSF(Horrible SpreadSheet Format): POI 的高级接口(如 HSSFWorkbookHSSFSheetHSSFRowHSSFCell] 的 HSSF 实现用于使用旧二进制文件格式的 excel 文件 - .xls
1.
XSSF(XML 电子表格格式): XSSF 实现用于处理较新的基于 XML 的文件格式 - .xlsx

###使用Apache POI读取excel文件的程序

以下程序向您展示了如何使用 Apache POI 读取 excel 文件。由于我们没有使用任何文件格式特定的 POI 类,该程序将适用于两种类型的文件格式 - .xls.xlsx

该程序显示了迭代 Excel 文件中的工作表、行和列的三种不同方式 -

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;

public class ExcelReader {
    public static final String SAMPLE_XLSX_FILE_PATH = "./sample-xlsx-file.xlsx";

    public static void main(String[] args) throws IOException, InvalidFormatException {

        // Creating a Workbook from an Excel file (.xls or .xlsx)
        Workbook workbook = WorkbookFactory.create(new File(SAMPLE_XLSX_FILE_PATH));

        // Retrieving the number of sheets in the Workbook
        System.out.println("Workbook has " + workbook.getNumberOfSheets() + " Sheets : ");

        /* ============================================================= Iterating over all the sheets in the workbook (Multiple ways) ============================================================= */

        // 1. You can obtain a sheetIterator and iterate over it
        Iterator<Sheet> sheetIterator = workbook.sheetIterator();
        System.out.println("Retrieving Sheets using Iterator");
        while (sheetIterator.hasNext()) {
            Sheet sheet = sheetIterator.next();
            System.out.println("=> " + sheet.getSheetName());
        }

        // 2. Or you can use a for-each loop
        System.out.println("Retrieving Sheets using for-each loop");
        for(Sheet sheet: workbook) {
            System.out.println("=> " + sheet.getSheetName());
        }

        // 3. Or you can use a Java 8 forEach with lambda
        System.out.println("Retrieving Sheets using Java 8 forEach with lambda");
        workbook.forEach(sheet -> {
            System.out.println("=> " + sheet.getSheetName());
        });

        /* ================================================================== Iterating over all the rows and columns in a Sheet (Multiple ways) ================================================================== */

        // Getting the Sheet at index zero
        Sheet sheet = workbook.getSheetAt(0);

        // Create a DataFormatter to format and get each cell's value as String
        DataFormatter dataFormatter = new DataFormatter();

        // 1. You can obtain a rowIterator and columnIterator and iterate over them
        System.out.println("\n\nIterating over Rows and Columns using Iterator\n");
        Iterator<Row> rowIterator = sheet.rowIterator();
        while (rowIterator.hasNext()) {
            Row row = rowIterator.next();

            // Now let's iterate over the columns of the current row
            Iterator<Cell> cellIterator = row.cellIterator();

            while (cellIterator.hasNext()) {
                Cell cell = cellIterator.next();
                String cellValue = dataFormatter.formatCellValue(cell);
                System.out.print(cellValue + "\t");
            }
            System.out.println();
        }

        // 2. Or you can use a for-each loop to iterate over the rows and columns
        System.out.println("\n\nIterating over Rows and Columns using for-each loop\n");
        for (Row row: sheet) {
            for(Cell cell: row) {
                String cellValue = dataFormatter.formatCellValue(cell);
                System.out.print(cellValue + "\t");
            }
            System.out.println();
        }

        // 3. Or you can use Java 8 forEach loop with lambda
        System.out.println("\n\nIterating over Rows and Columns using Java 8 forEach with lambda\n");
        sheet.forEach(row -> {
            row.forEach(cell -> {
                String cellValue = dataFormatter.formatCellValue(cell);
                System.out.print(cellValue + "\t");
            });
            System.out.println();
        });

        // Closing the workbook
        workbook.close();
    }
}

请注意,我们甚至没有使用 HSSFWorkbookXSSFWorkbook 这样的具体类来创建工作簿的实例。我们使用 WorkbookFactory 创建工作簿。这使我们的程序格式独立,它适用于两种类型的文件 - .xls.xlsx

该程序展示了迭代工作表、行和列的三种不同方法。我更喜欢带有 lambda 表达式的 Java 8 forEach 循环。你可以使用任何你喜欢的方法。

请注意,我使用了 DataFormatter 来格式化并获取每个单元格的值作为字符串。

按 CellType 检索单元格值

您可以检查每个单元格的类型,然后使用各种特定于类型的方法检索它的值,而不是使用 DataFormatter 来格式化和获取每个单元格的值作为字符串,而不考虑单元格类型 -

private static void printCellValue(Cell cell) {
    switch (cell.getCellTypeEnum()) {
        case BOOLEAN:
            System.out.print(cell.getBooleanCellValue());
            break;
        case STRING:
            System.out.print(cell.getRichStringCellValue().getString());
            break;
        case NUMERIC:
            if (DateUtil.isCellDateFormatted(cell)) {
                System.out.print(cell.getDateCellValue());
            } else {
                System.out.print(cell.getNumericCellValue());
            }
            break;
        case FORMULA:
            System.out.print(cell.getCellFormula());
            break;
        case BLANK:
            System.out.print("");
            break;
        default:
            System.out.print("");
    }

    System.out.print("\t");
}

您现在可以在主程序中调用上述方法来打印每个单元格的值 -

sheet.forEach(row -> {
    row.forEach(cell -> {
        printCellValue(cell);
    });
    System.out.println();
});

结论

在本文中,您学习了如何使用 Apache POI 库读取 Java 中的 excel 文件。您可以在 github repository 上找到完整的源代码。

相关文章

微信公众号

最新文章

更多