如何将 Excel 单元格中的数字字符串作为字符串(而不是数字)读取?

  1. 我有 Excel 文件,里面有这样的内容:

    • A1: SomString

    • 答2:2

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

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

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

如何将值读取为字符串?

315129 次浏览

然后做一个 .toString()。这是丑陋的,但它的工作。

我们有同样的问题,并强迫我们的用户格式化单元格为’文本’之前输入值。这样 Excel 就可以正确地将偶数存储为文本。 如果格式后来改变,Excel 只改变值的显示方式,但不改变值的存储方式,除非再次输入该值(例如在单元格中按 return)。

如果 Excel 认为单元格包含数字但格式为文本,那么 Excel 在单元格左上角显示的绿色小三角表示该值是否正确地存储为文本。

你控制 Excel 工作表吗?用户是否有一个模板来给你输入信息?如果是,您可以让代码为您设置输入单元格的格式。

我也有同样的问题。我在读取字符串值之前执行了 cell.setCellType(Cell.CELL_TYPE_STRING);,这解决了不管用户如何格式化单元格的问题。

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

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

仍然很出色。

当我们使用 ApachePOI 库读取 MSExcel 的数值单元格值时,它将其读取为数值。但有时我们希望它读作字符串(例如电话号码等)。我是这么做的:

  1. 插入一个新列,其中第一个 cell = CONCATENATE (“ !”,D2).我猜 D2是你电话号码栏的手机号码。将新单元格拖到末尾。

  2. 现在如果您使用 POI 读取单元格,它将读取公式而不是计算值。现在执行以下操作:

  3. 添加另一列

  4. 选择在步骤1中创建的完整列,并选择 Edit-> COPY

  5. 转到步骤3中创建的列的顶部单元格,选择 Edit-> Paste Special

  6. 在打开的窗口中,选择“值”单选按钮

  7. 选择「确定」

  8. 现在使用 POI API 读取... 在用 Java 读取之后... 只需删除第一个字符即“ !”

试试:

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

应正确格式化数字。

当你问这个问题的时候,我们没有这门课,但是今天有一个简单的答案。

你要做的是使用 DataFormatter 类。传递给它一个单元格,它会尽最大努力返回一个字符串,其中包含 Excel 为该单元格显示的内容。如果传递给它一个字符串单元格,就会得到返回的字符串。如果您传递给它一个应用了格式规则的数字单元格,它将根据这些规则格式化数字并返回字符串。

对于您的示例,我假设数值单元格应用了一个整数格式规则。如果要求 DataFormatter 格式化这些单元格,它将返回一个包含整数字符串的字符串。

另外,请注意,很多人建议做 cell.setCellType(Cell.CELL_TYPE_STRING),但 ApachePOIJavaDocs 非常明确地指出您不应该这样做!执行 setCellType调用将导致格式松散,因为 Javadocs 解释转换为 String 并保留格式的唯一方法是使用 DataFormatter 类

使用这个类的一个简单示例:

DataFormatter dataFormatter = new DataFormatter();
String formattedCellStr = dataFormatter.formatCellValue(cell);

我也遇到过类似的问题,关于数千个数字的数据集,我认为我已经找到了一个简单的方法来解决。我需要在数字之前插入撇号,这样单独的 DB 导入总是将数字视为文本。在此之前,数字8将被导入为8.0。

解决方案:

  • 保持所有格式为 General。
  • 这里我假设数字存储在从第1行开始的 A 列中。
  • 在 B 栏中填入“ ,并根据需要向下复制尽可能多的行。工作表中没有显示任何内容,只是单击单元格,您可以在公式栏中看到撇号。
  • C 栏: = B1 & A1。
  • 选择列 C 中的所有单元格,并使用 Value 选项将特殊粘贴到列 D 中。

嘿,普雷斯托所有的数字,但存储为文本。

只要单元格在用户键入数字之前是文本格式,POI 就允许您以字符串的形式获取值。一个关键是,如果在单元格的左上角有一个格式为 Text 的绿色小三角形,那么您将能够检索它的值作为一个字符串(每当看起来像数字的东西被强制转换为文本格式时,绿色三角形就会出现)。如果您有包含数字的文本格式单元格,但 POI 不允许您以字符串的形式获取这些值,那么可以对电子表格数据执行以下操作:

  • 双击单元格,使编辑光标出现在单元格中,然后单击 Enter (一次只能完成一个单元格)。
  • 使用 Excel2007文本转换函数(可以同时在多个单元格上执行)。
  • 将违规值剪切到另一个位置,将电子表格单元格重新格式化为文本,然后将先前剪切的值重新粘贴到适当的区域。

您可以做的最后一件事是,如果使用 POI 从 Excel2007电子表格获取数据,可以使用 Cell 类“ getRawValue ()”方法。这并不关心格式是什么。它将简单地返回一个包含原始数据的字符串。

是的,这样很好

建议:

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

旧的:

cell.setCellType(Cell.CELL_TYPE_STRING);

即使您在从具有公式的 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);


}

如果单元格类型为数值,getStringCellValue 返回 NumberFormatException。如果不想将单元格类型更改为 string,可以这样做。

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

SetCellType (Cell.CELL _ TYPE _ STRING) ; 对我来说工作得很好

当不需要修改 cell 的类型时,我建议采用以下方法:

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);

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

这些答案中的许多都引用了旧的 POI 文档和类

Cell.CELL_TYPE_STRING

enter image description here

相反,可以使用 CellType 枚举

CellType.STRING

只要确保将 poi 依赖项和 poi-ooxml 依赖项更新到新的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);
}

我更愿意走威尔的答案或维纳亚克多纳拉的路线,不幸的是,他们影响了我的表现远远不够。 我采用了 HACKY的隐式选角解决方案:

for (Row row : sheet){
String strValue = (row.getCell(numericColumn)+""); // hack
...

我不建议你这样做,对于我的情况下,它的工作原理,因为如何系统工作的性质,我有一个可靠的文件来源。

脚注: 数字列 是一个整型值,它是通过读取所处理文件的头而生成的。

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 将数字单元格读取为 String。

int type = cell.getCellType();
if(type == 0){
String value = NumberToTextConverter.toText(cell.getNumericCellValue());
}
else{
value = String.valueOf(cell.getStringCellValue());
}

给你,

0 = > 数字单元格

GetCellType () = > 此方法用于获取 excel 单元格的类型。