![](/img/trans.png)
[英]How can I read both string and numeric from excel in a single program in java selenium
[英]How can I read numeric strings in Excel cells as string (not numbers)?
我有包含以下内容的 excel 文件:
A1:一些字符串
A2:2
所有字段都设置为字符串格式。
当我使用 POI 在 java 中读取文件时,它告诉我 A2 是数字单元格格式。
.toString()
。我该怎么做才能将值读取为字符串?
我有同样的问题。 我做了cell.setCellType(Cell.CELL_TYPE_STRING);
在读取字符串值之前,无论用户如何格式化单元格,这都解决了问题。
当你问这个问题时,我不认为我们有这堂课,但今天有一个简单的答案。
您要做的是使用DataFormatter 类。 您将此单元格传递给它,它会尽力返回一个字符串,其中包含 Excel 会为您显示该单元格的内容。 如果你给它传递一个字符串单元格,你会得到这个字符串。 如果您传递一个应用了格式规则的数字单元格,它将根据它们格式化数字并返回字符串。
对于您的情况,我假设数字单元格应用了整数格式规则。 如果您要求 DataFormatter 格式化这些单元格,它会返回一个包含整数字符串的字符串。
另外,请注意很多人建议执行cell.setCellType(Cell.CELL_TYPE_STRING)
,但Apache POI JavaDocs 非常清楚地声明您不应该这样做! 执行setCellType
调用将丢失格式,因为javadocs 解释了转换为保留格式的字符串的唯一方法是使用DataFormatter 类。
使用此类的一个简单示例:
DataFormatter dataFormatter = new DataFormatter();
String formattedCellStr = dataFormatter.formatCellValue(cell);
以下代码适用于任何类型的单元格。
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);
}
当不希望修改单元格的类型时,我会推荐以下方法:
if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
String str = NumberToTextConverter.toText(cell.getNumericCellValue())
}
NumberToTextConverter 可以使用 Excel 的规则正确地将双精度值转换为文本,而不会损失精度。
正如 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);
老的:
cell.setCellType(Cell.CELL_TYPE_STRING);
即使您在从具有公式的cell
中检索值时遇到问题,这仍然有效。
尝试:
new java.text.DecimalFormat("0").format( cell.getNumericCellValue() )
应该正确格式化数字。
只要在用户输入数字之前单元格是文本格式,POI 就会允许您以字符串的形式获取值。 一个关键是,如果单元格的左上角有一个小绿色三角形,格式为文本,您将能够将其值作为字符串检索(只要看起来是数字,就会出现绿色三角形被强制转换成文本格式)。 如果您有包含数字的文本格式单元格,但 POI 不允许您将这些值作为字符串获取,您可以对电子表格数据执行一些操作以允许这样做:
您可以做的最后一件事是,如果您使用 POI 从 Excel 2007 电子表格中获取数据,您可以使用 Cell 类的“getRawValue()”方法。 这不关心格式是什么。 它只会返回一个带有原始数据的字符串。
如果单元格类型是数字,getStringCellValue 返回 NumberFormatException。 如果您不想将单元格类型更改为字符串,则可以这样做。
String rsdata = "";
try {
rsdata = cell.getStringValue();
} catch (NumberFormatException ex) {
rsdata = cell.getNumericValue() + "";
}
当我们使用 Apache POI 库读取 MS Excel 的数字单元格值时,它会将其读取为数字。 但有时我们希望它读取为字符串(例如电话号码等)。 我是这样做的:
插入一个新列,第一个单元格 =CONCATENATE("!",D2)。 我假设 D2 是您的电话号码列的单元格 ID。 将新单元格拖到最后。
现在,如果您使用 POI 读取单元格,它将读取公式而不是计算值。 现在执行以下操作:
添加另一列
选择在步骤 1 中创建的完整列。然后选择 Edit->COPY
转到在步骤 3 中创建的列的顶部单元格。然后选择 Edit->Paste Special
在打开的窗口中,选择“值”单选按钮
选择“确定”
现在使用 POI API 阅读……在 Java 中阅读之后……只需删除第一个字符,即“!”
其中许多答案都引用了旧的 POI 文档和类。 在最新的 POI 3.16 中,不推荐使用int 类型的 Cell
Cell.CELL_TYPE_STRING
相反,可以使用CellType 枚举。
CellType.STRING
请务必使用 poi 依赖项以及 poi-ooxml 依赖项将您的 pom 更新到新的 3.16 版本,否则您将继续遇到异常。 此版本的一个优点是您可以在创建单元格时指定单元格类型,从而消除先前答案中描述的所有额外步骤:
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);
}
我更愿意走 wil 的答案或 Vinayak Dornala 的路线,不幸的是,它们对我的表现影响很大。 我寻求隐式转换的HACKY解决方案:
for (Row row : sheet){
String strValue = (row.getCell(numericColumn)+""); // hack
...
我不建议你这样做,因为我的情况是因为系统的工作原理和我有一个可靠的文件来源。
脚注: numericColumn 是一个 int,它是通过读取已处理文件的标题生成的。
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());
}
我试过这个,它对我有用
有一个现成的包装器(可以应用一些额外的优化)
它支持数字和字符串单元格
自动识别和处理公式
避免一些样板
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(); } }
您可以使用 java 将数字单元格读取为字符串。
int type = cell.getCellType();
if(type == 0){
String value = NumberToTextConverter.toText(cell.getNumericCellValue());
}
else{
value = String.valueOf(cell.getStringCellValue());
}
这里,
0 => 数字单元格
getCellType() => 此方法用于获取 excel 单元格的类型。
我在包含数千个数字的数据集上也遇到过类似的问题,我认为我找到了一种简单的解决方法。 我需要在数字之前插入撇号,以便单独的数据库导入始终将数字视为文本。 在此之前,数字 8 将作为 8.0 导入。
解决方案:
嘿 Presto 所有数字,但存储为文本。
我遇到了同样的问题,最简单的解决方法是将CELL TYPE
设置为STRING
。 这样可以避免提示exceptions
。
FileInputStream fis = new FileInputStream(new File(filePath));
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sheet = wb.getSheetAt(0); // get first sheet
row.getCell(1).setCellType(CellType.STRING); // set Cell Type as String
String val = row.getCell(1).getStringCellValue(); // get the value as String type
System.out.println(val); // prints the value;
无论如何,您是否控制 Excel 工作表? 是否有用户提供输入的模板? 如果是这样,您可以为您设置输入单元格的代码格式。
我们遇到了同样的问题,并强制我们的用户在输入值之前将单元格格式化为“文本”。 这样,Excel 就可以正确地将偶数存储为文本。 如果随后更改格式,Excel 只会更改值的显示方式,但不会更改值的存储方式,除非再次输入值(例如,在单元格中按回车键)。
如果 Excel 认为单元格包含数字但格式为文本,则 Excel 是否将值正确存储为文本由 Excel 显示在单元格左上角的绿色小三角形指示。
cell.setCellType(Cell.CELL_TYPE_STRING); 对我来说很好
转换为 int 然后执行.toString()
。 它很丑,但它有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.