diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index 1d7c59882..766ded18f 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;