代码之家  ›  专栏  ›  技术社区  ›  joycollector

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

  •  130
  • joycollector  · 技术社区  · 17 年前
    1. 我有包含这些内容的Excel文件:

      • A1:字符串

      • A2:2

      所有字段都设置为字符串格式。

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

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

    如何将值读取为字符串?

    20 回复  |  直到 8 年前
        1
  •  292
  •   PaÅ­lo Ebermann    15 年前

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

        2
  •  86
  •   Gagravarr    11 年前

    我不认为你问这个问题时我们把这节课放回去了,但今天有一个简单的答案。

    你要做的是使用 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类 .

        3
  •  43
  •   Vinayak Dornala    12 年前

    下面的代码适用于任何类型的手机。

    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);
    
    }
    
        4
  •  24
  •   Stanislav Mamontov    10 年前

    当不希望修改单元格类型时,我建议使用以下方法:

    if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
        String str = NumberToTextConverter.toText(cell.getNumericCellValue())
    }
    

    NumberTotexConverter可以使用Excel规则将双精度值正确转换为文本,而不会造成精度损失。

        5
  •  15
  •   userM1433372    9 年前

    正如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

        6
  •  5
  •   Rajesh Mbm    8 年前

    是的,这个很好用

    推荐:

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

    旧的:

    cell.setCellType(Cell.CELL_TYPE_STRING);
    

    即使在从中检索值时遇到问题 cell 有了公式,这仍然有效。

        7
  •  4
  •   PaÅ­lo Ebermann    15 年前

    尝试:

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

    应该正确格式化数字。

        8
  •  1
  •   Mark Farnsworth    14 年前

    只要在用户键入数字之前单元格是文本格式,POI将允许您获取字符串形式的值。一个关键点是,如果单元格左上角有一个格式化为文本的小绿色三角形,则可以将其值作为字符串检索(每当某个看似数字的内容被强制转换为文本格式时,就会出现绿色三角形)。如果您有包含数字的文本格式单元格,但是POI不允许您将这些值作为字符串提取,那么您可以对电子表格数据执行一些操作,以允许这样做:

    • 双击单元格,使编辑光标出现在单元格内,然后单击Enter(一次只能执行一个单元格)。
    • 使用Excel2007文本转换函数(可以一次对多个单元格进行转换)。
    • 将有问题的值剪切到其他位置,将电子表格单元格重新格式化为文本,然后将以前剪切的值重新粘贴为 未格式化的值 回到适当的区域。

    最后一件事是,如果使用POI从Excel2007电子表格中获取数据,则可以使用cell类“getrawValue()”方法。这与格式无关。它只返回包含原始数据的字符串。

        9
  •  0
  •   Asif Shahzad    15 年前

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

    1. 插入第一个单元格=concatenate(“!”的新列,D2)。我假设d2是你电话号码栏的手机号。将新单元格拖到最后。

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

    3. 添加另一列

    4. 选择在步骤1中创建的完整列。然后选择“编辑”->复制

    5. 转到步骤3中创建的列的顶部单元格。然后选择“编辑”->选择性粘贴

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

    7. 选择“确定”

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

        10
  •  0
  •   Garrett Hyde NeilP    13 年前

    我在一个有数千个数字的数据集上也遇到了类似的问题,我认为我找到了一种简单的解决方法。我需要在数字前插入撇号,这样单独的db导入总是将数字视为文本。在此之前,数字8将作为8.0导入。

    解决方案:

    • 将所有格式保留为常规格式。
    • 这里我假设数字存储在A列中,从第1行开始。
    • 在B列中放入',并根据需要复制尽可能多的行。工作表中没有显示任何内容,只需单击单元格,即可在公式栏中看到撇号。
    • C栏:=b1&a1。
    • 选择C列中的所有单元格,并使用“值”选项将其特殊粘贴到D列中。

    嘿,把所有的数字都预存下来,但是作为文本存储。

        11
  •  0
  •   zawhtut    12 年前

    如果单元格类型为数字,则GetStringCellValue返回NumberFormatException。如果不想将单元格类型更改为字符串,可以这样做。

    String rsdata = "";
    try {
        rsdata = cell.getStringValue();
    } catch (NumberFormatException ex) {
        rsdata = cell.getNumericValue() + "";
    }
    
        12
  •  0
  •   Nelda.techspiress    9 年前

    这些答案中的许多都引用了旧的POI文档和类。在最新的POI 3.16中, Cell with the int types 已弃用

    Cell.CELL_TYPE_STRING
    

    enter image description here

    相反地 CellType enum 可以使用。

    CellType.STRING 
    

    只要确保使用POI依赖项以及POI OOXML依赖项将POM更新到新的3.16版本,否则您将继续获得异常。此版本的一个优点是,您可以在创建单元时指定单元类型,从而消除前面答案中描述的所有额外步骤:

    titleRowCell = currentReportRow.createCell(currentReportColumnIndex, CellType.STRING);
    
        13
  •  0
  •   KeaganFouche    8 年前

    我更愿意走威尔氏回答的路线,或者是维纳亚克·多纳拉,不幸的是,他们对我的表现影响很大。 我去了 哈奇 隐式铸造的解决方案:

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

    我不建议你这样做,因为我的情况下,它是工作的,因为系统工作的性质,我有一个可靠的文件源。

    脚注: 数字柱 是从读取处理的文件头中生成的int。

        14
  •  0
  •   Prasanna    8 年前
    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());
            }
    

    我试过了,它对我有用

        15
  •  -1
  •   Turismo    17 年前

    我们遇到了同样的问题,迫使用户将单元格格式设置为“文本” 之前 输入值。这样Excel就可以正确地将偶数存储为文本。 如果随后更改格式,Excel只更改值的显示方式,但不会更改值的存储方式,除非再次输入值(例如,在单元格中按回车键)。

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

        16
  •  -1
  •   datatoo    16 年前

    是否仍在中控制Excel工作表?是否有用户提供输入的模板?如果是这样,您可以让代码为输入单元格设置格式。

        17
  •  -1
  •   Simon D    16 年前

    基于以下事实,在当前版本的POI中似乎无法执行此操作:

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

    仍然很出色。

        18
  •  -1
  •   Nagen Biswal.    11 年前

    cell.setcelltype(cell.cell_type_string);对我来说工作正常

        19
  •  -1
  •   FelixSFD Tushar Panjwani    9 年前

    投射到int然后执行 .toString() . 它很难看,但很管用。

        20
  •  -1
  •   Rama Krishna    9 年前

    这对我很好。

    Double legacyRow = row.getCell(col).getNumericCellValue();
    String legacyRowStr = legacyRow.toString();
    if(legacyRowStr.contains(".0")){
        legacyRowStr = legacyRowStr.substring(0, legacyRowStr.length()-2);
    }
    
    推荐文章