用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()显示的重要决定的结果。