#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
This commit is contained in:
Nick Burch 2015-05-27 17:15:17 +00:00
parent 4e3011f70a
commit 77916b9364

View File

@ -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;