Apache POI 读取Excel单元格值
1.简介
在 Java 中读取 Excel 文件时,我们通常希望读取单元格的值以执行一些计算或生成报告。但是,我们可能会遇到一个或多个包含公式而不是原始数据值的单元格。那么,我们如何获得这些单元格的实际数据值呢?
在本教程中,我们将研究使用Apache POI Java 库读取 Excel 单元格值的不同方法——而不是计算单元格值的公式。
有两种方法可以解决这个问题:
- 获取单元格的最后一个缓存值
- 在运行时评估公式以获取单元格值
2. Maven依赖
我们需要在我们的 pom.xml 文件中为 Apache POI 添加以下依赖项:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.0</version>
</dependency>
可以从 Maven Central 下载最新版本的poi-ooxml 。
3. 获取最后一个缓存值
当公式计算单元格的值时,Excel 会为单元格存储两个对象。一是公式本身,二是缓存值。缓存的值包含公式计算的最后一个值。
所以这里的想法是我们可以获取最后一个缓存值并将其视为单元格值。最后一个缓存值是正确的单元格值可能并不总是正确的。但是,当我们使用已保存的 Excel 文件并且最近没有对文件进行修改时,最后缓存的值应该是单元格值。
让我们看看如何获取单元格的最后一个缓存值:
FileInputStream inputStream = new FileInputStream(new File("temp.xlsx"));
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet sheet = workbook.getSheetAt(0);
CellAddress cellAddress = new CellAddress("C2");
Row row = sheet.getRow(cellAddress.getRow());
Cell cell = row.getCell(cellAddress.getColumn());
if (cell.getCellType() == CellType.FORMULA) {
switch (cell.getCachedFormulaResultType()) {
case BOOLEAN:
System.out.println(cell.getBooleanCellValue());
break;
case NUMERIC:
System.out.println(cell.getNumericCellValue());
break;
case STRING:
System.out.println(cell.getRichStringCellValue());
break;
}
}
4. 评估公式以获取单元格值
Apache POI 提供了一个FormulaEvaluator类,它使我们能够计算 Excel 表格中公式的结果。
因此,我们可以直接使用FormulaEvaluator在运行时计算单元格值。FormulaEvaluator类提供了一个名为evaluateFormulaCell 的方法,该方法计算给定Cell对象的单元格值并返回一个CellType对象,该对象表示单元格值的数据类型。
让我们看看这种方法的实际效果:
// existing Workbook setup
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
// existing Sheet, Row, and Cell setup
if (cell.getCellType() == CellType.FORMULA) {
switch (evaluator.evaluateFormulaCell(cell)) {
case BOOLEAN:
System.out.println(cell.getBooleanCellValue());
break;
case NUMERIC:
System.out.println(cell.getNumericCellValue());
break;
case STRING:
System.out.println(cell.getStringCellValue());
break;
}
}
5. 选择哪种方法
这两种方法之间的简单区别在于,第一种方法使用最后一个缓存值,第二种方法在运行时计算公式。
如果我们正在使用已保存的 Excel 文件并且我们不打算在运行时对该电子表格进行更改,那么缓存值方法会更好,因为我们不必评估公式。
但是,如果我们知道我们将在运行时进行频繁的更改,那么最好在运行时评估公式以获取单元格值。