我有excel文件包含这样的内容:
A1:SomeString
A2:2
所有字段都设置为字符串格式。
当我使用POI在java中读取文件时,它告诉A2是数字单元格格式。
.toString()
。如何将值读取为字符串?
答案 0 :(得分:296)
我有同样的问题。我在读取字符串值之前做了cell.setCellType(Cell.CELL_TYPE_STRING);
,无论用户如何格式化单元格,都解决了问题。
答案 1 :(得分:87)
当你提出这个问题时,我认为我们没有回复这个课程,但今天有一个简单的答案。
您要做的是使用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。
答案 2 :(得分:45)
以下代码适用于任何类型的单元格。
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);
}
答案 3 :(得分:25)
在修改单元格类型时,我建议使用以下方法:
if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
String str = NumberToTextConverter.toText(cell.getNumericCellValue())
}
NumberToTextConverter可以使用Excel的规则正确地将double值转换为文本,而不会出现精度损失。
答案 4 :(得分:15)
正如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);
上的更多示例
答案 5 :(得分:5)
是的,这完美无缺
建议:
DataFormatter dataFormatter = new DataFormatter();
String value = dataFormatter.formatCellValue(cell);
旧:
cell.setCellType(Cell.CELL_TYPE_STRING);
即使您从cell
检索具有公式的值时遇到问题,仍然可行。
答案 6 :(得分:4)
尝试:
new java.text.DecimalFormat("0").format( cell.getNumericCellValue() )
应正确格式化数字。
答案 7 :(得分:1)
只要在用户输入数字之前单元格是文本格式,POI就会允许您以字符串形式获取值。一个关键是,如果单元格的左上角有一个绿色小三角形,格式为文本,您将能够将其值检索为字符串(只要看起来像是一个数字,就会出现绿色三角形被强制成文本格式)。如果您有包含数字的文本格式化单元格,但POI不允许您将这些值作为字符串获取,那么您可以对电子表格数据执行一些操作以允许:
您可以做的最后一件事是,如果您使用POI从Excel 2007电子表格中获取数据,则可以使用Cell类的'getRawValue()'方法。这并不关心格式是什么。它只会返回一个包含原始数据的字符串。
答案 8 :(得分:0)
有一个现成的包装器 (可以应用一些其他优化)
它支持数字和字符串单元格
公式被自动识别并处理
避免重复使用
public final class Cell {
private final static DataFormatter FORMATTER = new DataFormatter();
private XSSFCell mCell;
public Cell(@NotNull XSSFCell cell) {
mCell = cell;
if (isFormula()) {
XSSFWorkbook book = mCell.getSheet().getWorkbook();
FormulaEvaluator evaluator = book.getCreationHelper().createFormulaEvaluator();
mCell = (XSSFCell) evaluator.evaluateInCell(mCell);
}
}
/**
* Get content
*/
public final int getInt() {
return (int) getLong();
}
public final long getLong() {
return Math.round(getDouble());
}
public final double getDouble() {
return mCell.getNumericCellValue();
}
public final String getString() {
if (!isString()) {
return FORMATTER.formatCellValue(mCell);
}
return mCell.getStringCellValue();
}
/**
* Get properties
*/
public final boolean isNumber() {
if (isFormula()) {
return mCell.getCachedFormulaResultType().equals(CellType.NUMERIC);
}
return mCell.getCellType().equals(CellType.NUMERIC);
}
public final boolean isString() {
if (isFormula()) {
return mCell.getCachedFormulaResultType().equals(CellType.STRING);
}
return mCell.getCellType().equals(CellType.STRING);
}
public final boolean isFormula() {
return mCell.getCellType().equals(CellType.FORMULA);
}
/**
* Debug info
*/
@Override
public String toString() {
return getString();
}
}
答案 9 :(得分:0)
public class Excellib {
public String getExceldata(String sheetname,int rownum,int cellnum, boolean isString) {
String retVal=null;
try {
FileInputStream fis=new FileInputStream("E:\\Sample-Automation-Workspace\\SampleTestDataDriven\\Registration.xlsx");
Workbook wb=WorkbookFactory.create(fis);
Sheet s=wb.getSheet(sheetname);
Row r=s.getRow(rownum);
Cell c=r.getCell(cellnum);
if(c.getCellType() == Cell.CELL_TYPE_STRING)
retVal=c.getStringCellValue();
else {
retVal = String.valueOf(c.getNumericCellValue());
}
我尝试了这个并且对我有用
答案 10 :(得分:0)
我更愿意选择Wil的回答路线或Vinayak Dornala,不幸的是,他们的表现远远超过了我。 我选择了 HACKY 隐式转换的解决方案:
for (Row row : sheet){
String strValue = (row.getCell(numericColumn)+""); // hack
...
我不建议你这样做,因为我的情况很有效,因为系统工作的性质和我有一个可靠的文件来源。
脚注: numericColumn 是读取处理文件头部生成的int。
答案 11 :(得分:0)
其中许多答案都引用了旧的POI文档和类。在最新的POI 3.16中,Cell with the int types已被弃用
Cell.CELL_TYPE_STRING
而是可以使用CellType enum。
CellType.STRING
请务必使用poi依赖项以及poi-ooxml依赖项更新您的pom到新的3.16版本,否则您将继续获得异常。此版本的一个优点是您可以在创建单元格时指定单元格类型,从而消除以前答案中描述的所有额外步骤:
titleRowCell = currentReportRow.createCell(currentReportColumnIndex, CellType.STRING);
答案 12 :(得分:0)
如果单元格类型为数字,则getStringCellValue返回NumberFormatException。如果您不想将单元格类型更改为字符串,则可以执行此操作。
String rsdata = "";
try {
rsdata = cell.getStringValue();
} catch (NumberFormatException ex) {
rsdata = cell.getNumericValue() + "";
}
答案 13 :(得分:0)
我在数千个数字的数据集上也有类似的问题,我认为我找到了一个简单的解决方法。我需要在数字之前插入撇号,以便单独的数据库导入始终将数字视为文本。在此之前,数字8将导入为8.0。
解决方案:
嘿Presto所有数字,但存储为文本。
答案 14 :(得分:0)
当我们使用Apache POI库读取MS Excel的数值单元格值时,它会将其读取为数字。但有时我们希望它以字符串形式读取(例如电话号码等)。我就这样做了:
插入一个新列,第一个单元格= CONCATENATE(“!”,D2)。我假设D2是您的电话号码列的小区ID。将新单元格拖动到最后。
现在,如果您使用POI读取单元格,它将读取公式而不是计算值。现在做以下事项:
添加其他列
选择在步骤1中创建的完整列,然后选择编辑 - &gt;复制
转到步骤3中创建的列的顶部单元格,然后选择“编辑” - >“选择性粘贴”
在打开的窗口中,选择“值”单选按钮
选择“确定”
现在使用POI API读取...在阅读Java之后...只需删除第一个字符,即“!”
答案 15 :(得分:-1)
cell.setCellType(Cell.CELL_TYPE_STRING);对我来说工作正常
答案 16 :(得分:-1)
答案 17 :(得分:-1)
这对我来说非常适合。
localhost
答案 18 :(得分:-1)
你是否还在控制excel工作表?是否有用户为您提供输入的模板?如果是这样,您可以为您输入代码格式化输入单元格。
答案 19 :(得分:-1)
我们遇到了同样的问题,并强制我们的用户在输入值之前将单元格格式化为“text”。这样Excel就能正确存储偶数作为文本。 如果之后更改格式,则Excel仅更改显示值的方式,但不会更改值的存储方式,除非再次输入值(例如,在单元格中按回车键)。
Excel是否正确地将值存储为文本由Excel显示在单元格左上角的小绿色三角形指示,如果它认为单元格包含数字但是格式化为文本。
答案 20 :(得分:-1)
转换为int然后执行.toString()
。它很丑,但它确实有效。