用HSSF从Excel中读取string值,但它是双重的

我正在使用HSSF-POI来读取excel数据。 问题是我有一个单元格中的值看起来像一个数字,但实际上是string。 如果我在Excel中查看格式单元格,它说types是“文本”。 HSSF Cell仍认为它是数字。 我怎样才能得到一个string的价值?

如果我尝试使用cell.getRichStringValue ,我得到exception; 如果cell.toString ,它不是在Excel表中完全相同的值。

编辑 :直到这得到解决,我会用

 new BigDecimal(cell.getNumericCellValue()).toString() 

你的意思是HSSF-POI说

cell.getCellType() == Cell.CELL_TYPE_NUMERIC

Cell.CELL_TYPE_STRING因为它应该是?

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

PS不能在包含数字的Variant上使用任何getString() ,因为Variant数据的二进制表示取决于它的types,并且试图从实际上是数字的字符中获取string将导致垃圾 – 因此是例外。

您在POI中寻找的类是DataFormatter

当Excel写入文件时,一些单元格存储为文字string,而其他单元格存储为数字。 对于后者,代表单元的浮点值被存储在文件中,所以当你向POI询问实际上具有的单元的值时。

有时候,特别是在进行文本提取(但并非总是)时,您希望使单元格的值看起来像在Excel中一样。 并不总是可以在String中得到它(例如非满的空格填充),但DataFormatter类会让你closures。

如果你在单元格的string之后,看起来就像你在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单元格,而对于数字单元格,则将样式上的格式化规则应用于单元格的编号

如果您正在parsing的文档始终处于特定的布局中,则可以将单元格types更改为“string”,然后检索该值。 例如,如果第2列应始终为string数据,请将其单元格types设置为string,然后使用stringtypes的get方法读取它。

 cell.setCellType(Cell.CELL_TYPE_STRING); 

在我的testing中,更改单元格types不会修改单元格的内容,但确实允许使用以下任一方法来检索它:

 cell.getStringCellValue(); cell.getRichStringCellValue().getString(); 

如果没有一个没有正确转换的值的例子,很难知道这个行为与你在描述中描述的cell.toString()方法有什么不同。

这下面的代码工作正常阅读任何单元格,但该单元格应包含数值

 new BigDecimal(cell.getNumericCellValue())); 

例如

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

其中variablesgss是BigDecimaltypes。

Excel将从string转换任何看起来像数字或date或时间的东西。 请参阅MS知识库文章 ,基本上build议用一个额外的字符input数字,使其成为一个string。

你可能正在处理一个Excel问题。 当您创build电子表格时,默认的单元格types是“通用”。 使用这种types,Excel根据input猜测types,这种types与每个单元格一起保存。

当您稍后将单元格格式更改为文本时,您只是更改默认值。 Excel不会自动更改每个单元格的types。 我还没有find一种方法来自动执行此操作。

要确认这一点,你可以去Excel,重新键入其中一个数字,看看它是否是HSSF中的文本。

您也可以使用此function查看真实的细胞types,

  @Cell("type", A1) 

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

Excel的问题是默认格式是通用的。 使用这种格式,Excel将单元格中input的数字存储为数字。 input值之前,您必须将格式更改为文本。 更改格式后重新input值也将起作用。
如果内容看起来像Excel中的数字,那么会在单元格的左上angular导致几乎没有绿色的三angular形。 如果是这种情况,则该值实际上被存储为文本。

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

我尝试彻底地解释如何正确地创buildExcel到创build我必须用POI处理的文件的聚会。 如果文件是由最终用户上传的,我甚至已经创build了一个validation程序来检查预期的单元格types,如果我事先知道列。 作为副产品,您还可以检查提供的文件的各种其他内容(例如,提供的正确列或强制值)。

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

“但真的是string”=>这是什么意思? 你怎么知道他们真的是string?

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

'…在Excel中,它表示types是“文本”=>请解释。

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

“我怎样才能得到一个string的价值? => 如果是NUMERIC,则使用the_cell.getNumericCellValue()获取数字值,然后将其格式化为任意string。

“如果我尝试使用cell.getRichStringValue,我会得到exception;” =>所以这不是一个string。

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

无论启发式Excel用什么来确定types与你无关。 这是存储在文件中并由getCellType()显示的重要决定的结果。