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);
}
20 回答
我有同样的问题 . 我在读取字符串值之前做了
cell.setCellType(Cell.CELL_TYPE_STRING);
,无论用户如何格式化单元格,都解决了问题 .当你问这个问题时,我认为我们没有回到这个课程,但今天有一个简单的答案 .
你想要做的是使用DataFormatter class . 你传递了一个单元格,它会尽力返回一个字符串,其中包含Excel为该单元格显示的内容 . 如果你传递一个字符串单元格,你将得到回来的字符串 . 如果您传递了一个应用了格式规则的数字单元格,它将根据它们格式化数字并返回字符串 .
对于您的情况,我假设数字单元格应用了整数格式规则 . 如果您要求DataFormatter格式化这些单元格,它将返回一个包含整数字符串的字符串 .
另外,请注意很多人建议做
cell.setCellType(Cell.CELL_TYPE_STRING)
,但Apache POI JavaDocs quite clearly state that you shouldn't do this!执行setCellType
调用将导致格式化失败,因为javadocs explain转换为格式为剩余的字符串的唯一方法是使用DataFormatter class .以下代码适用于任何类型的单元格 .
在修改单元格类型时,我建议使用以下方法:
NumberToTextConverter可以使用Excel的规则正确地将double值转换为文本而不会丢失精度 .
正如Poi的JavaDocs(https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html#setCellType%28int%29)中已经提到的那样,不要使用:
但使用:
有关http://massapi.com/class/da/DataFormatter.html的更多示例
尝试:
应正确格式化数字 .
是的,这很有效
推荐的:
旧:
即使您从具有公式的
cell
中检索值时遇到问题,仍然可以 .只要在用户输入数字之前单元格是文本格式,POI将允许您以字符串形式获取值 . 一个关键是,如果单元格的左上角有一个绿色小三角形,格式为文本,您将能够将其值检索为字符串(只要看起来像是一个数字,就会出现绿色三角形被强制成文本格式) . 如果您有包含数字的文本格式化单元格,但POI不允许您将这些值作为字符串获取,那么您可以对电子表格数据执行以下操作以允许:
双击单元格,使编辑光标出现在单元格内,然后单击Enter(一次只能完成一个单元格) .
使用Excel 2007文本转换功能(可以在多个单元格上一次完成) .
将有问题的值剪切到另一个位置,将电子表格单元格重新格式化为文本,然后将以前剪切的值重新格式化为未格式化的值回到适当的区域 .
您可以做的最后一件事是,如果您使用POI从Excel 2007电子表格中获取数据,则可以使用Cell类的'getRawValue()'方法 . 这并不关心格式是什么 . 它只会返回一个包含原始数据的字符串 .
当我们使用Apache POI库读取MS Excel的数值单元格值时,它将其读取为数字 . 但有时我们希望它以字符串形式读取(例如电话号码等) . 我就这样做了:
使用第一个单元格= CONCATENATE(“!”,D2)插入一个新列 . 我假设D2是您的电话号码列的小区ID . 将新单元格拖动到结尾 .
现在,如果您使用POI读取单元格,它将读取公式而不是计算值 . 现在做以下事项:
添加另一列
选择在步骤1中创建的完整列,然后选择编辑 - >复制
转到步骤3中创建的列的顶部单元格,然后选择编辑 - >选择性粘贴
在打开的窗口中,选择“值”单选按钮
选择“确定”
现在使用POI API读取...在Java中读取...只需删除第一个字符,即“!”
我在数千个数字的数据集上也有类似的问题,我认为我找到了一个简单的解决方法 . 我需要得到撇号在数字之前插入,以便单独的数据库导入始终将数字视为文本 . 在此之前,数字8将导入为8.0 .
解:
将所有格式保留为常规 .
这里我假设数字从第1行开始存储在A列中 .
放入'在B列中'并根据需要复制多行 . 工作表中没有任何内容,但单击单元格可以看到公式栏中的撇号 .
在C栏中:= B1和A1 .
选择C列中的所有单元格,然后使用“值”选项将“特殊粘贴”添加到列D中 .
嘿Presto所有数字但存储为文本 .
如果单元格类型是数字,则getStringCellValue返回NumberFormatException . 如果您不想将单元格类型更改为字符串,则可以执行此操作 .
其中许多答案都引用了旧的POI文档和类 . 在最新的POI 3.16中,Cell with the int types已被弃用
而是可以使用CellType enum .
请务必使用poi依赖项以及poi-ooxml依赖项更新您的pom到新的3.16版本,否则您将继续获得异常 . 此版本的一个优点是您可以在创建单元格时指定单元格类型,从而消除以前答案中描述的所有额外步骤:
我更愿意选择Wil的回答路线或Vinayak Dornala,不幸的是,他们的表现远远超过了我 . 我去了一个隐式转换的解决方案:
我不建议你这样做,因为我的情况很有效,因为系统工作的性质和我有一个可靠的文件源 .
脚注:numericColumn是一个int,它是通过读取处理文件的 Headers 生成的 .
我试过这个,它对我有用
我们遇到了同样的问题,并强迫我们的用户将单元格格式化为'text' before 输入值 . 这样Excel就能正确存储偶数作为文本 . 如果之后更改格式,则Excel仅更改显示值的方式,但不会更改值的存储方式,除非再次输入值(例如,在单元格中按回车键) .
Excel是否正确地将值存储为文本由Excel显示在单元格左上角的小绿色三角形指示,如果它认为单元格包含数字但是格式化为文本 .
无论如何你是否控制excel工作表?是否有用户为您提供输入的模板?如果是这样,您可以为您输入代码格式化输入单元格 .
看起来这在当前版本的POI中无法完成,基于以下事实:
https://issues.apache.org/bugzilla/show_bug.cgi?id=46136
仍然很出色 .
cell.setCellType(Cell.CELL_TYPE_STRING);对我来说工作正常
强制转换为int然后执行
.toString()
. 它很难看,但它有效 .这对我来说非常完美 .