diff --git a/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java b/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java index 6bfd8252..f7cb1ced 100644 --- a/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java @@ -68,6 +68,7 @@ public abstract class AbstractHolder implements ConfigurationHolder { } else { globalConfiguration.setLocale(basicParameter.getLocale()); } + } public Boolean getNewInitialization() { diff --git a/src/main/java/com/alibaba/excel/metadata/BasicParameter.java b/src/main/java/com/alibaba/excel/metadata/BasicParameter.java index d00c93a8..5baf5cf5 100644 --- a/src/main/java/com/alibaba/excel/metadata/BasicParameter.java +++ b/src/main/java/com/alibaba/excel/metadata/BasicParameter.java @@ -41,6 +41,13 @@ public class BasicParameter { */ private Locale locale; + /** + * Whether to use scientific Format. + * + * default is false + */ + private Boolean useScientificFormat; + public List> 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 list = EasyExcel.read(file).useScientificFormat(false).sheet().headRowNumber(0).doReadSync(); LOGGER.info("数据:{}", list.size()); for (Object data : list) { LOGGER.info("返回数据:{}", JSON.toJSONString(data)); diff --git a/update.md b/update.md index b0fbc64d..a43d3fe7 100644 --- a/update.md +++ b/update.md @@ -1,5 +1,6 @@ # 2.2.4 * 撤销删除`AbstractMergeStrategy` +* 修改默认用String读取数字不使用科学计数法 通过`useScientificFormat`修改 # 2.2.3