> getHead() {
return head;
}
@@ -88,4 +95,12 @@ public class BasicParameter {
public void setLocale(Locale locale) {
this.locale = locale;
}
+
+ public Boolean getUseScientificFormat() {
+ return useScientificFormat;
+ }
+
+ public void setUseScientificFormat(Boolean useScientificFormat) {
+ this.useScientificFormat = useScientificFormat;
+ }
}
diff --git a/src/main/java/com/alibaba/excel/metadata/GlobalConfiguration.java b/src/main/java/com/alibaba/excel/metadata/GlobalConfiguration.java
index 12cc8d31..26f3720f 100644
--- a/src/main/java/com/alibaba/excel/metadata/GlobalConfiguration.java
+++ b/src/main/java/com/alibaba/excel/metadata/GlobalConfiguration.java
@@ -25,6 +25,12 @@ public class GlobalConfiguration {
* used when formatting dates and numbers.
*/
private Locale locale;
+ /**
+ * Whether to use scientific Format.
+ *
+ * default is false
+ */
+ private Boolean useScientificFormat;
public Boolean getUse1904windowing() {
return use1904windowing;
@@ -49,4 +55,12 @@ public class GlobalConfiguration {
public void setLocale(Locale locale) {
this.locale = locale;
}
+
+ public Boolean getUseScientificFormat() {
+ return useScientificFormat;
+ }
+
+ public void setUseScientificFormat(Boolean useScientificFormat) {
+ this.useScientificFormat = useScientificFormat;
+ }
}
diff --git a/src/main/java/com/alibaba/excel/metadata/DataFormatter.java b/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java
similarity index 96%
rename from src/main/java/com/alibaba/excel/metadata/DataFormatter.java
rename to src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java
index 7467cd26..0bc70d16 100644
--- a/src/main/java/com/alibaba/excel/metadata/DataFormatter.java
+++ b/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java
@@ -15,7 +15,7 @@
* can be found in svn at location root/projects/3rd-party/src
* ====================================================================
*/
-package com.alibaba.excel.metadata;
+package com.alibaba.excel.metadata.format;
import java.math.BigDecimal;
import java.math.RoundingMode;
@@ -35,12 +35,12 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.ss.usermodel.DateUtil;
-import org.apache.poi.ss.usermodel.ExcelGeneralNumberFormat;
import org.apache.poi.ss.usermodel.ExcelStyleDateFormatter;
import org.apache.poi.ss.usermodel.FractionFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.util.DateUtils;
/**
@@ -138,21 +138,32 @@ public class DataFormatter {
* @return
*/
private Boolean use1904windowing;
-
/**
- * Creates a formatter using the {@link Locale#getDefault() default locale}.
+ * Whether to use scientific Format.
+ *
+ * default is false
*/
- public DataFormatter() {
- this(null, null);
- }
+ private Boolean useScientificFormat;
/**
* Creates a formatter using the given locale.
*
*/
- public DataFormatter(Locale locale, Boolean use1904windowing) {
- this.use1904windowing = use1904windowing != null ? use1904windowing : Boolean.FALSE;
- this.locale = locale != null ? locale : Locale.getDefault();
+ public DataFormatter(GlobalConfiguration globalConfiguration) {
+ if (globalConfiguration == null) {
+ this.use1904windowing = Boolean.FALSE;
+ this.locale = Locale.getDefault();
+ this.useScientificFormat = Boolean.FALSE;
+ } else {
+ this.use1904windowing =
+ globalConfiguration.getUse1904windowing() != null ? globalConfiguration.getUse1904windowing()
+ : Boolean.FALSE;
+ this.locale =
+ globalConfiguration.getLocale() != null ? globalConfiguration.getLocale() : Locale.getDefault();
+ this.useScientificFormat =
+ globalConfiguration.getUseScientificFormat() != null ? globalConfiguration.getUseScientificFormat()
+ : Boolean.FALSE;
+ }
this.dateSymbols = DateFormatSymbols.getInstance(this.locale);
this.decimalSymbols = DecimalFormatSymbols.getInstance(this.locale);
}
@@ -532,7 +543,7 @@ public class DataFormatter {
return defaultNumFormat;
// otherwise use general format
}
- defaultNumFormat = new ExcelGeneralNumberFormat(locale);
+ defaultNumFormat = new ExcelGeneralNumberFormat(locale, useScientificFormat);
return defaultNumFormat;
}
diff --git a/src/main/java/com/alibaba/excel/metadata/format/ExcelGeneralNumberFormat.java b/src/main/java/com/alibaba/excel/metadata/format/ExcelGeneralNumberFormat.java
new file mode 100644
index 00000000..cdeb5e85
--- /dev/null
+++ b/src/main/java/com/alibaba/excel/metadata/format/ExcelGeneralNumberFormat.java
@@ -0,0 +1,81 @@
+package com.alibaba.excel.metadata.format;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+import org.apache.poi.ss.usermodel.DataFormatter;
+
+/**
+ * Written with reference to {@link org.apache.poi.ss.usermodel.ExcelGeneralNumberFormat }.
+ *
+ * Supported Do not use scientific notation.
+ *
+ * @author JiaJu Zhuang
+ **/
+public class ExcelGeneralNumberFormat extends Format {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final MathContext TO_10_SF = new MathContext(10, RoundingMode.HALF_UP);
+
+ private final DecimalFormatSymbols decimalSymbols;
+ private final DecimalFormat integerFormat;
+ private final DecimalFormat decimalFormat;
+ private final DecimalFormat scientificFormat;
+
+ public ExcelGeneralNumberFormat(final Locale locale, final boolean useScientificFormat) {
+ decimalSymbols = DecimalFormatSymbols.getInstance(locale);
+ // Supported Do not use scientific notation.
+ if (useScientificFormat) {
+ scientificFormat = new DecimalFormat("0.#####E0", decimalSymbols);
+ } else {
+ scientificFormat = new DecimalFormat("#", decimalSymbols);
+ }
+ org.apache.poi.ss.usermodel.DataFormatter.setExcelStyleRoundingMode(scientificFormat);
+ integerFormat = new DecimalFormat("#", decimalSymbols);
+ org.apache.poi.ss.usermodel.DataFormatter.setExcelStyleRoundingMode(integerFormat);
+ decimalFormat = new DecimalFormat("#.##########", decimalSymbols);
+ DataFormatter.setExcelStyleRoundingMode(decimalFormat);
+ }
+
+ @Override
+ public StringBuffer format(Object number, StringBuffer toAppendTo, FieldPosition pos) {
+ final double value;
+ if (number instanceof Number) {
+ value = ((Number) number).doubleValue();
+ if (Double.isInfinite(value) || Double.isNaN(value)) {
+ return integerFormat.format(number, toAppendTo, pos);
+ }
+ } else {
+ // testBug54786 gets here with a date, so retain previous behaviour
+ return integerFormat.format(number, toAppendTo, pos);
+ }
+
+ final double abs = Math.abs(value);
+ if (abs >= 1E11 || (abs <= 1E-10 && abs > 0)) {
+ return scientificFormat.format(number, toAppendTo, pos);
+ } else if (Math.floor(value) == value || abs >= 1E10) {
+ // integer, or integer portion uses all 11 allowed digits
+ return integerFormat.format(number, toAppendTo, pos);
+ }
+ // Non-integers of non-scientific magnitude are formatted as "up to 11
+ // numeric characters, with the decimal point counting as a numeric
+ // character". We know there is a decimal point, so limit to 10 digits.
+ // https://support.microsoft.com/en-us/kb/65903
+ final double rounded = new BigDecimal(value).round(TO_10_SF).doubleValue();
+ return decimalFormat.format(rounded, toAppendTo, pos);
+ }
+
+ @Override
+ public Object parseObject(String source, ParsePosition pos) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/src/main/java/com/alibaba/excel/read/builder/AbstractExcelReaderParameterBuilder.java b/src/main/java/com/alibaba/excel/read/builder/AbstractExcelReaderParameterBuilder.java
index 4e5e3702..29d676cb 100644
--- a/src/main/java/com/alibaba/excel/read/builder/AbstractExcelReaderParameterBuilder.java
+++ b/src/main/java/com/alibaba/excel/read/builder/AbstractExcelReaderParameterBuilder.java
@@ -31,6 +31,19 @@ public abstract class AbstractExcelReaderParameterBuilder list = EasyExcel.read(file).sheet().headRowNumber(0).doReadSync();
+ List