【问题标题】:Format Issue while reading excel data into Java将excel数据读入Java时出现格式问题
【发布时间】:2015-01-20 08:25:29
【问题描述】:

我正在使用 java apache 读取 Excel 数据。我在将诸如 869.87929(在 excel 中)之类的双值读取到 869.8792899999999(在 java 中)时遇到了格式问题。

我正在使用以下文件来读取 excel 数据。
1. Schema.csv:SheetName,2-int-Double

2. 文件.xls:

col1 | col2 123 | 869.87929

示例代码:

if(type.equals("Double")){
            Double fval=Double.parseDouble(content[i-1]);
            String sval=fval.toString();
            listObjects.add(new Double(Double.parseDouble(sval)));
        }

注意:来自 schema.csv 的类型和来自 file.xls 的内容 [] 值

【问题讨论】:

  • Floating point arithmetic. 你真的担心 1E-13 的差异吗??
  • if(type.equals("Double")){ String str = content[i-1]; //System.out.println(str); BigDecimal d = new BigDecimal(str); listObjects.add(d);如果我打印 str,它显示的值为 869.8792899999999。但我需要将 str 值设为 869.87929。我怎样才能得到它?

标签: java excel apache-poi export-to-csv


【解决方案1】:

没有必要将数字来回转换为字符串,因为这不应该做任何有用的事情。

尝试做

listObjects.add(new BigDecimal(content[i-1]));

你可以做四舍五入

listObjects.add(new BigDecimal(content[i-1]).setScale(9, RoundingMode.HALF_UP));

虽然我怀疑在此之前发生了舍入错误,因为这应该与

listObjects.add(new Double(content[i-1]));

你可以做四舍五入

double d = Double.parseDouble(content[i-1]);
double round9 = Math.round(d * 1e9) / 1e9;
listObjects.add((Double) round9);

这些与数字在双精度范围内大致相同,这里应该没有额外的错误(即错误很可能在此之前)

【讨论】:

  • if(type.equals("Double")){ String str = content[i-1]; //System.out.println(str); BigDecimal d = new BigDecimal(str); listObjects.add(d);如果我打印 str,它显示的值为 869.8792899999999。但我需要将 str 值设为 869.87929。我怎样才能得到它?
  • @Stone,因为我怀疑您的号码在来源处存在舍入错误。要删除9s,您需要对结果进行四舍五入。可以四舍五入到小数点后 6 位或 9 位吗?
  • @Stone 查看我的答案以获取舍入示例。
  • 谢谢彼得。在某些情况下,我们需要 Excel 中的 9 位小数。在这种情况下,当我们要四舍五入小数点后 6 位时,它可能会失败。例如; excel 值 0.737837838 并且要四舍五入 6 位小数,我们没有像在 java 中那样得到 excel 值。
  • @Stone 将代码更改为小数点后 9 位。我怀疑excel在显示错误时会隐藏错误,我不知道excel为此使用的规则,但我怀疑它会砍掉一个数字。
【解决方案2】:

Double 不利于保持精度。首选是使用 BigDecimal。我相信这是你的问题。

https://blogs.oracle.com/CoreJavaTechTips/entry/the_need_for_bigdecimal

【讨论】:

    【解决方案3】:

    如果您使用 Apache POI - 您可以使用getCellType()==Cell.CELL_TYPE_NUMERIC 比较和来自Cell 接口的getNumericCellValue()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      • 1970-01-01
      • 2011-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-28
      相关资源
      最近更新 更多