使用Apache POI从Excel中提取列名

2025/04/12

1. 简介

无论是读取数据进行处理还是生成报告,高效处理Excel文件都至关重要。Apache POI是一个功能强大的Java库,允许开发人员以编程方式操作Excel文件并与之交互。

在本教程中,我们将探索使用Apache POI从Excel表中读取列名。

我们将首先简要概述POI API,然后,我们将设置所需的依赖并介绍一个简单的数据示例。之后,我们将了解如何从新旧格式的Excel文件中的Excel工作表中提取列名。最后,我们将编写单元测试来验证所有操作是否按预期运行。

2. 依赖和示例设置

让我们首先在pom.xml中添加所需的依赖,包括poi-ooxmlcommons-collections4

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.4</version>
</dependency>

让我们从存储在两个Excel文件中的一些示例数据开始,第一个是food_info.xlsx文件,包含以下列和示例数据:

下一个由consumer_info.xls文件中的消费者数据组成,该文件具有较旧的.xls扩展名,列名由以下内容组成:

接下来我们将按照步骤使用POI提供的API从这些文件中提取列名。

3. 从Excel中提取列名

要使用Apache POI从Excel表中读取列名,我们将创建一个执行以下步骤的方法:

  • 打开Excel文件
  • 访问所需工作表
  • 读取标题行(第一行)以获取列名

3.1 打开Excel文件

首先,我们需要打开Excel文件并创建一个WorkBook实例,POI使用两种不同的抽象(即XSSFWorkbook和HSSFWorkbook)支持.xls和.xlsx文件:

public static Workbook openWorkbook(String filePath) throws IOException {
    try (InputStream fileInputStream = new FileInputStream(filePath)) {
        if (filePath.toLowerCase()
                .endsWith("xlsx")) {
            return new XSSFWorkbook(fileInputStream);
        } else if (filePath.toLowerCase()
                .endsWith("xls")) {
            return new HSSFWorkbook(fileInputStream);
        } else {
            throw new IllegalArgumentException("The specified file is not an Excel file");
        }
    } catch (OLE2NotOfficeXmlFileException | NotOLE2FileException e) {
        throw new IllegalArgumentException(
                "The file format is not supported. Ensure the file is a valid Excel file.", e);
    }
}

本质上,我们使用代表Excel工作簿的WorkBook接口,它是Apache POI中处理Excel文件的顶级对象,XSSFWorkbook是一个实现.xlsx文件WorkBook接口的类。另一方面,HSSFWorkbook类实现了.xls文件WorkBook接口

3.2 访问工作表

现在我们有了一个Workbook,让我们通过工作表名称访问工作簿中的所需工作表:

public static Sheet getSheet(Workbook workbook, String sheetName) {
    return workbook.getSheet(sheetName);
}

POI API中的Sheet接口表示Excel工作簿中的工作表

3.3 读取标题行

使用Sheet对象,我们可以根据需要访问其数据

让我们使用API读取包含工作表所有列名称的标题行,Row接口表示工作表中的一行。简而言之,我们将访问工作表的第一行,并将索引0传递给sheet.get()方法。然后,我们将使用Cell接口提取标题行中的每一列名称。

Cell接口表示一行中的一个单元格

public static List<String> getColumnNames(Sheet sheet) {
    Row headerRow = sheet.getRow(0);
    if (headerRow == null) {
        return Collections.EMPTY_LIST;
    }
    return StreamSupport.stream(headerRow.spliterator(), false)
            .filter(cell -> cell.getCellType() != CellType.BLANK)
            .map(Cell::getStringCellValue)
            .filter(cellValue -> cellValue != null && !cellValue.trim()
                    .isEmpty())
            .map(String::trim)
            .collect(Collectors.toList());
}

这里,我们使用Java Stream迭代每个Cell,我们过滤掉空白单元格以及仅包含空格或空值的单元格。然后,我们使用Cell的getStringCellValue()方法提取剩余每个单元格的字符串值。在本例中,API返回单元格中数据的字符串值。此外,我们还从这些字符串值中去除了空格。最后,我们将这些清理后的字符串值收集到一个列表中并返回。

此时,值得一提的是一个名为getRichStringTextValue()的相关方法,该方法将单元格值检索为RichTextString。这在处理格式化文本(例如,同一单元格中具有不同字体、颜色或样式的文本)时非常有用。如果我们的用例不仅需要提取列名,还需要保留这些列名的格式,那么我们将使用Cell::getRichStringTextValue()进行映射,并将结果存储为List<RichTextString>

4. 单元测试

现在让我们设置单元测试来查看POI API对.xls和.xlsx文件的运行情况:

@Test
public void givenExcelFileWithXLSXFormat_whenGetColumnNames_thenReturnsColumnNames() throws IOException {
    Workbook workbook = ExcelUtils.openWorkbook(XLSX_TEST_FILE_PATH);
    Sheet sheet = ExcelUtils.getSheet(workbook, SHEET_NAME);
    List<String> columnNames = ExcelUtils.getColumnNames(sheet);

    assertEquals(4, columnNames.size());
    assertTrue(columnNames.contains("Category"));
    assertTrue(columnNames.contains("Name"));
    assertTrue(columnNames.contains("Measure"));
    assertTrue(columnNames.contains("Calories"));
    workbook.close();
}

@Test
public void givenExcelFileWithXLSFormat_whenGetColumnNames_thenReturnsColumnNames() throws IOException {
    Workbook workbook = ExcelUtils.openWorkbook(XLS_TEST_FILE_PATH);
    Sheet sheet = ExcelUtils.getSheet(workbook, SHEET_NAME);
    List<String> columnNames = ExcelUtils.getColumnNames(sheet);

    assertEquals(3, columnNames.size());
    assertTrue(columnNames.contains("Name"));
    assertTrue(columnNames.contains("Age"));
    assertTrue(columnNames.contains("City"));

    workbook.close();
}

测试验证了API是否支持从两种类型的Excel文件中读取列名

5. 总结

在本文中,我们探讨了如何使用Apache POI从Excel表格中读取列名。我们首先概述了Apache POI,然后设置了必要的依赖。之后,我们提供了包含代码片段的分步指南,用于实现该解决方案,并包含单元测试以确保正确性。

Apache POI是一个强大的库,它简化了使用Java处理Excel文件的过程,使其成为处理应用程序和Excel之间数据交换的开发人员的宝贵工具。

Show Disqus Comments

Post Directory

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