Java Apache POI - 是否可以获得比 g​​etCellType 方法返回的更详细的单元格类型?

标签 java excel apache-poi

我正在验证 Excel 电子表格。我想确保特定列中的所有单元格存储相同的数据类型。

为此,我迭代行,然后收集一组 CellType由 getCellType 方法返回。一旦我有了这样的集合,我就可以确保该集合只有一项以及它是否是预期的类型。

<小时/>

问题

不幸的是,Apache POI CellType 非常通用。例如,NUMERIC 用于整数和日期类型。他们也不向我提供有关 field 大小的信息。 此外,我注意到有时日期被识别为字符串。

我的问题是:

  • 我是否应该尝试创建自己的更具体细胞类型的枚举,并尝试将单元格内容解析为这些枚举之一(此解决方案似乎是一个重大瓶颈/可能会减慢我的测试速度),
  • 或者 Apache POI 中是否有其他我应该使用的方法,
  • 或者我应该应用不同的库来解决我的问题吗?

最佳答案

您所观察到的不是 apache poi 的缺点,而是 Excel 存储单元格内容的方式。仅存在 StringNumericBooleanErrorFormula 类型的单元格在 Excel 中。数字单元格是否包含日期仅由单元格的数字格式决定。如果单元格的格式为日期,则它会将数字显示为日期,否则不会。如果单元格的类型为 String,但该字符串看起来像日期,则即使 Excel 也不会自动将该内容作为日期处理。

因此唯一的方法是确定不同的单元格内容,如Busy Developers' Guide to HSSF and XSSF Features - Getting the cell contents所示。主要按细胞类型来区分。对于Numeric单元格类型,通过DateUtil.isCellDateFormatted进行额外区分。对于公式单元格,您可能还需要获取 result type of the formula .

完整示例,读取 SAMPLE.xlsx 第一页的所有单元格并尽可能准确地确定单元格类型。

import java.io.FileInputStream;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.usermodel.CellType;

class ReadExcelExample {

 public static void main(String[] args) throws Exception {

  Workbook wb  = WorkbookFactory.create(new FileInputStream("SAMPLE.xlsx"));

  Sheet sheet = wb.getSheetAt(0);

  for (Row row : sheet) {
   for (Cell cell : row) {
    CellReference cellRef = new CellReference(row.getRowNum(), cell.getColumnIndex());
    System.out.print(cellRef.formatAsString() + " ");

    //switch (cell.getCellTypeEnum()) { // until apache poi 3.17
    switch (cell.getCellType()) { // from apache poi 4.0.0
     case STRING:
      System.out.println("is a string cell: " + cell.getRichStringCellValue().getString());
      break;
     case NUMERIC:
      if (DateUtil.isCellDateFormatted(cell)) {
       System.out.println("is a date cell: " + cell.getDateCellValue());
      } else {
       System.out.println("is a numeric cell: " + cell.getNumericCellValue());
      }
      break;
     case BOOLEAN:
      System.out.println("is a boolean cell: " + cell.getBooleanCellValue());
      break;
     case FORMULA:
      System.out.print("is a formula cell: " + cell.getCellFormula());
      //switch (cell.getCachedFormulaResultTypeEnum()) { // until apache poi 3.17
      switch (cell.getCachedFormulaResultType()) { // from apache poi 4.0.0
       case STRING:
        System.out.println(" returning a string: " + cell.getRichStringCellValue().getString());
        break;
       case NUMERIC:
        if (DateUtil.isCellDateFormatted(cell)) {
         System.out.println(" returning a date: " + cell.getDateCellValue());
        } else {
         System.out.println(" returning a number: " + cell.getNumericCellValue());
        }
        break;
       case BOOLEAN:
        System.out.println(" returning an boolean: " + cell.getBooleanCellValue());
        break;
       case ERROR:
       System.out.println(" returning an error: " + cell.getErrorCellValue());
        break;
       default:
        System.out.println("default formula cell"); //should never occur
      }
      break;
     case ERROR:
      System.out.println("is a error cell: " + cell.getErrorCellValue());
      break;
     case BLANK:
      System.out.println("is a blank cell");
      break;
     default:
      System.out.println("default cell"); //should never occur
    }
   }
  }

  wb.close();

 }
}

关于Java Apache POI - 是否可以获得比 g​​etCellType 方法返回的更详细的单元格类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59580640/

相关文章:

java - 在 Java HTTP 请求中包含 .pem 证书

java - 以编程方式从另一个项目获取类

java - 如何将容器内的内部框架图标化到特定位置

vba - 如何使用 VBA 在 Excel 2016 中获取筛选条件?

java excel 到 csv 文件转换

java - 将 .xltx 转换为 .xlsx

Java - Apache POI 在特定单元读取 XSSF 文件

java - 使用 Apache POI 读取 xlsx 文件时出现异常(org.apache.poi.openxml4j.exception - 无内容类型 [M1.13])?

java - 在表单 {} 中将数组作为参数传递

vba - 如果在该行中找不到字符 ","或 Chr(44),则删除整行。对所有行重复