使用Apache POI在Java中从数字单元格读取整数

7

我有一个应用程序,使用Apache POI读取xls表格。当单元格具有数字值时,我使用row.getCell(i).getNumericValue()进行读取。但它返回浮点数。例如,如果单元格的值为1,则返回1.0。我能将其转换为整数吗?任何帮助都将不胜感激。我尝试了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

明白了,获取值并转换为整数:Double val = cell.getNumericCellValue(); val.intValue 将会得到答案。 - Parameswar
以下是一个简单的解决方案:double dval = row.getCell(cellCounter, XSSFRow.CREATE_NULL_AS_BLANK ).getNumericCellValue(); System.out.println(new Integer(new Double(dval).intValue()).toString()); - Mike Preston
8个回答

33

在Excel中,数字(除了少数边缘情况)以浮点数的形式存储。在Java中,当格式化为字符串时,浮点数会带有一个尾随小数点,就像你所看到的一样。

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

相反,您需要使用DataFormatter类,该类提供了读取应用于单元格的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);
          }
     }
 }

你可能会注意到我还修复了一堆其他东西....!


4
非常简洁明了,谢谢。 - gschambial

4
  // 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;

示例:读取限定数量的行并使用DataFormatter提供精确的数字值,无论是整数还是双精度值。这将有效。


1

尝试执行以下操作(以获取长整型):

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

1

有人可能会发现这个黑客很有用:

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

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


3
setCellType 在新版本中已被弃用。 - Pranjal Choladhara

0
你可以使用简单的步骤将 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);
    }

这段代码对于数字单元格将会失败,因为你试图读取字符串值而没有检查/确保单元格是数字的。 - Gagravarr
现在它正在工作,您的单元格值通用也正在工作,无需检查。 - VISHWANATH N P

0

您可以直接将 float 强制转换为 int,例如:

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

0
Cell cell = row.getCell(cellCpt);

String cellContent = "";
if (cell != null) {
    cell.setCellType(CellType.STRING);
    cellContent = fmt.formatCellValue(cell);
}

0

以下实现对我有效:

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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接