From d2cde65c30d7f197231367ee514cf47cd0dd422b Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Wed, 27 May 2015 17:15:17 +0000 Subject: [PATCH] #57951 Use BigDecimal in some cases in DataFormatter.formatRawCellContents, to avoid rounding problems on JDK8. Patch from Robert Kish git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1682083 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ss/usermodel/DataFormatter.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index 1d7c598828..766ded18fe 100644 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -20,6 +20,7 @@ ==================================================================== */ package org.apache.poi.ss.usermodel; +import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DateFormatSymbols; import java.text.DecimalFormat; @@ -38,6 +39,8 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.poi.ss.util.NumberToTextConverter; + /** * DataFormatter contains methods for formatting the value stored in an @@ -755,14 +758,28 @@ public class DataFormatter { return invalidDateTimeString; } } + // else Number Format numberFormat = getFormat(value, formatIndex, formatString); if (numberFormat == null) { return String.valueOf(value); } - // RK: This hack handles scientific notation by adding the missing + back. - String result = numberFormat.format(new Double(value)); - if (result.contains("E") && !result.contains("E-")) { + + // When formatting 'value', double to text to BigDecimal produces more + // accurate results than double to Double in JDK8 (as compared to + // previous versions). However, if the value contains E notation, this + // would expand the values, which we do not want, so revert to + // original method. + String result; + final String textValue = NumberToTextConverter.toText(value); + if (textValue.indexOf('E') > -1) { + result = numberFormat.format(new Double(value)); + } + else { + result = numberFormat.format(new BigDecimal(textValue)); + } + // Complete scientific notation by adding the missing +. + if (result.indexOf('E') > -1 && !result.contains("E-")) { result = result.replaceFirst("E", "E+"); } return result;