【问题标题】:Read integer from numeric cell using Apache POI in java在java中使用Apache POI从数字单元格中读取整数
【发布时间】:2014-11-04 10:56:49
【问题描述】:

我有一个使用 apache poi 读取 xls 表的应用程序。当单元格具有数值时,我通过 row.getCell(i).getNumericValue() 读取它。但它返回浮点数。就像如果单元格值为 1,它返回 1.0。我可以将其转换为 int 吗?任何帮助,将不胜感激。我试过 Integer.parseInt(value)- 但它抛出 NumberFormat 异常。任何帮助表示赞赏。这是伪代码:

FileInputStream file = new FileInputStream(new File("C:\\test.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(file);
HSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
while(rowIterator.hasNext()) {
    Row row = rowIterator.next();
    Iterator<Cell> cellIterator = row.cellIterator();
    while(cellIterator.hasNext()) {
        Cell cell = cellIterator.next();
        switch(cell.getCellType()) {
            case Cell.CELL_TYPE_NUMERIC:
                String value= String.valueOf(cell.getNumericCellValue());
                int intVal = Integer.parseInt(value)-->>throws Exception

【问题讨论】:

  • 知道了,获取两倍于 conert 到 int 的值:Double val = cell.getNumericCellValue(); val.intValue 会给出答案
  • 这是一个简单的解决方案:double dval = row.getCell(cellCounter, XSSFRow.CREATE_NULL_AS_BLANK ).getNumericCellValue(); System.out.println(new Integer(new Double(dval).intValue()).toString());

标签: java apache-poi xls numberformatexception


【解决方案1】:

Excel 中的数字(除了少数极端情况)存储为浮点数。如您所见,Java 中的浮点数在格式化为字符串时会打印尾随小数点

假设您真正想要的是“给我一个看起来像 Excel 为该单元格显示的字符串”,然后不要调用 cell.toString()。在大多数情况下,这不会给你想要的东西

相反,您需要使用DataFormatter class,它提供了读取应用于单元格的 Excel 格式规则的方法,然后(尽其所能)用 Java 重新创建这些规则

你的代码应该是:

Workbook wb = WorkbookFactory.create(new File("c:/test.xls");
DataFormatter fmt = new DataFormatter();
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
     Cell cell = row.getcell(0, Row.RETURN_BLANK_AS_NULL);
     if(cell!=null) {
          String value = fmt.formatCellValue(cell);
          if (! value.trim().isEmpty()) {
             System.out.println("Cell as string is " + value);
          }
     }
 }

您可能会注意到我还修复了许多其他问题......!

【讨论】:

  • 非常干净的方法。谢谢。
【解决方案2】:

您可以使用简单的步骤将 int 值读取为字符串 apache poi

使用以下方法计算工作表中的第一个行数

private  int getRowCount(Sheet currentSheet) {
        int rowCount = 0;
        Iterator<Row> rowIterator = currentSheet.iterator();

        while(rowIterator.hasNext()) {  
            Row row = rowIterator.next();

            if(row == null || row.getCell(0) == null || row.getCell(0).getStringCellValue().trim().equals("") || row.getCell(0).toString().trim().equals("") 
                    || row.getCell(0).getCellType()==Cell.CELL_TYPE_BLANK){
                break;
            }
            else
                rowCount=rowCount + 1;
        }       
        return rowCount;
    }

然后在你的方法中使用下面的代码

    Workbook workbook = WorkbookFactory.create(new File("c:/test.xls");
    Sheet marksSheet = (Sheet) workbook.getSheet("Sheet1");
            int zoneLastCount = 0;
            if(marksSheet !=null ) {
                zoneLastCount = getRowCount(marksSheet);
            }
    int zone = zoneLastCount-1;
    int column=1

    for(int i = 0; i < zone; i++) {         
        Row currentrow = marksSheet.getRow(i);
        double year = Double.parseDouble(currentrow.getCell(columnno).toString());
        int year1 = (int)year;
        String str = String.valueOf(year1);
    }

【讨论】:

  • 此代码对于数字单元格将失败,因为您尝试读取字符串值而不检查/确保您的单元格是数字的
  • 现在可以正常工作了,您的单元格值一般也可以正常工作,无需检查
【解决方案3】:

有人可能会觉得这个 hack 有用:

cell.setCellType(CellType.STRING);
int value = Integer.parseInt(cell.getStringCellValue());

请记住,您在此处更改了单元格类型,因此请确保这不会造成任何副作用。在单线程应用程序中,您可以只读取之前的类型并在之后恢复它。

【讨论】:

  • setCellType 在新版本中已弃用。
【解决方案4】:

您只需键入 cast floatint 即可:

String value = String.valueOf((int)cell.getNumericCellValue());

【讨论】:

    【解决方案5】:
    Cell cell = row.getCell(cellCpt);
    
    String cellContent = "";
    if (cell != null) {
        cell.setCellType(CellType.STRING);
        cellContent = fmt.formatCellValue(cell);
    }
    

    【讨论】:

      【解决方案6】:

      尝试执行以下操作(以获得长):

      long value = (long) currentCell.getNumericValue();
      

      【讨论】:

        【解决方案7】:
          // to extract the exact numerical value either integer/double
          DataFormatter fmt = new DataFormatter();
          Iterator<Cell> cellIterator = row.cellIterator();
          while (cellIterator.hasNext()) {
            Cell cell = cellIterator.next();
            switch (cell.getCellType()) {
              case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                  Date date = cell.getDateCellValue();
                  DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
                  //DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                  fetchedRow.add(dateFormat.format(date));
                } else {
                  fetchedRow.add(fmt.formatCellValue(cell));
                }
                rowEmpty = false;
                break;
              case STRING:
                fetchedRow.add(cell.toString());
                rowEmpty = false;
                break;
              case BOOLEAN:
                fetchedRow.add(cell.toString());
                rowEmpty = false;
                break;
              case FORMULA:
                fetchedRow.add(Double.toString(cell.getNumericCellValue()));
                rowEmpty = false;
                break;
              case BLANK:
                fetchedRow.add("");
                break;
            }
          }
          if (!rowEmpty) {
            allRows.add(fetchedRow.toArray(new String[0]));
            count++;
          }
          if (count >= limit) {
            break;
          }
        }
        return allRows;
        

        }

        eaxmple 读取有限的行数并使用 DataFormatter 提供整数/双精度值的精确数值。这将起作用。

        【讨论】:

          【解决方案8】:

          以下实现对我有用:

          private Object getValue(Cell cell) {
              switch (cell.getCellType()) {
                  case Cell.CELL_TYPE_STRING:
                      return cell.getStringCellValue();
                  case Cell.CELL_TYPE_NUMERIC:
                      return String.valueOf((int) cell.getNumericCellValue());
                  case Cell.CELL_TYPE_BOOLEAN:
                      return cell.getBooleanCellValue();
                  case Cell.CELL_TYPE_ERROR:
                      return cell.getErrorCellValue();
                  case Cell.CELL_TYPE_FORMULA:
                      return cell.getCellFormula();
                  case Cell.CELL_TYPE_BLANK:
                      return null;
              }
              return null;
          }
          

          【讨论】:

            猜你喜欢
            • 2015-06-22
            • 2023-03-12
            • 1970-01-01
            • 2020-12-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多