我有一个Excel文件,其中包含以下内容:
A1:SomeString
A2:2
所有字段都设置为字符串格式。
当我在Java中使用POI读取文件时,它告诉我A2是数字单元格格式。
- 问题在于,A2中的值可以是2或2.0(我希望能够区分它们),因此我不能仅使用
.toString()
。
我该怎么做才能将其作为字符串读取?
我有一个Excel文件,其中包含以下内容:
A1:SomeString
A2:2
所有字段都设置为字符串格式。
当我在Java中使用POI读取文件时,它告诉我A2是数字单元格格式。
.toString()
。我该怎么做才能将其作为字符串读取?
cell.setCellType(Cell.CELL_TYPE_STRING);
,这样无论用户如何格式化单元格,问题都得到了解决。DataFormatter
我记得当你提出这个问题时,我们还没有这个类,但是现在有一个简单的答案。
你想要做的是使用DataFormatter类。你将一个单元格传递给它,它会尽力返回一个包含Excel显示该单元格内容的字符串。如果你传递给它一个字符串单元格,它会返回该字符串。如果你传递给它一个应用了格式规则的数值单元格,它会根据这些规则格式化数字并返回字符串。
对于你的情况,我假设数值单元格应用了整数格式规则。如果你要求DataFormatter格式化这些单元格,它会返回一个包含整数字符串的字符串。
此外,注意到很多人建议使用cell.setCellType(Cell.CELL_TYPE_STRING)
,但是Apache POI JavaDocs非常明确地指出你不应该这样做!调用setCellType
会丢失格式,因为javadocs解释了唯一保留格式的转换为字符串的方法是使用DataFormatter类。DataFormatter dataFormatter = new DataFormatter();
String formattedCellStr = dataFormatter.formatCellValue(cell);
当传递一个空单元格时,此方法将返回一个空字符串("")。公式类型单元格中的公式将不会被计算。
- SaratBhaswanthDataFormatter
在内部将其转换为double
,然后再转换回String
,因此存在失去精度和前导/尾随0的风险。 - Stik以下代码适用于我所遇到的任何类型的单元格。
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);
}
getCreationHelper().createFormulaEvaluator()
方法提供了一个公式求值器。这样你的代码就不会与HSSFFormulaEvaluator类耦合。 - Vitor SantosFormulaEvaluator
可以被简单地移除吗?它有什么作用吗? - P.Brian.Mackey如果不希望修改单元格类型,我建议采取以下方法:
if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
String str = NumberToTextConverter.toText(cell.getNumericCellValue())
}
NumberToTextConverter能够使用Excel的规则将双精度值正确转换为文本,而不会失去精度。
DateUtil.getLocalDateTime(row.getCell(1).getNumericCellValue()).toLocalDate()
- Georgy Bolyuba如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);
是的,这个完美地运作了。
推荐:
DataFormatter dataFormatter = new DataFormatter();
String value = dataFormatter.formatCellValue(cell);
old:
cell.setCellType(Cell.CELL_TYPE_STRING);
即便您从带有公式的cell
中检索值时遇到问题,这仍然有效。
尝试:
new java.text.DecimalFormat("0").format( cell.getNumericCellValue() )
2
和2.0
。您的解决方案无法实现这一点。(但是,欢迎来到Stack Overflow!) - Paŭlo Ebermannint type = cell.getCellType();
if(type == 0){
String value = NumberToTextConverter.toText(cell.getNumericCellValue());
}
else{
value = String.valueOf(cell.getStringCellValue());
}
最后一件你可以做的事情是,如果你正在使用POI从Excel 2007电子表格中获取数据,你可以使用Cell类的'getRawValue()'方法。这不关心格式是什么。它将简单地返回一个带有原始数据的字符串。
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());
}
我尝试了这个,对我有效。