java - Apache poi 在读取 excel 文件时的奇怪行为

标签 java excel apache apache-poi

我已经使用 Apache POI 库成功读取了 Excel 文件。但是,我收到了它的奇怪行为,我不确定为什么会发生。

如果我创建一个新的 Excel 文件并调整所需数据,如下所示:

enter image description here

根本不会读取电子邮件列第一个设置的空单元格(忽略)。

但是,如果我修改文件并更改同一文件的字体或字体大小,Apache POI 会成功读取空电子邮件单元格。

默认字体设置(不读取空单元格):

enter image description here

我从该方法收到的数组:

[Hari Krishna, 445444, 986544544]

更改字体大小(成功读取空单元格):

enter image description here

我从该方法收到的数组:

[Hari Krishna, 445444, 986544544, ]

这是我用来读取 Excel 文件的完整代码:

 public static List importExcelFile(String filePath, String fileName) {
    DataFormatter formatter = new DataFormatter(Locale.UK);
    // stores data from excel file
    List excelDataList = new ArrayList();
    try {
      // Import file from source destination
      FileInputStream file = new FileInputStream(new File(filePath.concat(File.separator.concat(fileName))));

      // Get the workbook instance for XLS file
      XSSFWorkbook workbook = new XSSFWorkbook(file);
      // workbook.setMissingCellPolicy(Row.RETURN_BLANK_AS_NULL);
      // Get first sheet from the workbook
      XSSFSheet sheet = workbook.getSheetAt(0);
      // Iterate through each rows from first sheet
      Iterator<Row> rowIterator = sheet.iterator();
      // Skip first row, since it is header row
      rowIterator.next();
      while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        int nextCell = 1;
        int currentCell = 0;
        // add data of each row
        ArrayList rowList = new ArrayList();
        // For each row, iterate through each columns
        Iterator<Cell> cellIterator = row.cellIterator();
        while (cellIterator.hasNext()) {
          Cell cell = cellIterator.next();
          currentCell = cell.getColumnIndex();
          if (currentCell >= nextCell) {
            int diffInCellCount = currentCell - nextCell;
            for (int nullLoop = 0; nullLoop <= diffInCellCount; nullLoop++) {
              rowList.add(" ");
              nextCell++;
            }
          }
          switch (cell.getCellType()) {
            case Cell.CELL_TYPE_BOOLEAN:
              rowList.add(cell.getBooleanCellValue());
              break;
            case Cell.CELL_TYPE_NUMERIC:
              if (DateUtil.isCellDateFormatted(cell)) {
                String date = formatter.formatCellValue(cell);
                rowList.add(date);
              } else {
                rowList.add(cell.getNumericCellValue());
              }
              break;
            case Cell.CELL_TYPE_STRING:
              rowList.add(cell.getStringCellValue());
              break;
            case Cell.CELL_TYPE_BLANK:
              rowList.add(" ");
              break;
            case Cell.CELL_TYPE_ERROR:
              rowList.add(" ");
              break;
            default:
              break;
          }
          nextCell++;
        }
        excelDataList.add(rowList);
      }
      file.close();
    } catch (FileNotFoundException e) {
      System.out.println(e.toString());
      return null;
    } catch (IOException e) {
      e.printStackTrace();
      return null;
    }
    return excelDataList;

  }

最佳答案

原因是,当您设置单元格的字体大小时,Excel 需要一种方法来知道单元格具有不同的字体(通常为 CellStyle )。当您更改默认字体大小时,Excel 会创建一个空白单元格并为其指定单元格样式 - 字体大小为 10。因为 CellStyleCell 的一个属性,Excel 需要 Cell所以它可以存储 CellStyle为了它。

当您阅读Cell时s 带有 Iterator<Cell> ,它只会返回那些 Cell存在的。在更改字体大小之前,“Hari Krishna”的“电子邮件”单元格不存在。更改字体大小后,现在“Hari Krishna”的“电子邮件”单元格存在,即使它是空白的。

如果你想要空白值,即使没有改变字体大小,那么你也不能使用 Iterator ,因为它不会返回 Cell ——它不存在。您可以使用标准 forRow 上循环对象,使用 MissingCellPolicy of CREATE_NULL_AS_BLANK .

如果您想跳过空白值,无论字体大小是否发生变化,那么您应该简单地跳过类型为 CELL_TYPE_BLANK 的单元格。 。从您的 switch 中删除该案例声明。

关于java - Apache poi 在读取 excel 文件时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31041805/

相关文章:

java - 将一个对象拆分为对象列表 - 需要 JAVA8 解决方案

java - 修复 Android 应用程序大小

java - Spring + Hibernate + Gradle-> org.springframework.beans.factory.BeanCreationException

vba - 如何在 VBA 中插入 TEMP 表

excel - 删除 FindNext 循环中的行的问题

arrays - 使用 ARRAY 中的变量声明 Cells(row,col)

python - 无法解决 Django 设置中的 mod_wsgi 异常

java - 使用 Tomcat 配置 Apache Web 服务器并尝试部署 war 文件

apache - ProxyPassReverse 删除 HTTPS

java - 覆盖 application.properties 中的值