如何读取Excel单元格中的数字string作为string(不是数字)?

  1. 我有这样的内容excel文件:

    • A1:SomeString

    • A2:2

    所有字段都设置为string格式。

  2. 当我使用POI在java中读取文件时,它告诉A2是数字单元格格式。

  3. 问题是,在A2中的值可以是2或2.0(我想能够区分它们),所以我不能只使用.toString()

我能做些什么来读取string的值?

我有同样的问题。 我做了cell.setCellType(Cell.CELL_TYPE_STRING); 在读取string值之前,无论用户如何格式化单元格,解决了问题。

当你问这个问题时,我不认为我们有这个课,但今天有一个简单的答案。

你想要做的是使用DataFormatter类 。 您将这个单元格传递给它,并尽可能返回一个包含Excel将向您显示该单元格的string。 如果你传递一个string单元格,你会得到string。 如果您将格式化规则应用于数字单元格,则会根据格式化数字并将string返回。

对于你的情况,我会假设数字单元格有一个整数格式化规则适用于他们。 如果您要求DataFormatter格式化这些单元格,则会返回一个包含整数string的string。

此外,请注意,很多人build议做cell.setCellType(Cell.CELL_TYPE_STRING) ,但是Apache POI JavaDocs很清楚地表明你不应该这样做 ! 执行setCellType调用会松散格式化,因为javadoc解释了转换为格式剩余的String的唯一方法是使用DataFormatter类 。

下面的代码适用于任何types的单元格。

 InputStream inp =getClass().getResourceAsStream("filename.xls")); Workbook wb = WorkbookFactory.create(inp); DataFormatter objDefaultFormat = new DataFormatter(); FormulaEvaluator objFormulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) wb); Sheet sheet= wb.getSheetAt(0); Iterator<Row> objIterator = sheet.rowIterator(); while(objIterator.hasNext()){ Row row = objIterator.next(); Cell cellValue = row.getCell(0); objFormulaEvaluator.evaluate(cellValue); // This will evaluate the cell, And any type of cell will return string value String cellValueStr = objDefaultFormat.formatCellValue(cellValue,objFormulaEvaluator); } 

当修改单元格types是不可取的时,我会推荐以下方法:

 if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC) { String str = NumberToTextConverter.toText(cell.getNumericCellValue()) } 

NumberToTextConverter可以使用Excel的规则将double值正确地转换为文本,而不会丢失精确度。

正如Poi的JavaDocs( https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html#setCellType%28int%29 )中已经提到的那样,不要使用:

 cell.setCellType(Cell.CELL_TYPE_STRING); 

但使用:

 DataFormatter df = new DataFormatter(); String value = df.formatCellValue(cell); 

更多关于http://massapi.com/class/da/DataFormatter.html的例子;

尝试:

 new java.text.DecimalFormat("0").format( cell.getNumericCellValue() ) 

应正确格式化数字。

是的,这是完美的

 cell.setCellType(Cell.CELL_TYPE_STRING); 

即使你在从具有公式的cell中检索值时遇到问题,仍然有效。

只要在用户键入数字之前单元格是文本格式,POI将允许您以stringforms获取该值。 一个关键是如果格式化为文本的单元格左上angular有一个小的绿色三angular形,则可以以string的forms检索其值(绿色三angular形出现在看起来像是数字的地方被强制为文本格式)。 如果您的文本格式的单元格包含数字,但POI不会让您将这些值作为string获取,则可以对电子表格数据执行以下操作:

  • 双击单元格,使编辑光标出现在单元格内,然后单击Enter(一次只能完成一个单元格)。
  • 使用Excel 2007文本转换function(可以一次在多个单元格中完成)。
  • 将违规值剪切到另一个位置,将文本格式的电子表格单元格重新格式化,然后将之前删除的值作为无格式值重新join适当的区域。

你可以做的最后一件事是,如果你使用POI从Excel 2007电子表格中获取数据,你可以使用Cell类的getRawValue()方法。 这不关心格式是什么。 它将简单地返回一个string与原始数据。

你可以预先在Excel中的string撇号? 它们不会显示在工作表上,而是强制单元格格式为文本,并且可以在导入过程中识别并剥离/强制。

我们遇到同样的问题,并迫使我们的用户input值之前将单元格格式化为“文本”。 这样Excel正确地存储偶数作为文本。 如果格式改变之后,Excel只改变数值的显示方式,但不改变数值的存储方式,除非再次input数值(例如在单元格中按回车键)。

Excel是否正确地将值存储为文本,如果Excel认为单元格中包含一个数字,并将其格式化为文本,则Excel将在该单元格的左上angular显示一个绿色的小三angular形。

你是否控制了Excel工作表呢? 有没有用户给你的input模板? 如果是这样,你可以为你input单元格格式。

看起来这是不能在当前版本的POI中完成的,基于这个bug:

https://issues.apache.org/bugzilla/show_bug.cgi?id=46136

仍然是优秀的。

当我们使用Apache POI库读取MS Excel的数字单元格值时,将其作为数字读取。 但有时我们希望它读取为string(例如电话号码等)。 这是我做到的:

  1. 用第一个单元格= CONCATENATE(“!”,D2)插入一个新列。 我假设D2是您的电话号码列的单元ID。 拖动新的单元格结束。

  2. 现在,如果使用POI读取单元格,它将读取公式而不是计算值。 现在做以下事情:

  3. 添加另一列

  4. select在步骤1中创build的完整列,然后select“编辑” – >“复制”

  5. 转到步骤3中创build的列的顶部单元格,然后select编辑 – >select性粘贴

  6. 在打开的窗口中,select“值”单选button

  7. select“确定”

  8. 现在阅读使用POI API …阅读Java后…只是删除第一个字符,即“!”

我在数千个数据集上也遇到类似的问题,我想我已经find了一个简单的解决方法。 我需要在数字之前插入撇号,以便单独的数据库导入始终将数字视为文本。 在此之前,数字8将被导入为8.0。

解:

  • 保持所有格式为一般。
  • 在这里,我假设数字存储在第1行的列A中。
  • 放在B列中,根据需要复制多行。 工作表中没有显示任何内容,但单击单元格,可以在“公式”栏中看到“启动”。
  • 在C列:= B1&A1。
  • select列C中的所有单元格,并使用值选项将特殊选项粘贴到列D中。

嘿Presto所有的数字,但存储为文本。

如果单元格types是数字,getStringCellValue将返回NumberFormatException。 如果您不想将单元格types更改为string,则可以执行此操作。

 String rsdata = ""; try { rsdata = cell.getStringValue(); } catch (NumberFormatException ex) { rsdata = cell.getNumericValue() + ""; } 

cell.setCellType(Cell.CELL_TYPE_STRING); 对我来说工作正常

强制转换为int,然后执行.toString() 。 这是丑陋的,但它的工作。

许多这些答案引用了旧的POI文档和类。 在最新的POI 3.16中, 具有inttypes的Cell已被弃用

 Cell.CELL_TYPE_STRING 

在这里输入图像描述

而是可以使用CellType枚举 。

 CellType.STRING 

只要确保将poi依赖项以及poi-ooxml依赖项更新到新的3.16版本,否则您将继续得到exception。 这个版本的一个优点是,你可以在创build单元格时指定单元格types,从而消除以前答案中所描述的所有额外步骤:

 titleRowCell = currentReportRow.createCell(currentReportColumnIndex, CellType.STRING); 

这对我来说非常合适。

 Double legacyRow = row.getCell(col).getNumericCellValue(); String legacyRowStr = legacyRow.toString(); if(legacyRowStr.contains(".0")){ legacyRowStr = legacyRowStr.substring(0, legacyRowStr.length()-2); }