From 35558838718454cf4784f70288fc90960c07e403 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Tue, 24 Dec 2019 20:44:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=94=A8String=E6=8E=A5?= =?UTF-8?q?=E6=94=B6=E6=97=A5=E6=9C=9F=E3=80=81=E6=95=B0=E5=AD=97=E5=92=8C?= =?UTF-8?q?excel=E6=98=BE=E7=A4=BA=E4=B8=8D=E4=B8=80=E8=87=B4=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 +- .../excel/analysis/ExcelAnalyserImpl.java | 9 + .../excel/analysis/v03/XlsSaxAnalyser.java | 6 +- .../v03/handlers/NumberRecordHandler.java | 13 +- .../v07/handlers/DefaultCellHandler.java | 8 +- .../excel/constant/BuiltinFormats.java | 193 +++++++++++++++++- .../excel/context/AnalysisContext.java | 1 - .../excel/context/WriteContextImpl.java | 9 + .../byteconverter/ByteNumberConverter.java | 2 +- .../floatconverter/FloatNumberConverter.java | 2 +- .../integer/IntegerNumberConverter.java | 2 +- .../shortconverter/ShortNumberConverter.java | 2 +- .../excel/metadata/AbstractHolder.java | 12 +- .../metadata/AbstractParameterBuilder.java | 93 +++++++++ .../alibaba/excel/metadata/DataFormatter.java | 4 +- .../AbstractExcelReaderParameterBuilder.java | 47 +++++ .../read/builder/ExcelReaderBuilder.java | 103 +--------- .../read/builder/ExcelReaderSheetBuilder.java | 101 +-------- .../com/alibaba/excel/util/DateUtils.java | 5 +- .../excel/util/NumberDataFormatterUtils.java | 5 +- .../excel/util/ThreadLocalCachedUtils.java | 14 -- .../AbstractExcelWriterParameterBuilder.java | 104 ++++++++++ .../write/builder/ExcelWriterBuilder.java | 133 +----------- .../builder/ExcelWriterSheetBuilder.java | 136 +----------- .../builder/ExcelWriterTableBuilder.java | 135 +----------- .../test/core/dataformat/DateFormatData.java | 6 +- .../test/core/dataformat/DateFormatTest.java | 27 ++- .../test/temp/dataformat/DataFormatTest.java | 2 +- .../easyexcel/test/temp/poi/PoiWriteTest.java | 12 ++ .../easyexcel/test/temp/simple/JsonData.java | 15 ++ .../easyexcel/test/temp/simple/Wirte.java | 41 +++- .../easyexcel/test/temp/simple/WriteData.java | 13 ++ src/test/resources/dataformat/dataformat.xls | Bin 0 -> 26112 bytes src/test/resources/dataformat/dataformat.xlsx | Bin 11489 -> 11754 bytes update.md | 6 + 35 files changed, 618 insertions(+), 647 deletions(-) create mode 100644 src/main/java/com/alibaba/excel/metadata/AbstractParameterBuilder.java create mode 100644 src/main/java/com/alibaba/excel/read/builder/AbstractExcelReaderParameterBuilder.java delete mode 100644 src/main/java/com/alibaba/excel/util/ThreadLocalCachedUtils.java create mode 100644 src/main/java/com/alibaba/excel/write/builder/AbstractExcelWriterParameterBuilder.java create mode 100644 src/test/java/com/alibaba/easyexcel/test/temp/simple/JsonData.java create mode 100644 src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteData.java create mode 100644 src/test/resources/dataformat/dataformat.xls diff --git a/pom.xml b/pom.xml index 7e2235cb..5aff4234 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ UTF-8 - 1.7 + 1.6 @@ -84,7 +84,7 @@ org.ehcache ehcache - 3.7.1 + 3.4.0 diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java index eb4f1886..feec16b6 100644 --- a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java +++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java @@ -22,7 +22,9 @@ import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.util.CollectionUtils; +import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.FileUtils; +import com.alibaba.excel.util.NumberDataFormatterUtils; import com.alibaba.excel.util.StringUtils; /** @@ -175,11 +177,18 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { clearEncrypt03(); + removeThreadLocalCache(); + if (throwable != null) { throw new ExcelAnalysisException("Can not close IO.", throwable); } } + private void removeThreadLocalCache() { + NumberDataFormatterUtils.removeThreadLocalCache(); + DateUtils.removeThreadLocalCache(); + } + private void clearEncrypt03() { if (StringUtils.isEmpty(analysisContext.readWorkbookHolder().getPassword()) || !ExcelTypeEnum.XLS.equals(analysisContext.readWorkbookHolder().getExcelType())) { diff --git a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java index e0c150cd..fd73e672 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java @@ -3,10 +3,10 @@ package com.alibaba.excel.analysis.v03; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.TreeMap; import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder; import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; @@ -191,7 +191,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor { analysisContext.readRowHolder( new ReadRowHolder(lastRowNumber, analysisContext.readSheetHolder().getGlobalConfiguration())); analysisContext.readSheetHolder().notifyEndOneRow(new EachRowAnalysisFinishEvent(records), analysisContext); - records.clear(); + records = new HashMap(); lastColumnNumber = -1; } @@ -208,7 +208,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor { recordHandlers.add(new FormulaRecordHandler(stubWorkbook, formatListener)); recordHandlers.add(new LabelRecordHandler()); recordHandlers.add(new NoteRecordHandler()); - recordHandlers.add(new NumberRecordHandler(formatListener)); + recordHandlers.add(new NumberRecordHandler(analysisContext, formatListener)); recordHandlers.add(new RkRecordHandler()); recordHandlers.add(new SstRecordHandler()); recordHandlers.add(new MissingCellDummyRecordHandler()); diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java index d8f35240..af024882 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java @@ -8,6 +8,7 @@ import org.apache.poi.hssf.record.Record; import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler; import com.alibaba.excel.constant.BuiltinFormats; +import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.metadata.CellData; /** @@ -18,7 +19,10 @@ import com.alibaba.excel.metadata.CellData; public class NumberRecordHandler extends AbstractXlsRecordHandler { private FormatTrackingHSSFListener formatListener; - public NumberRecordHandler(FormatTrackingHSSFListener formatListener) { + private AnalysisContext context; + + public NumberRecordHandler(AnalysisContext context, FormatTrackingHSSFListener formatListener) { + this.context = context; this.formatListener = formatListener; } @@ -35,11 +39,8 @@ public class NumberRecordHandler extends AbstractXlsRecordHandler { this.cellData = new CellData(BigDecimal.valueOf(numrec.getValue())); int dataFormat = formatListener.getFormatIndex(numrec); this.cellData.setDataFormat(dataFormat); - if (dataFormat <= BuiltinFormats.builtinFormats.length) { - this.cellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat)); - } else { - this.cellData.setDataFormatString(formatListener.getFormatString(numrec)); - } + this.cellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, + formatListener.getFormatString(numrec), context.readSheetHolder().getGlobalConfiguration().getLocale())); } @Override diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java index 7312b2ca..3d96a902 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java @@ -88,11 +88,9 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger); int dataFormat = xssfCellStyle.getDataFormat(); currentCellData.setDataFormat(dataFormat); - if (dataFormat <= BuiltinFormats.builtinFormats.length) { - currentCellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat)); - } else { - currentCellData.setDataFormatString(xssfCellStyle.getDataFormatString()); - } + currentCellData.setDataFormatString( + BuiltinFormats.getBuiltinFormat(dataFormat, xssfCellStyle.getDataFormatString(), + analysisContext.readSheetHolder().getGlobalConfiguration().getLocale())); } } // cell is formula diff --git a/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java b/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java index 5663054e..1dec2c68 100644 --- a/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java +++ b/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java @@ -1,6 +1,6 @@ package com.alibaba.excel.constant; -import com.alibaba.excel.util.StringUtils; +import java.util.Locale; /** * Excel's built-in format conversion.Currently only supports Chinese. @@ -17,7 +17,179 @@ import com.alibaba.excel.util.StringUtils; **/ public class BuiltinFormats { - public static String[] builtinFormats = { + private static final String[] BUILTIN_FORMATS_CN = { + // 0 + "General", + // 1 + "0", + // 2 + "0.00", + // 3 + "#,##0", + // 4 + "#,##0.00", + // 5 + "\"¥\"#,##0_);(\"¥\"#,##0)", + // 6 + "\"¥\"#,##0_);[Red](\"¥\"#,##0)", + // 7 + "\"¥\"#,##0.00_);(\"¥\"#,##0.00)", + // 8 + "\"¥\"#,##0.00_);[Red](\"¥\"#,##0.00)", + // 9 + "0%", + // 10 + "0.00%", + // 11 + "0.00E+00", + // 12 + "# ?/?", + // 13 + "# ??/??", + // 14 + // The official documentation shows "m/d/yy", but the actual test is "yyyy/m/d". + "yyyy/m/d", + // 15 + "d-mmm-yy", + // 16 + "d-mmm", + // 17 + "mmm-yy", + // 18 + "h:mm AM/PM", + // 19 + "h:mm:ss AM/PM", + // 20 + "h:mm", + // 21 + "h:mm:ss", + // 22 + // The official documentation shows "m/d/yy h:mm", but the actual test is "yyyy/m/d h:mm". + "yyyy/m/d h:mm", + // 23-26 No specific correspondence found in the official documentation. + // 23 + null, + // 24 + null, + // 25 + null, + // 26 + null, + // 27 + "yyyy\"年\"m\"月\"", + // 28 + "m\"月\"d\"日\"", + // 29 + "m\"月\"d\"日\"", + // 30 + "m-d-yy", + // 31 + "yyyy\"年\"m\"月\"d\"日\"", + // 32 + "h\"时\"mm\"分\"", + // 33 + "h\"时\"mm\"分\"ss\"秒\"", + // 34 + "上午/下午h\"时\"mm\"分\"", + // 35 + "上午/下午h\"时\"mm\"分\"ss\"秒\"", + // 36 + "yyyy\"年\"m\"月\"", + // 37 + "#,##0_);(#,##0)", + // 38 + "#,##0_);[Red](#,##0)", + // 39 + "#,##0.00_);(#,##0.00)", + // 40 + "#,##0.00_);[Red](#,##0.00)", + // 41 + "_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)", + // 42 + "_(\"¥\"* #,##0_);_(\"¥\"* (#,##0);_(\"¥\"* \"-\"_);_(@_)", + // 43 + "_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)", + // 44 + "_(\"¥\"* #,##0.00_);_(\"¥\"* (#,##0.00);_(\"¥\"* \"-\"??_);_(@_)", + // 45 + "mm:ss", + // 46 + "[h]:mm:ss", + // 47 + "mm:ss.0", + // 48 + "##0.0E+0", + // 49 + "@", + // 50 + "yyyy\"年\"m\"月\"", + // 51 + "m\"月\"d\"日\"", + // 52 + "yyyy\"年\"m\"月\"", + // 53 + "m\"月\"d\"日\"", + // 54 + "m\"月\"d\"日\"", + // 55 + "上午/下午h\"时\"mm\"分\"", + // 56 + "上午/下午h\"时\"mm\"分\"ss\"秒\"", + // 57 + "yyyy\"年\"m\"月\"", + // 58 + "m\"月\"d\"日\"", + // 59 + "t0", + // 60 + "t0.00", + // 61 + "t#,##0", + // 62 + "t#,##0.00", + // 63-66 No specific correspondence found in the official documentation. + // 63 + null, + // 64 + null, + // 65 + null, + // 66 + null, + // 67 + "t0%", + // 68 + "t0.00%", + // 69 + "t# ?/?", + // 70 + "t# ??/??", + // 71 + "ว/ด/ปปปป", + // 72 + "ว-ดดด-ปป", + // 73 + "ว-ดดด", + // 74 + "ดดด-ปป", + // 75 + "ช:นน", + // 76 + "ช:นน:ทท", + // 77 + "ว/ด/ปปปป ช:นน", + // 78 + "นน:ทท", + // 79 + "[ช]:นน:ทท", + // 80 + "นน:ทท.0", + // 81 + "d/m/bb", + // end + }; + + private static final String[] BUILTIN_FORMATS_US = { // 0 "General", // 1 @@ -189,18 +361,19 @@ public class BuiltinFormats { // end }; - public static String getBuiltinFormat(Integer index) { - if (index == null || index < 0 || index >= builtinFormats.length) { - return null; + public static String getBuiltinFormat(Integer index, String defaultFormat, Locale locale) { + String[] builtinFormat = switchBuiltinFormats(locale); + if (index == null || index < 0 || index >= builtinFormat.length) { + return defaultFormat; } - return builtinFormats[index]; + return builtinFormat[index]; } - public static String getFormat(Integer index, String format) { - if (!StringUtils.isEmpty(format)) { - return format; + private static String[] switchBuiltinFormats(Locale locale) { + if (locale != null && Locale.US.getCountry().equals(locale.getCountry())) { + return BUILTIN_FORMATS_US; } - return getBuiltinFormat(index); + return BUILTIN_FORMATS_CN; } } diff --git a/src/main/java/com/alibaba/excel/context/AnalysisContext.java b/src/main/java/com/alibaba/excel/context/AnalysisContext.java index f44c2b38..66c69a52 100644 --- a/src/main/java/com/alibaba/excel/context/AnalysisContext.java +++ b/src/main/java/com/alibaba/excel/context/AnalysisContext.java @@ -2,7 +2,6 @@ package com.alibaba.excel.context; import java.io.InputStream; -import com.alibaba.excel.analysis.ExcelReadExecutor; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.read.metadata.ReadSheet; diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index 09358687..7b9bb81c 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java @@ -27,7 +27,9 @@ import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.FileUtils; +import com.alibaba.excel.util.NumberDataFormatterUtils; import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WriteHandlerUtils; @@ -327,6 +329,8 @@ public class WriteContextImpl implements WriteContext { clearEncrypt03(); + removeThreadLocalCache(); + if (throwable != null) { throw new ExcelGenerateException("Can not close IO.", throwable); } @@ -336,6 +340,11 @@ public class WriteContextImpl implements WriteContext { } } + private void removeThreadLocalCache() { + NumberDataFormatterUtils.removeThreadLocalCache(); + DateUtils.removeThreadLocalCache(); + } + @Override public Sheet getCurrentSheet() { return writeSheetHolder.getSheet(); diff --git a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java index 8c16a779..f1facdfb 100644 --- a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java @@ -34,7 +34,7 @@ public class ByteNumberConverter implements Converter { @Override public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(BigDecimal.valueOf(value)); + return new CellData(new BigDecimal(Byte.toString(value))); } } diff --git a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java index a1b64719..69cc22e7 100644 --- a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java @@ -34,7 +34,7 @@ public class FloatNumberConverter implements Converter { @Override public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(BigDecimal.valueOf(value)); + return new CellData(new BigDecimal(Float.toString(value))); } } diff --git a/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java b/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java index 3b0deac6..117d4c11 100644 --- a/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java @@ -34,7 +34,7 @@ public class IntegerNumberConverter implements Converter { @Override public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(BigDecimal.valueOf(value)); + return new CellData(new BigDecimal(Integer.toString(value))); } } diff --git a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java index 7d1d7da2..357c6aeb 100644 --- a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java @@ -34,7 +34,7 @@ public class ShortNumberConverter implements Converter { @Override public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(BigDecimal.valueOf(value)); + return new CellData(new BigDecimal(Short.toString(value))); } } diff --git a/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java b/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java index 37a19422..6bfd8252 100644 --- a/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java @@ -1,6 +1,7 @@ package com.alibaba.excel.metadata; import java.util.List; +import java.util.Locale; import java.util.Map; import com.alibaba.excel.converters.Converter; @@ -27,7 +28,6 @@ public abstract class AbstractHolder implements ConfigurationHolder { * Some global variables */ private GlobalConfiguration globalConfiguration; - /** *

* Read key: @@ -58,6 +58,16 @@ public abstract class AbstractHolder implements ConfigurationHolder { } else { globalConfiguration.setAutoTrim(basicParameter.getAutoTrim()); } + + if (basicParameter.getLocale() == null) { + if (prentAbstractHolder == null) { + globalConfiguration.setLocale(Locale.getDefault()); + } else { + globalConfiguration.setLocale(prentAbstractHolder.getGlobalConfiguration().getLocale()); + } + } else { + globalConfiguration.setLocale(basicParameter.getLocale()); + } } public Boolean getNewInitialization() { diff --git a/src/main/java/com/alibaba/excel/metadata/AbstractParameterBuilder.java b/src/main/java/com/alibaba/excel/metadata/AbstractParameterBuilder.java new file mode 100644 index 00000000..58400465 --- /dev/null +++ b/src/main/java/com/alibaba/excel/metadata/AbstractParameterBuilder.java @@ -0,0 +1,93 @@ +package com.alibaba.excel.metadata; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import com.alibaba.excel.converters.Converter; + +/** + * ExcelBuilder + * + * @author Jiaju Zhuang + */ +public abstract class AbstractParameterBuilder { + /** + * You can only choose one of the {@link #head(List)} and {@link #head(Class)} + * + * @param head + * @return + */ + public T head(List> head) { + parameter().setHead(head); + return self(); + } + + /** + * You can only choose one of the {@link #head(List)} and {@link #head(Class)} + * + * @param clazz + * @return + */ + public T head(Class clazz) { + parameter().setClazz(clazz); + return self(); + } + + /** + * Custom type conversions override the default. + * + * @param converter + * @return + */ + public T registerConverter(Converter converter) { + if (parameter().getCustomConverterList() == null) { + parameter().setCustomConverterList(new ArrayList()); + } + parameter().getCustomConverterList().add(converter); + return self(); + } + + /** + * true if date uses 1904 windowing, or false if using 1900 date windowing. + * + * default is false + * + * @param use1904windowing + * @return + */ + public T use1904windowing(Boolean use1904windowing) { + parameter().setUse1904windowing(use1904windowing); + return self(); + } + + /** + * A Locale object represents a specific geographical, political, or cultural region. This parameter is + * used when formatting dates and numbers. + * + * @param locale + * @return + */ + public T locale(Locale locale) { + parameter().setLocale(locale); + return self(); + } + + /** + * Automatic trim includes sheet name and content + * + * @param autoTrim + * @return + */ + public T autoTrim(Boolean autoTrim) { + parameter().setAutoTrim(autoTrim); + return self(); + } + + @SuppressWarnings("unchecked") + protected T self() { + return (T)this; + } + + protected abstract C parameter(); +} diff --git a/src/main/java/com/alibaba/excel/metadata/DataFormatter.java b/src/main/java/com/alibaba/excel/metadata/DataFormatter.java index 13bd1628..7467cd26 100644 --- a/src/main/java/com/alibaba/excel/metadata/DataFormatter.java +++ b/src/main/java/com/alibaba/excel/metadata/DataFormatter.java @@ -63,7 +63,8 @@ public class DataFormatter { private static final Pattern daysAsText = Pattern.compile("([d]{3,})", Pattern.CASE_INSENSITIVE); /** Pattern to find "AM/PM" marker */ - private static final Pattern amPmPattern = Pattern.compile("(([AP])[M/P]*)|(([上下])[午/下]*)", Pattern.CASE_INSENSITIVE); + private static final Pattern amPmPattern = + Pattern.compile("(([AP])[M/P]*)|(([上下])[午/下]*)", Pattern.CASE_INSENSITIVE); /** Pattern to find formats with condition ranges e.g. [>=100] */ private static final Pattern rangeConditionalPattern = @@ -152,7 +153,6 @@ public class DataFormatter { public DataFormatter(Locale locale, Boolean use1904windowing) { this.use1904windowing = use1904windowing != null ? use1904windowing : Boolean.FALSE; this.locale = locale != null ? locale : Locale.getDefault(); - this.locale = Locale.US; this.dateSymbols = DateFormatSymbols.getInstance(this.locale); this.decimalSymbols = DecimalFormatSymbols.getInstance(this.locale); } diff --git a/src/main/java/com/alibaba/excel/read/builder/AbstractExcelReaderParameterBuilder.java b/src/main/java/com/alibaba/excel/read/builder/AbstractExcelReaderParameterBuilder.java new file mode 100644 index 00000000..4e5e3702 --- /dev/null +++ b/src/main/java/com/alibaba/excel/read/builder/AbstractExcelReaderParameterBuilder.java @@ -0,0 +1,47 @@ +package com.alibaba.excel.read.builder; + +import java.util.ArrayList; + +import com.alibaba.excel.metadata.AbstractParameterBuilder; +import com.alibaba.excel.read.listener.ReadListener; +import com.alibaba.excel.read.metadata.ReadBasicParameter; + +/** + * Build ExcelBuilder + * + * @author Jiaju Zhuang + */ +public abstract class AbstractExcelReaderParameterBuilder extends AbstractParameterBuilder { + /** + * Count the number of added heads when read sheet. + * + *

+ * 0 - This Sheet has no head ,since the first row are the data + *

+ * 1 - This Sheet has one row head , this is the default + *

+ * 2 - This Sheet has two row head ,since the third row is the data + * + * @param headRowNumber + * @return + */ + public T headRowNumber(Integer headRowNumber) { + parameter().setHeadRowNumber(headRowNumber); + return self(); + } + + /** + * Custom type listener run after default + * + * @param readListener + * @return + */ + public T registerReadListener(ReadListener readListener) { + if (parameter().getCustomReadListenerList() == null) { + parameter().setCustomReadListenerList(new ArrayList()); + } + parameter().getCustomReadListenerList().add(readListener); + return self(); + } +} diff --git a/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java b/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java index 4f6cddaa..1bdfd6d2 100644 --- a/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java +++ b/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java @@ -2,8 +2,6 @@ package com.alibaba.excel.read.builder; import java.io.File; import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; import javax.xml.parsers.SAXParserFactory; @@ -11,9 +9,7 @@ import com.alibaba.excel.ExcelReader; import com.alibaba.excel.cache.ReadCache; import com.alibaba.excel.cache.selector.ReadCacheSelector; import com.alibaba.excel.context.AnalysisContext; -import com.alibaba.excel.converters.Converter; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.support.ExcelTypeEnum; @@ -22,7 +18,7 @@ import com.alibaba.excel.support.ExcelTypeEnum; * * @author Jiaju Zhuang */ -public class ExcelReaderBuilder { +public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder { /** * Workbook */ @@ -132,98 +128,6 @@ public class ExcelReaderBuilder { return this; } - /** - * Count the number of added heads when read sheet. - * - *

- * 0 - This Sheet has no head ,since the first row are the data - *

- * 1 - This Sheet has one row head , this is the default - *

- * 2 - This Sheet has two row head ,since the third row is the data - * - * @param headRowNumber - * @return - */ - public ExcelReaderBuilder headRowNumber(Integer headRowNumber) { - readWorkbook.setHeadRowNumber(headRowNumber); - return this; - } - - /** - * You can only choose one of the {@link ExcelReaderBuilder#head(List)} and {@link ExcelReaderBuilder#head(Class)} - * - * @param head - * @return - */ - public ExcelReaderBuilder head(List> head) { - readWorkbook.setHead(head); - return this; - } - - /** - * You can only choose one of the {@link ExcelReaderBuilder#head(List)} and {@link ExcelReaderBuilder#head(Class)} - * - * @param clazz - * @return - */ - public ExcelReaderBuilder head(Class clazz) { - readWorkbook.setClazz(clazz); - return this; - } - - /** - * Custom type conversions override the default. - * - * @param converter - * @return - */ - public ExcelReaderBuilder registerConverter(Converter converter) { - if (readWorkbook.getCustomConverterList() == null) { - readWorkbook.setCustomConverterList(new ArrayList()); - } - readWorkbook.getCustomConverterList().add(converter); - return this; - } - - /** - * Custom type listener run after default - * - * @param readListener - * @return - */ - public ExcelReaderBuilder registerReadListener(ReadListener readListener) { - if (readWorkbook.getCustomReadListenerList() == null) { - readWorkbook.setCustomReadListenerList(new ArrayList()); - } - readWorkbook.getCustomReadListenerList().add(readListener); - return this; - } - - /** - * true if date uses 1904 windowing, or false if using 1900 date windowing. - * - * default is false - * - * @param use1904windowing - * @return - */ - public ExcelReaderBuilder use1904windowing(Boolean use1904windowing) { - readWorkbook.setUse1904windowing(use1904windowing); - return this; - } - - /** - * Automatic trim includes sheet name and content - * - * @param autoTrim - * @return - */ - public ExcelReaderBuilder autoTrim(Boolean autoTrim) { - readWorkbook.setAutoTrim(autoTrim); - return this; - } - /** * Whether the encryption * @@ -285,4 +189,9 @@ public class ExcelReaderBuilder { } return excelReaderSheetBuilder; } + + @Override + protected ReadWorkbook parameter() { + return readWorkbook; + } } diff --git a/src/main/java/com/alibaba/excel/read/builder/ExcelReaderSheetBuilder.java b/src/main/java/com/alibaba/excel/read/builder/ExcelReaderSheetBuilder.java index d494e233..84ec6bae 100644 --- a/src/main/java/com/alibaba/excel/read/builder/ExcelReaderSheetBuilder.java +++ b/src/main/java/com/alibaba/excel/read/builder/ExcelReaderSheetBuilder.java @@ -1,14 +1,11 @@ package com.alibaba.excel.read.builder; -import java.util.ArrayList; import java.util.List; import com.alibaba.excel.ExcelReader; -import com.alibaba.excel.converters.Converter; import com.alibaba.excel.event.SyncReadListener; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelGenerateException; -import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.read.metadata.ReadSheet; /** @@ -16,7 +13,7 @@ import com.alibaba.excel.read.metadata.ReadSheet; * * @author Jiaju Zhuang */ -public class ExcelReaderSheetBuilder { +public class ExcelReaderSheetBuilder extends AbstractExcelReaderParameterBuilder { private ExcelReader excelReader; /** * Sheet @@ -54,98 +51,6 @@ public class ExcelReaderSheetBuilder { return this; } - /** - * Count the number of added heads when read sheet. - * - *

- * 0 - This Sheet has no head ,since the first row are the data - *

- * 1 - This Sheet has one row head , this is the default - *

- * 2 - This Sheet has two row head ,since the third row is the data - * - * @param headRowNumber - * @return - */ - public ExcelReaderSheetBuilder headRowNumber(Integer headRowNumber) { - readSheet.setHeadRowNumber(headRowNumber); - return this; - } - - /** - * You can only choose one of the {@link ExcelReaderBuilder#head(List)} and {@link ExcelReaderBuilder#head(Class)} - * - * @param head - * @return - */ - public ExcelReaderSheetBuilder head(List> head) { - readSheet.setHead(head); - return this; - } - - /** - * You can only choose one of the {@link ExcelReaderBuilder#head(List)} and {@link ExcelReaderBuilder#head(Class)} - * - * @param clazz - * @return - */ - public ExcelReaderSheetBuilder head(Class clazz) { - readSheet.setClazz(clazz); - return this; - } - - /** - * Custom type conversions override the default. - * - * @param converter - * @return - */ - public ExcelReaderSheetBuilder registerConverter(Converter converter) { - if (readSheet.getCustomConverterList() == null) { - readSheet.setCustomConverterList(new ArrayList()); - } - readSheet.getCustomConverterList().add(converter); - return this; - } - - /** - * Custom type listener run after default - * - * @param readListener - * @return - */ - public ExcelReaderSheetBuilder registerReadListener(ReadListener readListener) { - if (readSheet.getCustomReadListenerList() == null) { - readSheet.setCustomReadListenerList(new ArrayList()); - } - readSheet.getCustomReadListenerList().add(readListener); - return this; - } - - /** - * true if date uses 1904 windowing, or false if using 1900 date windowing. - * - * default is false - * - * @param use1904windowing - * @return - */ - public ExcelReaderSheetBuilder use1904windowing(Boolean use1904windowing) { - readSheet.setUse1904windowing(use1904windowing); - return this; - } - - /** - * Automatic trim includes sheet name and content - * - * @param autoTrim - * @return - */ - public ExcelReaderSheetBuilder autoTrim(Boolean autoTrim) { - readSheet.setAutoTrim(autoTrim); - return this; - } - public ReadSheet build() { return readSheet; } @@ -177,4 +82,8 @@ public class ExcelReaderSheetBuilder { return (List)syncReadListener.getList(); } + @Override + protected ReadSheet parameter() { + return readSheet; + } } diff --git a/src/main/java/com/alibaba/excel/util/DateUtils.java b/src/main/java/com/alibaba/excel/util/DateUtils.java index b375733a..815257b9 100644 --- a/src/main/java/com/alibaba/excel/util/DateUtils.java +++ b/src/main/java/com/alibaba/excel/util/DateUtils.java @@ -13,7 +13,7 @@ import java.util.regex.Pattern; * * @author Jiaju Zhuang **/ -public class DateUtils implements ThreadLocalCachedUtils { +public class DateUtils { /** * Is a cache of dates */ @@ -302,8 +302,7 @@ public class DateUtils implements ThreadLocalCachedUtils { return false; } - @Override - public void removeThreadLocalCache() { + public static void removeThreadLocalCache() { DATE_THREAD_LOCAL.remove(); DATE_FORMAT_THREAD_LOCAL.remove(); } diff --git a/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java b/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java index 52ced2ac..5bceb4a1 100644 --- a/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java +++ b/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java @@ -8,7 +8,7 @@ import com.alibaba.excel.metadata.GlobalConfiguration; * * @author Jiaju Zhuang **/ -public class NumberDataFormatterUtils implements ThreadLocalCachedUtils { +public class NumberDataFormatterUtils { /** * Cache DataFormatter. */ @@ -40,8 +40,7 @@ public class NumberDataFormatterUtils implements ThreadLocalCachedUtils { } - @Override - public void removeThreadLocalCache() { + public static void removeThreadLocalCache() { DATA_FORMATTER_THREAD_LOCAL.remove(); } } diff --git a/src/main/java/com/alibaba/excel/util/ThreadLocalCachedUtils.java b/src/main/java/com/alibaba/excel/util/ThreadLocalCachedUtils.java deleted file mode 100644 index d1367038..00000000 --- a/src/main/java/com/alibaba/excel/util/ThreadLocalCachedUtils.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.alibaba.excel.util; - -/** - * Thread local cache in the current tool class. - * - * @author Jiaju Zhuang - **/ -public interface ThreadLocalCachedUtils { - - /** - * Remove remove thread local cached. - */ - void removeThreadLocalCache(); -} diff --git a/src/main/java/com/alibaba/excel/write/builder/AbstractExcelWriterParameterBuilder.java b/src/main/java/com/alibaba/excel/write/builder/AbstractExcelWriterParameterBuilder.java new file mode 100644 index 00000000..d44c0ad0 --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/builder/AbstractExcelWriterParameterBuilder.java @@ -0,0 +1,104 @@ +package com.alibaba.excel.write.builder; + +import java.util.ArrayList; +import java.util.Collection; + +import com.alibaba.excel.metadata.AbstractParameterBuilder; +import com.alibaba.excel.write.handler.WriteHandler; +import com.alibaba.excel.write.metadata.WriteBasicParameter; + +/** + * Build ExcelBuilder + * + * @author Jiaju Zhuang + */ +public abstract class AbstractExcelWriterParameterBuilder extends AbstractParameterBuilder { + /** + * Writes the head relative to the existing contents of the sheet. Indexes are zero-based. + * + * @param relativeHeadRowIndex + * @return + */ + public T relativeHeadRowIndex(Integer relativeHeadRowIndex) { + parameter().setRelativeHeadRowIndex(relativeHeadRowIndex); + return self(); + } + + /** + * Need Head + */ + public T needHead(Boolean needHead) { + parameter().setNeedHead(needHead); + return self(); + } + + /** + * Custom write handler + * + * @param writeHandler + * @return + */ + public T registerWriteHandler(WriteHandler writeHandler) { + if (parameter().getCustomWriteHandlerList() == null) { + parameter().setCustomWriteHandlerList(new ArrayList()); + } + parameter().getCustomWriteHandlerList().add(writeHandler); + return self(); + } + + /** + * Use the default style.Default is true. + * + * @param useDefaultStyle + * @return + */ + public T useDefaultStyle(Boolean useDefaultStyle) { + parameter().setUseDefaultStyle(useDefaultStyle); + return self(); + } + + /** + * Whether to automatically merge headers.Default is true. + * + * @param automaticMergeHead + * @return + */ + public T automaticMergeHead(Boolean automaticMergeHead) { + parameter().setAutomaticMergeHead(automaticMergeHead); + return self(); + } + + /** + * Ignore the custom columns. + */ + public T excludeColumnIndexes(Collection excludeColumnIndexes) { + parameter().setExcludeColumnIndexes(excludeColumnIndexes); + return self(); + } + + /** + * Ignore the custom columns. + */ + public T excludeColumnFiledNames(Collection excludeColumnFiledNames) { + parameter().setExcludeColumnFiledNames(excludeColumnFiledNames); + return self(); + } + + /** + * Only output the custom columns. + */ + public T includeColumnIndexes(Collection includeColumnIndexes) { + parameter().setIncludeColumnIndexes(includeColumnIndexes); + return self(); + } + + /** + * Only output the custom columns. + */ + public T includeColumnFiledNames(Collection includeColumnFiledNames) { + parameter().setIncludeColumnFiledNames(includeColumnFiledNames); + return self(); + } + +} diff --git a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java index c1f2d949..12c2f22f 100644 --- a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java +++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java @@ -3,12 +3,8 @@ package com.alibaba.excel.write.builder; import java.io.File; import java.io.InputStream; import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.converters.Converter; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.metadata.WriteWorkbook; @@ -18,7 +14,7 @@ import com.alibaba.excel.write.metadata.WriteWorkbook; * * @author Jiaju Zhuang */ -public class ExcelWriterBuilder { +public class ExcelWriterBuilder extends AbstractExcelWriterParameterBuilder { /** * Workbook */ @@ -28,47 +24,6 @@ public class ExcelWriterBuilder { this.writeWorkbook = new WriteWorkbook(); } - /** - * Writes the head relative to the existing contents of the sheet. Indexes are zero-based. - * - * @param relativeHeadRowIndex - * @return - */ - public ExcelWriterBuilder relativeHeadRowIndex(Integer relativeHeadRowIndex) { - writeWorkbook.setRelativeHeadRowIndex(relativeHeadRowIndex); - return this; - } - - /** - * You can only choose one of the {@link ExcelWriterBuilder#head(List)} and {@link ExcelWriterBuilder#head(Class)} - * - * @param head - * @return - */ - public ExcelWriterBuilder head(List> head) { - writeWorkbook.setHead(head); - return this; - } - - /** - * You can only choose one of the {@link ExcelWriterBuilder#head(List)} and {@link ExcelWriterBuilder#head(Class)} - * - * @param clazz - * @return - */ - public ExcelWriterBuilder head(Class clazz) { - writeWorkbook.setClazz(clazz); - return this; - } - - /** - * Need Head - */ - public ExcelWriterBuilder needHead(Boolean needHead) { - writeWorkbook.setNeedHead(needHead); - return this; - } - /** * Default true * @@ -80,28 +35,6 @@ public class ExcelWriterBuilder { return this; } - /** - * Use the default style.Default is true. - * - * @param useDefaultStyle - * @return - */ - public ExcelWriterBuilder useDefaultStyle(Boolean useDefaultStyle) { - writeWorkbook.setUseDefaultStyle(useDefaultStyle); - return this; - } - - /** - * Whether to automatically merge headers.Default is true. - * - * @param automaticMergeHead - * @return - */ - public ExcelWriterBuilder automaticMergeHead(Boolean automaticMergeHead) { - writeWorkbook.setAutomaticMergeHead(automaticMergeHead); - return this; - } - /** * Whether the encryption. *

@@ -125,38 +58,6 @@ public class ExcelWriterBuilder { return this; } - /** - * Ignore the custom columns. - */ - public ExcelWriterBuilder excludeColumnIndexes(Collection excludeColumnIndexes) { - writeWorkbook.setExcludeColumnIndexes(excludeColumnIndexes); - return this; - } - - /** - * Ignore the custom columns. - */ - public ExcelWriterBuilder excludeColumnFiledNames(Collection excludeColumnFiledNames) { - writeWorkbook.setExcludeColumnFiledNames(excludeColumnFiledNames); - return this; - } - - /** - * Only output the custom columns. - */ - public ExcelWriterBuilder includeColumnIndexes(Collection includeColumnIndexes) { - writeWorkbook.setIncludeColumnIndexes(includeColumnIndexes); - return this; - } - - /** - * Only output the custom columns. - */ - public ExcelWriterBuilder includeColumnFiledNames(Collection includeColumnFiledNames) { - writeWorkbook.setIncludeColumnFiledNames(includeColumnFiledNames); - return this; - } - /** * Excel is also written in the event of an exception being thrown.The default false. */ @@ -181,34 +82,6 @@ public class ExcelWriterBuilder { return this; } - /** - * Custom type conversions override the default. - * - * @param converter - * @return - */ - public ExcelWriterBuilder registerConverter(Converter converter) { - if (writeWorkbook.getCustomConverterList() == null) { - writeWorkbook.setCustomConverterList(new ArrayList()); - } - writeWorkbook.getCustomConverterList().add(converter); - return this; - } - - /** - * Custom write handler - * - * @param writeHandler - * @return - */ - public ExcelWriterBuilder registerWriteHandler(WriteHandler writeHandler) { - if (writeWorkbook.getCustomWriteHandlerList() == null) { - writeWorkbook.setCustomWriteHandlerList(new ArrayList()); - } - writeWorkbook.getCustomWriteHandlerList().add(writeHandler); - return this; - } - public ExcelWriterBuilder excelType(ExcelTypeEnum excelType) { writeWorkbook.setExcelType(excelType); return this; @@ -281,4 +154,8 @@ public class ExcelWriterBuilder { return excelWriterSheetBuilder; } + @Override + protected WriteWorkbook parameter() { + return writeWorkbook; + } } diff --git a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java index 5cb71cc9..f79b7710 100644 --- a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java +++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java @@ -1,13 +1,9 @@ package com.alibaba.excel.write.builder; -import java.util.ArrayList; -import java.util.Collection; import java.util.List; import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.converters.Converter; import com.alibaba.excel.exception.ExcelGenerateException; -import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.fill.FillConfig; @@ -16,7 +12,7 @@ import com.alibaba.excel.write.metadata.fill.FillConfig; * * @author Jiaju Zhuang */ -public class ExcelWriterSheetBuilder { +public class ExcelWriterSheetBuilder extends AbstractExcelWriterParameterBuilder { private ExcelWriter excelWriter; /** * Sheet @@ -32,99 +28,6 @@ public class ExcelWriterSheetBuilder { this.excelWriter = excelWriter; } - /** - * Writes the head relative to the existing contents of the sheet. Indexes are zero-based. - * - * @param relativeHeadRowIndex - * @return - */ - public ExcelWriterSheetBuilder relativeHeadRowIndex(Integer relativeHeadRowIndex) { - writeSheet.setRelativeHeadRowIndex(relativeHeadRowIndex); - return this; - } - - /** - * You can only choose one of the {@link ExcelWriterSheetBuilder#head(List)} and - * {@link ExcelWriterSheetBuilder#head(Class)} - * - * @param head - * @return - */ - public ExcelWriterSheetBuilder head(List> head) { - writeSheet.setHead(head); - return this; - } - - /** - * You can only choose one of the {@link ExcelWriterSheetBuilder#head(List)} and - * {@link ExcelWriterSheetBuilder#head(Class)} - * - * @param clazz - * @return - */ - public ExcelWriterSheetBuilder head(Class clazz) { - writeSheet.setClazz(clazz); - return this; - } - - /** - * Need Head - */ - public ExcelWriterSheetBuilder needHead(Boolean needHead) { - writeSheet.setNeedHead(needHead); - return this; - } - - /** - * Use the default style.Default is true. - * - * @param useDefaultStyle - * @return - */ - public ExcelWriterSheetBuilder useDefaultStyle(Boolean useDefaultStyle) { - writeSheet.setUseDefaultStyle(useDefaultStyle); - return this; - } - - /** - * Whether to automatically merge headers.Default is true. - * - * @param automaticMergeHead - * @return - */ - public ExcelWriterSheetBuilder automaticMergeHead(Boolean automaticMergeHead) { - writeSheet.setAutomaticMergeHead(automaticMergeHead); - return this; - } - - /** - * Custom type conversions override the default. - * - * @param converter - * @return - */ - public ExcelWriterSheetBuilder registerConverter(Converter converter) { - if (writeSheet.getCustomConverterList() == null) { - writeSheet.setCustomConverterList(new ArrayList()); - } - writeSheet.getCustomConverterList().add(converter); - return this; - } - - /** - * Custom write handler - * - * @param writeHandler - * @return - */ - public ExcelWriterSheetBuilder registerWriteHandler(WriteHandler writeHandler) { - if (writeSheet.getCustomWriteHandlerList() == null) { - writeSheet.setCustomWriteHandlerList(new ArrayList()); - } - writeSheet.getCustomWriteHandlerList().add(writeHandler); - return this; - } - /** * Starting from 0 * @@ -147,38 +50,6 @@ public class ExcelWriterSheetBuilder { return this; } - /** - * Ignore the custom columns. - */ - public ExcelWriterSheetBuilder excludeColumnIndexes(Collection excludeColumnIndexes) { - writeSheet.setExcludeColumnIndexes(excludeColumnIndexes); - return this; - } - - /** - * Ignore the custom columns. - */ - public ExcelWriterSheetBuilder excludeColumnFiledNames(Collection excludeColumnFiledNames) { - writeSheet.setExcludeColumnFiledNames(excludeColumnFiledNames); - return this; - } - - /** - * Only output the custom columns. - */ - public ExcelWriterSheetBuilder includeColumnIndexes(Collection includeColumnIndexes) { - writeSheet.setIncludeColumnIndexes(includeColumnIndexes); - return this; - } - - /** - * Only output the custom columns. - */ - public ExcelWriterSheetBuilder includeColumnFiledNames(Collection includeColumnFiledNames) { - writeSheet.setIncludeColumnFiledNames(includeColumnFiledNames); - return this; - } - public WriteSheet build() { return writeSheet; } @@ -215,4 +86,9 @@ public class ExcelWriterSheetBuilder { return excelWriterTableBuilder; } + @Override + protected WriteSheet parameter() { + return writeSheet; + } + } diff --git a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterTableBuilder.java b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterTableBuilder.java index 2b461a9d..077361ad 100644 --- a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterTableBuilder.java +++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterTableBuilder.java @@ -1,13 +1,9 @@ package com.alibaba.excel.write.builder; -import java.util.ArrayList; -import java.util.Collection; import java.util.List; import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.converters.Converter; import com.alibaba.excel.exception.ExcelGenerateException; -import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteTable; @@ -16,7 +12,7 @@ import com.alibaba.excel.write.metadata.WriteTable; * * @author Jiaju Zhuang */ -public class ExcelWriterTableBuilder { +public class ExcelWriterTableBuilder extends AbstractExcelWriterParameterBuilder { private ExcelWriter excelWriter; @@ -36,99 +32,6 @@ public class ExcelWriterTableBuilder { this.writeTable = new WriteTable(); } - /** - * Writes the head relative to the existing contents of the sheet. Indexes are zero-based. - * - * @param relativeHeadRowIndex - * @return - */ - public ExcelWriterTableBuilder relativeHeadRowIndex(Integer relativeHeadRowIndex) { - writeTable.setRelativeHeadRowIndex(relativeHeadRowIndex); - return this; - } - - /** - * You can only choose one of the {@link ExcelWriterTableBuilder#head(List)} and - * {@link ExcelWriterTableBuilder#head(Class)} - * - * @param head - * @return - */ - public ExcelWriterTableBuilder head(List> head) { - writeTable.setHead(head); - return this; - } - - /** - * You can only choose one of the {@link ExcelWriterTableBuilder#head(List)} and - * {@link ExcelWriterTableBuilder#head(Class)} - * - * @param clazz - * @return - */ - public ExcelWriterTableBuilder head(Class clazz) { - writeTable.setClazz(clazz); - return this; - } - - /** - * Need Head - */ - public ExcelWriterTableBuilder needHead(Boolean needHead) { - writeTable.setNeedHead(needHead); - return this; - } - - /** - * Use the default style.Default is true. - * - * @param useDefaultStyle - * @return - */ - public ExcelWriterTableBuilder useDefaultStyle(Boolean useDefaultStyle) { - writeTable.setUseDefaultStyle(useDefaultStyle); - return this; - } - - /** - * Whether to automatically merge headers.Default is true. - * - * @param automaticMergeHead - * @return - */ - public ExcelWriterTableBuilder automaticMergeHead(Boolean automaticMergeHead) { - writeTable.setAutomaticMergeHead(automaticMergeHead); - return this; - } - - /** - * Custom type conversions override the default. - * - * @param converter - * @return - */ - public ExcelWriterTableBuilder registerConverter(Converter converter) { - if (writeTable.getCustomConverterList() == null) { - writeTable.setCustomConverterList(new ArrayList()); - } - writeTable.getCustomConverterList().add(converter); - return this; - } - - /** - * Custom write handler - * - * @param writeHandler - * @return - */ - public ExcelWriterTableBuilder registerWriteHandler(WriteHandler writeHandler) { - if (writeTable.getCustomWriteHandlerList() == null) { - writeTable.setCustomWriteHandlerList(new ArrayList()); - } - writeTable.getCustomWriteHandlerList().add(writeHandler); - return this; - } - /** * Starting from 0 * @@ -140,38 +43,6 @@ public class ExcelWriterTableBuilder { return this; } - /** - * Ignore the custom columns. - */ - public ExcelWriterTableBuilder excludeColumnIndexes(Collection excludeColumnIndexes) { - writeTable.setExcludeColumnIndexes(excludeColumnIndexes); - return this; - } - - /** - * Ignore the custom columns. - */ - public ExcelWriterTableBuilder excludeColumnFiledNames(Collection excludeColumnFiledNames) { - writeTable.setExcludeColumnFiledNames(excludeColumnFiledNames); - return this; - } - - /** - * Only output the custom columns. - */ - public ExcelWriterTableBuilder includeColumnIndexes(Collection includeColumnIndexes) { - writeTable.setIncludeColumnIndexes(includeColumnIndexes); - return this; - } - - /** - * Only output the custom columns. - */ - public ExcelWriterTableBuilder includeColumnFiledNames(Collection includeColumnFiledNames) { - writeSheet.setIncludeColumnFiledNames(includeColumnFiledNames); - return this; - } - public WriteTable build() { return writeTable; } @@ -184,4 +55,8 @@ public class ExcelWriterTableBuilder { excelWriter.finish(); } + @Override + protected WriteTable parameter() { + return writeTable; + } } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatData.java b/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatData.java index d627e46c..1930bce5 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatData.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatData.java @@ -8,7 +8,9 @@ import lombok.Data; @Data public class DateFormatData { private String date; - private String dateString; + private String dateStringCn; + private String dateStringUs; private String number; - private String numberString; + private String numberStringCn; + private String numberStringUs; } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatTest.java b/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatTest.java index 69b67098..477652b0 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatTest.java @@ -2,7 +2,9 @@ package com.alibaba.easyexcel.test.core.dataformat; import java.io.File; import java.util.List; +import java.util.Locale; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.slf4j.Logger; @@ -10,7 +12,6 @@ import org.slf4j.LoggerFactory; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson.JSON; /** * @@ -30,21 +31,31 @@ public class DateFormatTest { @Test public void t01Read07() { - read(file07); + readCn(file07); + readUs(file07); } @Test public void t02Read03() { - read(file03); + readCn(file03); + readUs(file03); } - private void read(File file) { - List list = EasyExcel.read(file, DateFormatData.class, null).sheet().doReadSync(); + private void readCn(File file) { + List list = + EasyExcel.read(file, DateFormatData.class, null).locale(Locale.CHINA).sheet().doReadSync(); for (DateFormatData data : list) { - if (!data.getDate().equals(data.getDateString())) { - LOGGER.info("返回:{}", JSON.toJSONString(data)); - } + Assert.assertEquals(data.getDate(), data.getDateStringCn()); + Assert.assertEquals(data.getNumber(), data.getNumberStringCn()); } } + private void readUs(File file) { + List list = + EasyExcel.read(file, DateFormatData.class, null).locale(Locale.US).sheet().doReadSync(); + for (DateFormatData data : list) { + Assert.assertEquals(data.getDate(), data.getDateStringUs()); + Assert.assertEquals(data.getNumber(), data.getNumberStringUs()); + } + } } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java index d3db5e06..e165d987 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java @@ -146,7 +146,7 @@ public class DataFormatTest { @Test public void test3556() throws IOException, InvalidFormatException { - String file = "D://test/dataformat.xlsx"; + String file = "D://test/dataformat1.xlsx"; XSSFWorkbook xssfWorkbook = new XSSFWorkbook(file); Sheet xssfSheet = xssfWorkbook.getSheetAt(0); DataFormatter d = new DataFormatter(Locale.CHINA); diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java index 68fff703..fa417049 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java @@ -2,6 +2,7 @@ package com.alibaba.easyexcel.test.temp.poi; import java.io.FileOutputStream; import java.io.IOException; +import java.math.BigDecimal; import java.util.regex.Pattern; import org.apache.poi.xssf.streaming.SXSSFCell; @@ -35,9 +36,20 @@ public class PoiWriteTest { cell1.setCellValue(999999999999999L); SXSSFCell cell2 = row.createCell(1); cell2.setCellValue(1000000000000001L); + SXSSFCell cell32 = row.createCell(2); + cell32.setCellValue(300.35f); sxxsFWorkbook.write(fileOutputStream); } + @Test + public void write01() throws IOException { + float ff = 300.35f; + BigDecimal bd = new BigDecimal(Float.toString(ff)); + System.out.println(bd.doubleValue()); + System.out.println(bd.floatValue()); + + } + @Test public void write() throws IOException { FileOutputStream fileOutputStream = diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/simple/JsonData.java b/src/test/java/com/alibaba/easyexcel/test/temp/simple/JsonData.java new file mode 100644 index 00000000..a9ba7fa4 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/simple/JsonData.java @@ -0,0 +1,15 @@ +package com.alibaba.easyexcel.test.temp.simple; + +import lombok.Data; + +/** + * TODO + * + * @author Jiaju Zhuang + **/ +@Data +public class JsonData { + private String SS1; + private String sS2; + private String ss3; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java b/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java index 44bc943f..61571812 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java @@ -14,6 +14,7 @@ import com.alibaba.easyexcel.test.core.large.LargeData; import com.alibaba.easyexcel.test.demo.write.DemoData; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.fastjson.JSON; import net.sf.cglib.beans.BeanMap; @@ -43,7 +44,35 @@ public class Wirte { String fileName = TestFileUtil.getPath() + "t22" + System.currentTimeMillis() + ".xlsx"; // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 // 如果这里想使用03 则 传入excelType参数即可 - EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data()); + EasyExcel.write(fileName, DemoData.class).relativeHeadRowIndex(10).sheet("模板").doWrite(data()); + } + + @Test + public void simpleWrite2() { + // 写法1 + String fileName = TestFileUtil.getPath() + "t22" + System.currentTimeMillis() + ".xlsx"; + // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + // 如果这里想使用03 则 传入excelType参数即可 + EasyExcel.write(fileName, WriteData.class).sheet("模板").doWrite(data1()); + } + + @Test + public void json() { + JsonData jsonData = new JsonData(); + jsonData.setSS1("11"); + jsonData.setSS2("22"); + jsonData.setSs3("33"); + System.out.println(JSON.toJSONString(jsonData)); + + } + + @Test + public void json3() { + String json = "{\"SS1\":\"11\",\"sS2\":\"22\",\"ss3\":\"33\"}"; + + JsonData jsonData = JSON.parseObject(json, JsonData.class); + System.out.println(JSON.toJSONString(jsonData)); + } private List> head() { @@ -72,4 +101,14 @@ public class Wirte { return list; } + private List data1() { + List list = new ArrayList(); + for (int i = 0; i < 10; i++) { + WriteData data = new WriteData(); + data.setF(300.35f); + list.add(data); + } + return list; + } + } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteData.java b/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteData.java new file mode 100644 index 00000000..b8ff14d6 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteData.java @@ -0,0 +1,13 @@ +package com.alibaba.easyexcel.test.temp.simple; + +import lombok.Data; + +/** + * write data + * + * @author Jiaju Zhuang + **/ +@Data +public class WriteData { + private float f; +} diff --git a/src/test/resources/dataformat/dataformat.xls b/src/test/resources/dataformat/dataformat.xls new file mode 100644 index 0000000000000000000000000000000000000000..c03847e4e5cde9f156ddf23b5d8263dc1357453e GIT binary patch literal 26112 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 Hx%~eDWlI1` literal 0 HcmV?d00001 diff --git a/src/test/resources/dataformat/dataformat.xlsx b/src/test/resources/dataformat/dataformat.xlsx index 370d983a931862faf90274a954ed71e38cb92ac5..0085930c31d5b3a08eb63f6f868089eb89c6a29d 100644 GIT binary patch delta 7423 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 R|C%Wne@zx7DdvCB{{byD`cD7= delta 7099 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 3.4.0(jdk6) +* 修复xls 用Map接收时多次接收会是同一个对象的bug +* 修复浮点型数据导入到excel 会丢失精度的bug + # 2.1.3 * 每个java进程单独创建一个缓存目录 [Issue #813](https://github.com/alibaba/easyexcel/issues/813) * 统一修改合并为unsafe,提高大量数据导出的合并的效率