我正在使用HSSF-POI来读取Excel数据。问题是我在单元格中的值看起来像一个数字,但实际上是字符串。如果我在Excel中查看格式单元格,则表示类型为“text”。 HSSF Cell仍然认为它是数字的。如何将值作为字符串获取?

如果我尝试使用 cell.getRichStringValue ,我会得到异常; if cell.toString ,它与Excel表格中的值不完全相同。

修改:在此问题得到解决之前,我将使用

new BigDecimal(cell.getNumericCellValue()).toString()
有帮助吗?

解决方案

你的意思是HSSF-POI说

cell.getCellType()== Cell.CELL_TYPE_NUMERIC

不是

应该是

Cell.CELL_TYPE_STRING

我认为这是POI中的一个错误,但每个单元格都包含一个Variant,Variant有一个类型。在那里制作一个bug很难,所以我认为Excel使用一些额外的数据或启发式来将字段报告为文本。通常的MS方式,唉。

P.S。你不能在包含numeric的Variant上使用任何 getString(),因为Variant数据的二进制表示取决于它的类型,并且尝试从实际上是一个数字的字符串中获取一个字符串会导致垃圾 - - 因此例外。

其他提示

您在POI中寻找的课程是 DataFormatter

当Excel写入文件时,某些单元格存储为文字字符串,而其他单元格存储为数字。对于后者,表示单元格的浮点值存储在文件中,因此当您向POI询问单元格的值时,它实际上具有该值。

有时候,特别是在进行文本提取时(但并非总是如此),您希望使单元格值与Excel中的一样。并不总是能够在String(例如非完整空间填充)中完全得到它,但是DataFormatter类会让你关闭。

如果您正在查看单元格的字符串,看起来就像在Excel中查找一样,只需执行以下操作:

 // Create a formatter, do this once
 DataFormatter formatter = new DataFormatter(Locale.US);

 .....

 for(Cell cell : row) {
     CellReference ref = new CellReference(cell);
     // eg "The value of B12 is 12.4%"
     System.out.println("The value of " + ref.formatAsString() + " is " + formatter.formatCellValue(cell));
 }

格式化程序将按原样返回String单元格,对于Numeric单元格,将样式上的格式规则应用于单元格的数量

如果要解析的文档始终采用特定布局,则可以将单元格类型更改为“string”。在运行中然后检索值。例如,如果第2列应始终为字符串数据,请将其单元格类型设置为字符串,然后使用字符串类型的get方法读取它。

cell.setCellType(Cell.CELL_TYPE_STRING);

在我的测试中,更改单元格类型并未修改单元格的内容,但允许使用以下任一方法检索它:

cell.getStringCellValue();

cell.getRichStringCellValue().getString();

如果没有未正确转换的值的示例,很难知道它的行为是否与您在描述中描述的cell.toString()方法有任何不同。

以下代码可以正常读取任何单元格类型,但该单元格应包含数值

new BigDecimal(cell.getNumericCellValue()));

e.g。

ase.setGss(new BigDecimal(hssfRow.getCell(3).getNumericCellValue()));

其中变量gss是BigDecimal类型。

Excel将从字符串中转换任何看起来像数字或日期或时间的内容。请参阅 MS知识库文章,它基本上建议输入带有额外字符的数字一个字符串。

您可能正在处理Excel问题。创建电子表格时,默认单元格类型为Generic。使用此类型,Excel会根据输入猜测类型,并且每个单元格都会保存此类型。

稍后将单元格格式更改为“文本”时,您只需更改默认值。 Excel不会自动更改每个单元格的类型。我没有找到办法自动完成这项工作。

要确认这一点,您可以转到Excel并重新键入其中一个数字,然后查看它是否为HSSF中的文本。

您还可以使用此功能

查看真实的细胞类型
  @Cell("type", A1)

A1是该数字的单元格。它显示“l”。对于文本,“v”数字。

Excel的问题是默认格式是通用的。使用此格式,Excel将在单元格中输入的数字存储为数字。您必须在>输入值之前将格式更改为文本。更改格式后重新输入值也将有效。
如果内容看起来像Excel的数字,那将导致单元格左上角的绿色三角形变小。如果是这种情况,则该值实际上存储为文本。

使用新的BigDecimal(cell.getNumericCellValue())。toString(),你仍然会遇到很多问题。例如,如果您有识别号码(例如,部件号或分类号),则可能存在具有前导零的情况,这将是getNumericCellValue()方法的问题。

我尝试彻底解释如何正确创建Excel以创建我必须使用POI处理的文件。如果文件是由最终用户上传的,我甚至已经创建了一个验证程序,以便在我事先知道列时检查预期的单元格类型。作为副产品,您还可以检查所提供文件的各种其他内容(例如,提供的是正确的列还是必需的值)。

"问题是我在一个看起来像数字的单元格中有值“ =>在Excel中查看时看起来像数字?

“但实际上是字符串” =>那是什么意思?你怎么知道他们真的是字符串?

“如果我查看格式单元格” =>什么是“格式单元格”???

'...在Excel中,它表示类型为“text”“ =>请解释一下。

“仍然HSSF Cell认为它是数字的。” =>你的意思是the_cell.getCellType()返回Cell.CELL_TYPE_NUMERIC?

“如何将值作为字符串获取?” => 如果是NUMERIC,请使用the_cell.getNumericCellValue()获取数值,然后以任意方式将其格式化为字符串。

"如果我尝试使用cell.getRichStringValue,我会得到异常;" =>所以它不是一个字符串。

“如果是cell.toString,则它与Excel工作表中的值不完全相同。” =>所以cell.toString()不会像Excel那样格式化它。

无论启发式Excel用于确定类型,都与您无关。这是存储在文件中并由重要的getCellType()显示的决定的结果。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top