Java ApachePOI-如何像Excel在单元格编辑器中那样对数字进行舍入

Java ApachePOI-如何像Excel在单元格编辑器中那样对数字进行舍入,java,excel,apache-poi,Java,Excel,Apache Poi,我使用ApachePOI“XSSF和SAX事件API”导入Excel文件 我正在用ApachePOI解析原始值,我想问,我如何才能像Excel GUI对单元格编辑器所做的那样对这些原始值进行舍入。以下示例说明了该问题: Raw: 1.9210999999999999E-2 (value is stored like this in xlsx-file) Edit: 1.9211% (user sees this value in ex

我使用ApachePOI“XSSF和SAX事件API”导入Excel文件

我正在用ApachePOI解析原始值,我想问,我如何才能像Excel GUI对单元格编辑器所做的那样对这些原始值进行舍入。以下示例说明了该问题:

Raw:      1.9210999999999999E-2     (value is stored like this in xlsx-file)
Edit:     1.9211%                   (user sees this value in excel cell-editor)
View:     1.92%                     (user sees this value in excel grid-overview)
Format:   0.00%                     (the cell-style)
Excel如何将原始值读取为编辑值?Excel如何知道它需要在小数点分隔符后四舍五入到4位数的小数点。ApachePOI如何帮助我做到这一点,以便我也可以在Excel导入中使用编辑值(而不是视图值)

我见过一张类似的票,上面写着Excel是如何做到的:


在这张罚单中,我想问,Apache POI如何帮助我,使我不需要在这里重新发明轮子,并实现Excels算法。

Excel根据IEEE 754规范获得双精度值,然后在显示在工作表中之前将其舍入到15位有效数字

为了达到同样的效果,可以根据15位精度的设置使用四舍五入

import java.math.BigDecimal;
import java.math.MathContext;

class ReadLongNumbersAsExcel {

 public static void main(String[] args) throws Exception{

  String v = "1.921099999999999E-2";
  double d = Double.parseDouble(v);
  System.out.println("raw: " + v);
  System.out.println("double: " + d);
  BigDecimal bd = new BigDecimal(d);
  v = bd.round(new MathContext(15)).toPlainString();
  System.out.println("like Excel: " + v);

 }
}
%
是一种特殊情况,因为Excel在这种情况下不显示实际存储的值,而是显示该值乘以100,后跟“%”。所以,如果你想要同样的,那就做同样的事。在将原始值四舍五入到15位有效数字后,执行与100相乘并附加“%”的操作


但是,如果只需要像Excel中那样获取格式化值,那么请参见Excel根据IEEE 754规范获取双精度值,然后在显示在工作表中之前将其舍入到15位有效数字

为了达到同样的效果,可以根据15位精度的设置使用四舍五入

import java.math.BigDecimal;
import java.math.MathContext;

class ReadLongNumbersAsExcel {

 public static void main(String[] args) throws Exception{

  String v = "1.921099999999999E-2";
  double d = Double.parseDouble(v);
  System.out.println("raw: " + v);
  System.out.println("double: " + d);
  BigDecimal bd = new BigDecimal(d);
  v = bd.round(new MathContext(15)).toPlainString();
  System.out.println("like Excel: " + v);

 }
}
%
是一种特殊情况,因为Excel在这种情况下不显示实际存储的值,而是显示该值乘以100,后跟“%”。所以,如果你想要同样的,那就做同样的事。在将原始值四舍五入到15位有效数字后,执行与100相乘并附加“%”的操作


但是,如果只需要像Excel中那样获取格式化值,那么请参见

如果使用
getNumericCellValue()
,则将获得原始的双精度值,然后可以根据需要对其进行解析/舍入。您可能需要更具体地说明您试图执行的操作,因为您可能过于复杂。“编辑:1.9211(用户在excel单元格编辑器中看到此值)”:不,在这种情况下,我的excel显示1.9211%。@AxelRichter您在单元格编辑器中的“1.9211%”是正确的。我现在在我的示例中修复了它。如果您使用
getNumericCellValue()
,您将获得原始双精度,然后您可以根据需要对其进行解析/舍入。您可能需要更具体地说明您试图执行的操作,因为您可能过于复杂。“编辑:1.9211(用户在excel单元格编辑器中看到此值)”:不,在这种情况下,我的excel显示1.9211%。@AxelRichter您在单元格编辑器中的“1.9211%”是正确的。我现在在我的示例中修复了它。这回答了我的问题。也感谢您解释%的情况。我天真地认为ApachePOI应该为此提供一个实用函数。@funkrusher:“我认为ApachePOI应该为此提供一个实用函数”:为什么?要获取单元格中Excel显示的内容,需要进行以下操作。当Excel在编辑模式下显示内容时,要求获取内容的背景是什么?因为poi提供了一个数据格式化程序来获取单元格中显示的内容,所以poi也可以为编辑模式的内容提供一个数据格式化程序,因为它也有助于导入/导出场景,在这种场景中,必须以不受显示样式影响的方式处理数据。我想说的是,我将使用DataFormatter来解决我的问题,因为我不想重新实现框架应该为我解决的一些问题。我知道我可以走多远,如果你的解决方案不够好,我会回到你的解决方案上来。@funkrusher:“以一种不受显示样式影响的方式处理数据”:然后使用原始存储值,记住在其中使用浮点数值时始终存在的浮点数问题。这就是使用基数不同的数字系统的缺点——二进制和十进制。这回答了我的问题。也感谢您解释%的情况。我天真地认为ApachePOI应该为此提供一个实用函数。@funkrusher:“我认为ApachePOI应该为此提供一个实用函数”:为什么?要获取单元格中Excel显示的内容,需要进行以下操作。当Excel在编辑模式下显示内容时,要求获取内容的背景是什么?因为poi提供了一个数据格式化程序来获取单元格中显示的内容,所以poi也可以为编辑模式的内容提供一个数据格式化程序,因为它也有助于导入/导出场景,在这种场景中,必须以不受显示样式影响的方式处理数据。我想说的是,我将使用DataFormatter来解决我的问题,因为我不想重新实现框架应该为我解决的一些问题。我知道我可以走多远,如果你的解决方案不够好,我会回到你的解决方案上来。@funkrusher:“以一种不受显示样式影响的方式处理数据”:然后使用原始存储值,记住在其中使用浮点数值时始终存在的浮点数问题。这就是使用基数不同的数字系统的缺点——二进制和十进制。