diff --git a/README.md b/README.md index 2f1a12fe..89bae018 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ EasyExcel [![Maven central](https://maven-badges.herokuapp.com/maven-central/com.alibaba/easyexcel/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.alibaba/easyexcel) [![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) -[QQ群: 662022184](//shang.qq.com/wpa/qunwpa?idkey=53d9d821b0833e3c14670f007488a61e300f00ff4f1b81fd950590d90dd80f80) +[QQ1群(已满): 662022184](https://jq.qq.com/?_wv=1027&k=1T21jJxh) +[QQ2群: 1097936804](https://jq.qq.com/?_wv=1027&k=j5zEy6Xl) [钉钉1群(已满): 21960511](https://qr.dingtalk.com/action/joingroup?code=v1,k1,cchz6k12ci9B08NNqhNRFGXocNVHrZtW0kaOtTKg/Rk=&_dt_no_comment=1&origin=11) [钉钉2群: 32796397](https://qr.dingtalk.com/action/joingroup?code=v1,k1,jyU9GtEuNU5S0QTyklqYcYJ8qDZtUuTPMM7uPZTS8Hs=&_dt_no_comment=1&origin=11) diff --git a/pom.xml b/pom.xml index 783f1207..be70e6bf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.alibaba easyexcel - 2.2.3 + 2.2.4 jar easyexcel @@ -97,7 +97,7 @@ com.alibaba fastjson - 1.2.58 + 1.2.68 test @@ -162,6 +162,8 @@ com/alibaba/excel/event/AnalysisEventListener.java com/alibaba/excel/metadata/DataFormatter.java com/alibaba/excel/util/DateUtils.java + com/alibaba/excel/metadata/format/DataFormatter.java + com/alibaba/excel/metadata/format/ExcelGeneralNumberFormat.java 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 bda4f53d..e1c19be6 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java @@ -147,7 +147,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor { return; } boolean ignoreRecord = (handler instanceof IgnorableXlsRecordHandler) - && xlsReadContext.xlsReadSheetHolder() != null && xlsReadContext.xlsReadSheetHolder().getIgnoreRecord(); + && xlsReadContext.xlsReadSheetHolder() != null && xlsReadContext.xlsReadWorkbookHolder().getIgnoreRecord(); if (ignoreRecord) { // No need to read the current sheet return; diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java index 66e3ab76..3e6713c4 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java @@ -22,10 +22,11 @@ public class BofRecordHandler extends AbstractXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { - BOFRecord br = (BOFRecord)record; + BOFRecord br = (BOFRecord) record; XlsReadWorkbookHolder xlsReadWorkbookHolder = xlsReadContext.xlsReadWorkbookHolder(); if (br.getType() == BOFRecord.TYPE_WORKBOOK) { xlsReadWorkbookHolder.setReadSheetIndex(null); + xlsReadWorkbookHolder.setIgnoreRecord(Boolean.FALSE); return; } if (br.getType() != BOFRecord.TYPE_WORKSHEET) { @@ -38,15 +39,15 @@ public class BofRecordHandler extends AbstractXlsRecordHandler { readSheetIndex = 0; xlsReadWorkbookHolder.setReadSheetIndex(readSheetIndex); } - ReadSheet readSheet = xlsReadWorkbookHolder.getActualSheetDataList().get(readSheetIndex); - assert readSheet != null : "Can't find the sheet."; + ReadSheet actualReadSheet = xlsReadWorkbookHolder.getActualSheetDataList().get(readSheetIndex); + assert actualReadSheet != null : "Can't find the sheet."; // Copy the parameter to the current sheet - readSheet = SheetUtils.match(readSheet, xlsReadContext); + ReadSheet readSheet = SheetUtils.match(actualReadSheet, xlsReadContext); if (readSheet != null) { xlsReadContext.currentSheet(readSheet); - xlsReadContext.xlsReadSheetHolder().setIgnoreRecord(Boolean.FALSE); + xlsReadContext.xlsReadWorkbookHolder().setIgnoreRecord(Boolean.FALSE); } else { - xlsReadContext.xlsReadSheetHolder().setIgnoreRecord(Boolean.TRUE); + xlsReadContext.xlsReadWorkbookHolder().setIgnoreRecord(Boolean.TRUE); } // Go read the next one xlsReadWorkbookHolder.setReadSheetIndex(xlsReadWorkbookHolder.getReadSheetIndex() + 1); diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java index 099b3087..f78d4102 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java @@ -3,6 +3,7 @@ package com.alibaba.excel.analysis.v03.handlers; import java.math.BigDecimal; import java.util.Map; +import com.alibaba.excel.enums.RowTypeEnum; import org.apache.poi.hssf.model.HSSFFormulaParser; import org.apache.poi.hssf.record.FormulaRecord; import org.apache.poi.hssf.record.Record; @@ -14,6 +15,7 @@ import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.constant.BuiltinFormats; import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.metadata.Cell; import com.alibaba.excel.metadata.CellData; @@ -43,6 +45,7 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler implements Ig } tempCellData.setFormula(Boolean.TRUE); tempCellData.setFormulaValue(formulaValue); + xlsReadContext.xlsReadSheetHolder().setTempRowType(RowTypeEnum.DATA); switch (cellType) { case STRING: // Formula result is a string diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java index 329b2245..877c6a5f 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java @@ -10,6 +10,7 @@ import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.metadata.Cell; import com.alibaba.excel.read.metadata.holder.ReadRowHolder; import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder; +import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.PositionUtils; /** @@ -39,7 +40,9 @@ public class RowTagHandler extends AbstractXlsxTagHandler { @Override public void endElement(XlsxReadContext xlsxReadContext, String name) { XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder(); - xlsxReadContext.readRowHolder(new ReadRowHolder(xlsxReadSheetHolder.getRowIndex(), RowTypeEnum.DATA, + RowTypeEnum rowType = + CollectionUtils.isEmpty(xlsxReadSheetHolder.getCellMap()) ? RowTypeEnum.EMPTY : RowTypeEnum.DATA; + xlsxReadContext.readRowHolder(new ReadRowHolder(xlsxReadSheetHolder.getRowIndex(), rowType, xlsxReadSheetHolder.getGlobalConfiguration(), xlsxReadSheetHolder.getCellMap())); xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext); xlsxReadSheetHolder.setColumnIndex(null); diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index 0af631ca..c1f89f02 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java @@ -112,7 +112,6 @@ public class WriteContextImpl implements WriteContext { return; } - initCurrentSheetHolder(writeSheet); // Workbook handler need to supplementary execution @@ -125,8 +124,12 @@ public class WriteContextImpl implements WriteContext { private boolean selectSheetFromCache(WriteSheet writeSheet) { writeSheetHolder = null; - if (writeSheet.getSheetNo() != null) { - writeSheetHolder = writeWorkbookHolder.getHasBeenInitializedSheetIndexMap().get(writeSheet.getSheetNo()); + Integer sheetNo = writeSheet.getSheetNo(); + if (sheetNo == null && StringUtils.isEmpty(writeSheet.getSheetName())) { + sheetNo = 0; + } + if (sheetNo != null) { + writeSheetHolder = writeWorkbookHolder.getHasBeenInitializedSheetIndexMap().get(sheetNo); } if (writeSheetHolder == null && !StringUtils.isEmpty(writeSheet.getSheetName())) { writeSheetHolder = writeWorkbookHolder.getHasBeenInitializedSheetNameMap().get(writeSheet.getSheetName()); @@ -160,9 +163,15 @@ public class WriteContextImpl implements WriteContext { Sheet currentSheet; try { if (writeSheetHolder.getSheetNo() != null) { - currentSheet = writeWorkbookHolder.getWorkbook().getSheetAt(writeSheetHolder.getSheetNo()); - writeSheetHolder - .setCachedSheet(writeWorkbookHolder.getCachedWorkbook().getSheetAt(writeSheetHolder.getSheetNo())); + // When the add default sort order of appearance + if (WriteTypeEnum.ADD.equals(writeType) && writeWorkbookHolder.getTempTemplateInputStream() == null) { + currentSheet = createSheet(); + } else { + currentSheet = writeWorkbookHolder.getWorkbook().getSheetAt(writeSheetHolder.getSheetNo()); + writeSheetHolder + .setCachedSheet( + writeWorkbookHolder.getCachedWorkbook().getSheetAt(writeSheetHolder.getSheetNo())); + } } else { // sheet name must not null currentSheet = writeWorkbookHolder.getWorkbook().getSheet(writeSheetHolder.getSheetName()); 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/metadata/property/ExcelHeadProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java index 34109adc..5a035772 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java @@ -73,7 +73,7 @@ public class ExcelHeadProperty { int headIndex = 0; for (int i = 0; i < head.size(); i++) { if (holder instanceof AbstractWriteHolder) { - if (((AbstractWriteHolder)holder).ignore(null, i)) { + if (((AbstractWriteHolder) holder).ignore(null, i)) { continue; } } @@ -130,9 +130,8 @@ public class ExcelHeadProperty { index++; } } - if (!initOneColumnProperty(holder, index, field, Boolean.FALSE)) { - index++; - } + initOneColumnProperty(holder, index, field, Boolean.FALSE); + index++; } for (Map.Entry entry : customFiledMap.entrySet()) { initOneColumnProperty(holder, entry.getKey(), entry.getValue(), Boolean.TRUE); @@ -151,7 +150,7 @@ public class ExcelHeadProperty { */ private boolean initOneColumnProperty(Holder holder, int index, Field field, Boolean forceIndex) { if (holder instanceof AbstractWriteHolder) { - if (((AbstractWriteHolder)holder).ignore(field.getName(), index)) { + if (((AbstractWriteHolder) holder).ignore(field.getName(), index)) { return true; } } 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 AbstractExcelReaderParameterBuilderReadRowHolder. */ private RowTypeEnum tempRowType; - /** - * Ignore record. - */ - private Boolean ignoreRecord; /** * Temp object index. */ @@ -33,7 +29,6 @@ public class XlsReadSheetHolder extends ReadSheetHolder { public XlsReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) { super(readSheet, readWorkbookHolder); - ignoreRecord = Boolean.FALSE; tempRowType = RowTypeEnum.EMPTY; objectCacheMap = new HashMap(16); } @@ -46,13 +41,6 @@ public class XlsReadSheetHolder extends ReadSheetHolder { this.tempRowType = tempRowType; } - public Boolean getIgnoreRecord() { - return ignoreRecord; - } - - public void setIgnoreRecord(Boolean ignoreRecord) { - this.ignoreRecord = ignoreRecord; - } public Integer getTempObjectIndex() { return tempObjectIndex; diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java index 70c1c03a..a8c86a75 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java @@ -42,6 +42,10 @@ public class XlsReadWorkbookHolder extends ReadWorkbookHolder { * Sheet Index */ private Integer readSheetIndex; + /** + * Ignore record. + */ + private Boolean ignoreRecord; public XlsReadWorkbookHolder(ReadWorkbook readWorkbook) { super(readWorkbook); @@ -51,6 +55,7 @@ public class XlsReadWorkbookHolder extends ReadWorkbookHolder { if (getGlobalConfiguration().getUse1904windowing() == null) { getGlobalConfiguration().setUse1904windowing(Boolean.FALSE); } + ignoreRecord = Boolean.FALSE; } public POIFSFileSystem getPoifsFileSystem() { @@ -100,4 +105,12 @@ public class XlsReadWorkbookHolder extends ReadWorkbookHolder { public void setReadSheetIndex(Integer readSheetIndex) { this.readSheetIndex = readSheetIndex; } + + public Boolean getIgnoreRecord() { + return ignoreRecord; + } + + public void setIgnoreRecord(Boolean ignoreRecord) { + this.ignoreRecord = ignoreRecord; + } } diff --git a/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java b/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java index 5bceb4a1..09d149b6 100644 --- a/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java +++ b/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java @@ -1,6 +1,6 @@ package com.alibaba.excel.util; -import com.alibaba.excel.metadata.DataFormatter; +import com.alibaba.excel.metadata.format.DataFormatter; import com.alibaba.excel.metadata.GlobalConfiguration; /** @@ -9,6 +9,7 @@ import com.alibaba.excel.metadata.GlobalConfiguration; * @author Jiaju Zhuang **/ public class NumberDataFormatterUtils { + /** * Cache DataFormatter. */ @@ -18,8 +19,7 @@ public class NumberDataFormatterUtils { * Format number data. * * @param data - * @param dataFormat - * Not null. + * @param dataFormat Not null. * @param dataFormatString * @param globalConfiguration * @return @@ -28,12 +28,7 @@ public class NumberDataFormatterUtils { GlobalConfiguration globalConfiguration) { DataFormatter dataFormatter = DATA_FORMATTER_THREAD_LOCAL.get(); if (dataFormatter == null) { - if (globalConfiguration != null) { - dataFormatter = - new DataFormatter(globalConfiguration.getLocale(), globalConfiguration.getUse1904windowing()); - } else { - dataFormatter = new DataFormatter(); - } + dataFormatter = new DataFormatter(globalConfiguration); DATA_FORMATTER_THREAD_LOCAL.set(dataFormatter); } return dataFormatter.format(data, dataFormat, dataFormatString); diff --git a/src/main/java/com/alibaba/excel/util/NumberUtils.java b/src/main/java/com/alibaba/excel/util/NumberUtils.java index e687fbfc..4257ff44 100644 --- a/src/main/java/com/alibaba/excel/util/NumberUtils.java +++ b/src/main/java/com/alibaba/excel/util/NumberUtils.java @@ -167,6 +167,7 @@ public class NumberUtils { RoundingMode roundingMode = contentProperty.getNumberFormatProperty().getRoundingMode(); DecimalFormat decimalFormat = new DecimalFormat(format); decimalFormat.setRoundingMode(roundingMode); + decimalFormat.setParseBigDecimal(true); return decimalFormat.parse(string); } } diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java index d25ee941..728703ef 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java @@ -156,6 +156,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName) || ignoreMap.containsKey(filedName) || writeContext.currentWriteHolder().ignore(filedName, cellIndex); if (uselessData) { + cellIndex++; continue; } Object value = beanMap.get(filedName); diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java index 1a42fde1..29a037a6 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java @@ -295,28 +295,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { default: throw new ExcelGenerateException("The wrong direction."); } - Row row = sheet.getRow(lastRowIndex); - if (row == null) { - row = cachedSheet.getRow(lastRowIndex); - if (row == null) { - WriteHandlerUtils.beforeRowCreate(writeContext, lastRowIndex, null, Boolean.FALSE); - if (fillConfig.getForceNewRow()) { - row = cachedSheet.createRow(lastRowIndex); - } else { - row = sheet.createRow(lastRowIndex); - } - checkRowHeight(analysisCell, fillConfig, isOriginalCell, row); - WriteHandlerUtils.afterRowCreate(writeContext, row, null, Boolean.FALSE); - } else { - checkRowHeight(analysisCell, fillConfig, isOriginalCell, row); - } - } - Cell cell = row.getCell(lastColumnIndex); - if (cell == null) { - WriteHandlerUtils.beforeCellCreate(writeContext, row, null, lastColumnIndex, null, Boolean.FALSE); - cell = row.createCell(lastColumnIndex); - WriteHandlerUtils.afterCellCreate(writeContext, cell, null, null, Boolean.FALSE); - } + + Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell); + Cell cell = createCellIfNecessary(row,lastColumnIndex); Map collectionFieldStyleMap = collectionFieldStyleCache.get(currentUniqueDataFlag); if (collectionFieldStyleMap == null) { @@ -334,6 +315,45 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { return cell; } + private Cell createCellIfNecessary(Row row, Integer lastColumnIndex) { + Cell cell = row.getCell(lastColumnIndex); + if (cell != null) { + return cell; + } + WriteHandlerUtils.beforeCellCreate(writeContext, row, null, lastColumnIndex, null, Boolean.FALSE); + cell = row.createCell(lastColumnIndex); + WriteHandlerUtils.afterCellCreate(writeContext, cell, null, null, Boolean.FALSE); + return cell; + } + + private Row createRowIfNecessary(Sheet sheet, Sheet cachedSheet, Integer lastRowIndex, FillConfig fillConfig, + AnalysisCell analysisCell, boolean isOriginalCell) { + Row row = sheet.getRow(lastRowIndex); + if (row != null) { + return row; + } + row = cachedSheet.getRow(lastRowIndex); + if (row == null) { + WriteHandlerUtils.beforeRowCreate(writeContext, lastRowIndex, null, Boolean.FALSE); + if (fillConfig.getForceNewRow()) { + row = cachedSheet.createRow(lastRowIndex); + } else { + // The last row of the middle disk inside empty rows, resulting in cachedSheet can not get inside. + // Will throw Attempting to write a row[" + rownum + "] " + "in the range [0," + this._sh.getLastRowNum() + "] that is already written to disk. + try { + row = sheet.createRow(lastRowIndex); + } catch (IllegalArgumentException ignore) { + row = cachedSheet.createRow(lastRowIndex); + } + } + checkRowHeight(analysisCell, fillConfig, isOriginalCell, row); + WriteHandlerUtils.afterRowCreate(writeContext, row, null, Boolean.FALSE); + } else { + checkRowHeight(analysisCell, fillConfig, isOriginalCell, row); + } + return row; + } + private void checkRowHeight(AnalysisCell analysisCell, FillConfig fillConfig, boolean isOriginalCell, Row row) { if (!analysisCell.getFirstRow() || !WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection())) { return; diff --git a/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java b/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java new file mode 100644 index 00000000..2a2b7b6d --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java @@ -0,0 +1,56 @@ +package com.alibaba.excel.write.merge; + +import java.util.List; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; + +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; + +/** + * Merge strategy + * + * @author Jiaju Zhuang + */ +public abstract class AbstractMergeStrategy implements CellWriteHandler { + @Override + public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, + Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, + Head head, Integer relativeRowIndex, Boolean isHead) {} + + @Override + public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, + WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, + Boolean isHead) { + + } + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, + List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + if (isHead) { + return; + } + merge(writeSheetHolder.getSheet(), cell, head, relativeRowIndex); + } + + /** + * merge + * + * @param sheet + * @param cell + * @param head + * @param relativeRowIndex + */ + protected abstract void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex); +} diff --git a/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java index 77d5d06a..0fced0b5 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java +++ b/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java @@ -111,6 +111,10 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ getGlobalConfiguration().setUse1904windowing(writeBasicParameter.getUse1904windowing()); } + if (writeBasicParameter.getUseScientificFormat() != null) { + throw new UnsupportedOperationException("Currently does not support setting useScientificFormat."); + } + if (writeBasicParameter.getNeedHead() == null) { if (parentAbstractWriteHolder == null) { this.needHead = Boolean.TRUE; diff --git a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java index be557ebd..8c84f1dc 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java @@ -112,6 +112,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { */ private Boolean writeExcelOnException; + public WriteWorkbookHolder(WriteWorkbook writeWorkbook) { super(writeWorkbook, null, writeWorkbook.getConvertAllFiled()); this.writeWorkbook = writeWorkbook; diff --git a/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java b/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java index 8fe03497..979a7750 100644 --- a/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java +++ b/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java @@ -39,6 +39,7 @@ import com.alibaba.excel.metadata.property.StyleProperty; * @author jipengfei */ public class ExcelWriteHeadProperty extends ExcelHeadProperty { + private RowHeightProperty headRowHeightProperty; private RowHeightProperty contentRowHeightProperty; private OnceAbsoluteMergeProperty onceAbsoluteMergeProperty; @@ -49,21 +50,25 @@ public class ExcelWriteHeadProperty extends ExcelHeadProperty { return; } this.headRowHeightProperty = - RowHeightProperty.build((HeadRowHeight)headClazz.getAnnotation(HeadRowHeight.class)); + RowHeightProperty.build((HeadRowHeight) headClazz.getAnnotation(HeadRowHeight.class)); this.contentRowHeightProperty = - RowHeightProperty.build((ContentRowHeight)headClazz.getAnnotation(ContentRowHeight.class)); + RowHeightProperty.build((ContentRowHeight) headClazz.getAnnotation(ContentRowHeight.class)); this.onceAbsoluteMergeProperty = - OnceAbsoluteMergeProperty.build((OnceAbsoluteMerge)headClazz.getAnnotation(OnceAbsoluteMerge.class)); + OnceAbsoluteMergeProperty.build((OnceAbsoluteMerge) headClazz.getAnnotation(OnceAbsoluteMerge.class)); - ColumnWidth parentColumnWidth = (ColumnWidth)headClazz.getAnnotation(ColumnWidth.class); - HeadStyle parentHeadStyle = (HeadStyle)headClazz.getAnnotation(HeadStyle.class); - HeadFontStyle parentHeadFontStyle = (HeadFontStyle)headClazz.getAnnotation(HeadFontStyle.class); - ContentStyle parentContentStyle = (ContentStyle)headClazz.getAnnotation(ContentStyle.class); - ContentFontStyle parentContentFontStyle = (ContentFontStyle)headClazz.getAnnotation(ContentFontStyle.class); + ColumnWidth parentColumnWidth = (ColumnWidth) headClazz.getAnnotation(ColumnWidth.class); + HeadStyle parentHeadStyle = (HeadStyle) headClazz.getAnnotation(HeadStyle.class); + HeadFontStyle parentHeadFontStyle = (HeadFontStyle) headClazz.getAnnotation(HeadFontStyle.class); + ContentStyle parentContentStyle = (ContentStyle) headClazz.getAnnotation(ContentStyle.class); + ContentFontStyle parentContentFontStyle = (ContentFontStyle) headClazz.getAnnotation(ContentFontStyle.class); for (Map.Entry entry : getContentPropertyMap().entrySet()) { Integer index = entry.getKey(); ExcelContentProperty excelContentPropertyData = entry.getValue(); + if (excelContentPropertyData == null) { + throw new IllegalArgumentException( + "Passing in the class and list the head, the two must be the same size."); + } Field field = excelContentPropertyData.getField(); Head headData = getHeadMap().get(index); ColumnWidth columnWidth = field.getAnnotation(ColumnWidth.class); @@ -176,7 +181,8 @@ public class ExcelWriteHeadProperty extends ExcelHeadProperty { if (j == lastRow && i == lastCol) { continue; } - cellRangeList.add(new CellRange(j, lastRow, i, lastCol)); + cellRangeList + .add(new CellRange(j, lastRow, head.getColumnIndex(), headList.get(lastCol).getColumnIndex())); } } return cellRangeList; diff --git a/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java index 06a596f1..14ad9ce5 100644 --- a/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java @@ -22,6 +22,7 @@ import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; * @author Jiaju Zhuang */ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, WorkbookWriteHandler, NotRepeatExecutor { + boolean hasInitialized = false; @Override @@ -50,7 +51,7 @@ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, Wor @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { - if (isHead == null || head == null) { + if (isHead == null) { return; } if (isHead) { diff --git a/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java index 09903a00..197c5cf8 100644 --- a/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java @@ -12,7 +12,6 @@ import com.alibaba.excel.util.StyleUtil; import com.alibaba.excel.write.metadata.style.WriteCellStyle; /** - * * Use the same style for the column * * @author Jiaju Zhuang @@ -30,6 +29,9 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl @Override protected void setHeadCellStyle(Cell cell, Head head, Integer relativeRowIndex) { + if (head == null) { + return; + } int columnIndex = head.getColumnIndex(); if (headCellStyleCache.containsKey(columnIndex)) { CellStyle cellStyle = headCellStyleCache.get(columnIndex); @@ -50,6 +52,9 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl @Override protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) { + if (head == null) { + return; + } int columnIndex = head.getColumnIndex(); if (contentCellStyleCache.containsKey(columnIndex)) { CellStyle cellStyle = contentCellStyleCache.get(columnIndex); @@ -71,8 +76,7 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl /** * Returns the column width corresponding to each column head * - * @param head - * Nullable + * @param head Nullable * @return */ protected abstract WriteCellStyle headCellStyle(Head head); @@ -80,8 +84,7 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl /** * Returns the column width corresponding to each column head * - * @param head - * Nullable + * @param head Nullable * @return */ protected abstract WriteCellStyle contentCellStyle(Head head); diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java index edcf8a0b..ea011b31 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java @@ -27,6 +27,7 @@ import com.alibaba.fastjson.JSON; */ @Ignore public class ReadTest { + private static final Logger LOGGER = LoggerFactory.getLogger(ReadTest.class); /** @@ -48,11 +49,17 @@ public class ReadTest { // 写法2: fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; - ExcelReader excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build(); - ReadSheet readSheet = EasyExcel.readSheet(0).build(); - excelReader.read(readSheet); - // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的 - excelReader.finish(); + ExcelReader excelReader = null; + try { + excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build(); + ReadSheet readSheet = EasyExcel.readSheet(0).build(); + excelReader.read(readSheet); + } finally { + if (excelReader != null) { + // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的 + excelReader.finish(); + } + } } /** @@ -90,16 +97,23 @@ public class ReadTest { // 读取部分sheet fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; - ExcelReader excelReader = EasyExcel.read(fileName).build(); - // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener - ReadSheet readSheet1 = - EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build(); - ReadSheet readSheet2 = - EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build(); - // 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能 - excelReader.read(readSheet1, readSheet2); - // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的 - excelReader.finish(); + ExcelReader excelReader = null; + try { + excelReader = EasyExcel.read(fileName).build(); + + // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener + ReadSheet readSheet1 = + EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build(); + ReadSheet readSheet2 = + EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build(); + // 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能 + excelReader.read(readSheet1, readSheet2); + } finally { + if (excelReader != null) { + // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的 + excelReader.finish(); + } + } } /** diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index 7139fa8f..ee9ce2f6 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -40,6 +40,7 @@ import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy */ @Ignore public class WriteTest { + /** * 最简单的写 *

@@ -58,11 +59,17 @@ public class WriteTest { // 写法2 fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx"; // 这里 需要指定写用哪个class去写 - ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build(); - WriteSheet writeSheet = EasyExcel.writerSheet("模板").build(); - excelWriter.write(data(), writeSheet); - /// 千万别忘记finish 会帮忙关闭流 - excelWriter.finish(); + ExcelWriter excelWriter = null; + try { + excelWriter = EasyExcel.write(fileName, DemoData.class).build(); + WriteSheet writeSheet = EasyExcel.writerSheet("模板").build(); + excelWriter.write(data(), writeSheet); + } finally { + // 千万别忘记finish 会帮忙关闭流 + if (excelWriter != null) { + excelWriter.finish(); + } + } } /** @@ -141,48 +148,64 @@ public class WriteTest { public void repeatedWrite() { // 方法1 如果写到同一个sheet String fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; - // 这里 需要指定写用哪个class去写 - ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build(); - // 这里注意 如果同一个sheet只要创建一次 - WriteSheet writeSheet = EasyExcel.writerSheet("模板").build(); - // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来 - for (int i = 0; i < 5; i++) { - // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 - List data = data(); - excelWriter.write(data, writeSheet); + ExcelWriter excelWriter = null; + try { + // 这里 需要指定写用哪个class去写 + excelWriter = EasyExcel.write(fileName, DemoData.class).build(); + // 这里注意 如果同一个sheet只要创建一次 + WriteSheet writeSheet = EasyExcel.writerSheet("模板").build(); + // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来 + for (int i = 0; i < 5; i++) { + // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 + List data = data(); + excelWriter.write(data, writeSheet); + } + } finally { + // 千万别忘记finish 会帮忙关闭流 + if (excelWriter != null) { + excelWriter.finish(); + } } - /// 千万别忘记finish 会帮忙关闭流 - excelWriter.finish(); // 方法2 如果写到不同的sheet 同一个对象 fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; - // 这里 指定文件 - excelWriter = EasyExcel.write(fileName, DemoData.class).build(); - // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面 - for (int i = 0; i < 5; i++) { - // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样 - writeSheet = EasyExcel.writerSheet(i, "模板" + i).build(); - // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 - List data = data(); - excelWriter.write(data, writeSheet); + try { + // 这里 指定文件 + excelWriter = EasyExcel.write(fileName, DemoData.class).build(); + // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面 + for (int i = 0; i < 5; i++) { + // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样 + WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).build(); + // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 + List data = data(); + excelWriter.write(data, writeSheet); + } + } finally { + // 千万别忘记finish 会帮忙关闭流 + if (excelWriter != null) { + excelWriter.finish(); + } } - /// 千万别忘记finish 会帮忙关闭流 - excelWriter.finish(); // 方法3 如果写到不同的sheet 不同的对象 fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; - // 这里 指定文件 - excelWriter = EasyExcel.write(fileName).build(); - // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面 - for (int i = 0; i < 5; i++) { - // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class 实际上可以一直变 - writeSheet = EasyExcel.writerSheet(i, "模板" + i).head(DemoData.class).build(); - // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 - List data = data(); - excelWriter.write(data, writeSheet); + try { + // 这里 指定文件 + excelWriter = EasyExcel.write(fileName).build(); + // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面 + for (int i = 0; i < 5; i++) { + // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class 实际上可以一直变 + WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).head(DemoData.class).build(); + // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 + List data = data(); + excelWriter.write(data, writeSheet); + } + } finally { + // 千万别忘记finish 会帮忙关闭流 + if (excelWriter != null) { + excelWriter.finish(); + } } - /// 千万别忘记finish 会帮忙关闭流 - excelWriter.finish(); } /** @@ -302,7 +325,7 @@ public class WriteTest { // 背景设置为红色 headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); WriteFont headWriteFont = new WriteFont(); - headWriteFont.setFontHeightInPoints((short)20); + headWriteFont.setFontHeightInPoints((short) 20); headWriteCellStyle.setWriteFont(headWriteFont); // 内容的策略 WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); @@ -312,7 +335,7 @@ public class WriteTest { contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); WriteFont contentWriteFont = new WriteFont(); // 字体大小 - contentWriteFont.setFontHeightInPoints((short)20); + contentWriteFont.setFontHeightInPoints((short) 20); contentWriteCellStyle.setWriteFont(contentWriteFont); // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现 HorizontalCellStyleStrategy horizontalCellStyleStrategy = @@ -362,18 +385,24 @@ public class WriteTest { String fileName = TestFileUtil.getPath() + "tableWrite" + System.currentTimeMillis() + ".xlsx"; // 这里直接写多个table的案例了,如果只有一个 也可以直一行代码搞定,参照其他案例 // 这里 需要指定写用哪个class去写 - ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build(); - // 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了 - WriteSheet writeSheet = EasyExcel.writerSheet("模板").needHead(Boolean.FALSE).build(); - // 这里必须指定需要头,table 会继承sheet的配置,sheet配置了不需要,table 默认也是不需要 - WriteTable writeTable0 = EasyExcel.writerTable(0).needHead(Boolean.TRUE).build(); - WriteTable writeTable1 = EasyExcel.writerTable(1).needHead(Boolean.TRUE).build(); - // 第一次写入会创建头 - excelWriter.write(data(), writeSheet, writeTable0); - // 第二次写如也会创建头,然后在第一次的后面写入数据 - excelWriter.write(data(), writeSheet, writeTable1); - /// 千万别忘记finish 会帮忙关闭流 - excelWriter.finish(); + ExcelWriter excelWriter = null; + try { + EasyExcel.write(fileName, DemoData.class).build(); + // 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了 + WriteSheet writeSheet = EasyExcel.writerSheet("模板").needHead(Boolean.FALSE).build(); + // 这里必须指定需要头,table 会继承sheet的配置,sheet配置了不需要,table 默认也是不需要 + WriteTable writeTable0 = EasyExcel.writerTable(0).needHead(Boolean.TRUE).build(); + WriteTable writeTable1 = EasyExcel.writerTable(1).needHead(Boolean.TRUE).build(); + // 第一次写入会创建头 + excelWriter.write(data(), writeSheet, writeTable0); + // 第二次写如也会创建头,然后在第一次的后面写入数据 + excelWriter.write(data(), writeSheet, writeTable1); + } finally { + // 千万别忘记finish 会帮忙关闭流 + if (excelWriter != null) { + excelWriter.finish(); + } + } } /** @@ -399,8 +428,7 @@ public class WriteTest { /** * 自动列宽(不太精确) *

- * 这个目前不是很好用,比如有数字就会导致换行。而且长度也不是刚好和实际长度一致。 所以需要精确到刚好列宽的慎用。 当然也可以自己参照 - * {@link LongestMatchColumnWidthStyleStrategy}重新实现. + * 这个目前不是很好用,比如有数字就会导致换行。而且长度也不是刚好和实际长度一致。 所以需要精确到刚好列宽的慎用。 当然也可以自己参照 {@link LongestMatchColumnWidthStyleStrategy}重新实现. *

* poi 自带{@link SXSSFSheet#autoSizeColumn(int)} 对中文支持也不太好。目前没找到很好的算法。 有的话可以推荐下。 * diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/FillTempTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/FillTempTest.java index 0ed625da..7917e063 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/FillTempTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/FillTempTest.java @@ -13,6 +13,7 @@ import com.alibaba.easyexcel.test.temp.fill.FillData2; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy; import com.alibaba.excel.write.metadata.WriteSheet; /** @@ -33,16 +34,21 @@ public class FillTempTest { public void complexFill() { // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替 // {} 代表普通变量 {.} 代表是list的变量 - String templateFileName = "D:\\test\\simple.xlsx"; + OnceAbsoluteMergeStrategy onceAbsoluteMergeStrategy = new OnceAbsoluteMergeStrategy(2, 2, 0, 1); String fileName = TestFileUtil.getPath() + "complexFill" + System.currentTimeMillis() + ".xlsx"; - ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); - WriteSheet writeSheet = EasyExcel.writerSheet().build(); - excelWriter.fill(teamp(), writeSheet); + ExcelWriter excelWriter = EasyExcel.write(fileName).registerWriteHandler(onceAbsoluteMergeStrategy).withTemplate(TestFileUtil.readUserHomeFile("test/simple.xlsx")).build(); + WriteSheet writeSheet0 = EasyExcel.writerSheet(0).build(); + WriteSheet writeSheet1 = EasyExcel.writerSheet(1).build(); + + excelWriter.fill(teamp(), writeSheet0); + excelWriter.fill(teamp(), writeSheet1); + Map map = new HashMap(); map.put("date", "2019年10月9日13:28:28"); map.put("total", 1000); - excelWriter.fill(map, writeSheet); + excelWriter.fill(map, writeSheet0); + excelWriter.finish(); } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java b/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java index c801077f..0dcef53c 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java @@ -28,19 +28,29 @@ import com.alibaba.fastjson.JSON; **/ @Ignore public class Lock2Test { + private static final Logger LOGGER = LoggerFactory.getLogger(Lock2Test.class); @Test public void test() throws Exception { - File file = TestFileUtil.readUserHomeFile("test/t3.xls"); + File file = TestFileUtil.readUserHomeFile("test/test6.xls"); - List list = EasyExcel.read(file).sheet().headRowNumber(0).doReadSync(); + List list = EasyExcel.read(file).sheet(1).headRowNumber(0).doReadSync(); LOGGER.info("数据:{}", list.size()); for (Object data : list) { LOGGER.info("返回数据:{}", JSON.toJSONString(data)); } } + @Test + public void test33() throws Exception { + File file = TestFileUtil.readUserHomeFile("test/test6.xlsx"); + + EasyExcel.read(file, LockData.class, new LockDataListener()).sheet(0).headRowNumber(0) + .doRead(); + + } + @Test public void write() throws Exception { String fileName = TestFileUtil.getPath() + "styleWrite" + System.currentTimeMillis() + ".xlsx"; @@ -49,7 +59,7 @@ public class Lock2Test { // 背景设置为红色 headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); WriteFont headWriteFont = new WriteFont(); - headWriteFont.setFontHeightInPoints((short)20); + headWriteFont.setFontHeightInPoints((short) 20); headWriteCellStyle.setWriteFont(headWriteFont); // 内容的策略 WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); @@ -59,7 +69,7 @@ public class Lock2Test { contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); WriteFont contentWriteFont = new WriteFont(); // 字体大小 - contentWriteFont.setFontHeightInPoints((short)20); + contentWriteFont.setFontHeightInPoints((short) 20); contentWriteCellStyle.setWriteFont(contentWriteFont); // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现 HorizontalCellStyleStrategy horizontalCellStyleStrategy = diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/LockData.java b/src/test/java/com/alibaba/easyexcel/test/temp/LockData.java index 2e1ed7b0..14fa65e3 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/LockData.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/LockData.java @@ -1,5 +1,7 @@ package com.alibaba.easyexcel.test.temp; +import com.alibaba.excel.annotation.format.NumberFormat; + import lombok.Data; /** @@ -9,7 +11,8 @@ import lombok.Data; **/ @Data public class LockData { - private String string0; + @NumberFormat("#.##%") + private Double string0; private String string1; private String string2; private String string3; diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/LockDataListener.java b/src/test/java/com/alibaba/easyexcel/test/temp/LockDataListener.java index d5891115..64cce8db 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/LockDataListener.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/LockDataListener.java @@ -18,16 +18,16 @@ import com.alibaba.fastjson.JSON; * * @author Jiaju Zhuang */ -public class LockDataListener extends AnalysisEventListener> { +public class LockDataListener extends AnalysisEventListener { private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class); /** * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 */ private static final int BATCH_COUNT = 5; - List> list = new ArrayList>(); + List list = new ArrayList(); @Override - public void invoke(Map data, AnalysisContext context) { + public void invoke(LockData data, AnalysisContext context) { LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data)); list.add(data); if (list.size() >= BATCH_COUNT) { diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/WriteLargeTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/WriteLargeTest.java new file mode 100644 index 00000000..008d7629 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/WriteLargeTest.java @@ -0,0 +1,108 @@ +package com.alibaba.easyexcel.test.temp; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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.excel.ExcelWriter; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.metadata.style.WriteFont; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; + +/** + * 临时测试 + * + * @author Jiaju Zhuang + **/ +@Ignore +public class WriteLargeTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(WriteLargeTest.class); + private int i = 0; + + @Test + public void test() throws Exception { + // 方法2 如果写到不同的sheet 同一个对象 + String fileName = TestFileUtil.getPath() + "large" + System.currentTimeMillis() + ".xlsx"; + // 头的策略 + WriteCellStyle headWriteCellStyle = new WriteCellStyle(); + // 背景设置为红色 + headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); + WriteFont headWriteFont = new WriteFont(); + headWriteFont.setFontHeightInPoints((short)20); + headWriteCellStyle.setWriteFont(headWriteFont); + // 内容的策略 + WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); + // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定 + contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); + // 背景绿色 + contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); + WriteFont contentWriteFont = new WriteFont(); + // 字体大小 + contentWriteFont.setFontHeightInPoints((short)20); + contentWriteCellStyle.setWriteFont(contentWriteFont); + // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现 + HorizontalCellStyleStrategy horizontalCellStyleStrategy = + new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); + + + ExcelWriter excelWriter = EasyExcel.write(fileName,LargeData.class).registerWriteHandler(horizontalCellStyleStrategy).build(); + WriteSheet writeSheet = EasyExcel.writerSheet().build(); + for (int j = 0; j < 100; j++) { + excelWriter.write(data(), writeSheet); + LOGGER.info("{} fill success.", j); + } + excelWriter.finish(); + + } + + + private List data() { + List list = new ArrayList(); + int size = i + 5000; + for (; i < size; i++) { + LargeData largeData = new LargeData(); + list.add(largeData); + largeData.setStr1("str1-" + i); + largeData.setStr2("str2-" + i); + largeData.setStr3("str3-" + i); + largeData.setStr4("str4-" + i); + largeData.setStr5("str5-" + i); + largeData.setStr6("str6-" + i); + largeData.setStr7("str7-" + i); + largeData.setStr8("str8-" + i); + largeData.setStr9("str9-" + i); + largeData.setStr10("str10-" + i); + largeData.setStr11("str11-" + i); + largeData.setStr12("str12-" + i); + largeData.setStr13("str13-" + i); + largeData.setStr14("str14-" + i); + largeData.setStr15("str15-" + i); + largeData.setStr16("str16-" + i); + largeData.setStr17("str17-" + i); + largeData.setStr18("str18-" + i); + largeData.setStr19("str19-" + i); + largeData.setStr20("str20-" + i); + largeData.setStr21("str21-" + i); + largeData.setStr22("str22-" + i); + largeData.setStr23("str23-" + i); + largeData.setStr24("str24-" + i); + largeData.setStr25("str25-" + i); + } + return list; + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java b/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java new file mode 100644 index 00000000..f8db7f9c --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java @@ -0,0 +1,67 @@ +package com.alibaba.easyexcel.test.temp; + +import java.io.File; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.apache.poi.hssf.util.CellReference; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.easyexcel.test.demo.write.DemoData; +import com.alibaba.easyexcel.test.util.TestFileUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.metadata.style.WriteFont; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +import com.alibaba.fastjson.JSON; + +/** + * 临时测试 + * + * @author Jiaju Zhuang + **/ +@Ignore +public class WriteV33Test { + + private static final Logger LOGGER = LoggerFactory.getLogger(WriteV33Test.class); + + @Test + public void test() throws Exception { + // 方法2 如果写到不同的sheet 同一个对象 + String fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; + OnceAbsoluteMergeStrategy onceAbsoluteMergeStrategy = new OnceAbsoluteMergeStrategy(2, 2, 0, 1); + + // 这里 指定文件 + ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).registerWriteHandler(onceAbsoluteMergeStrategy).build(); + WriteSheet writeSheet1 = EasyExcel.writerSheet(1, "模板1").build(); + WriteSheet writeSheet2 = EasyExcel.writerSheet(2, "模板2").build(); + WriteSheet writeSheet3 = EasyExcel.writerSheet(3, "模板3").build(); + excelWriter.write(data(2), writeSheet2); + excelWriter.write(data(3), writeSheet3); + excelWriter.write(data(1), writeSheet1); + excelWriter.write(data(3), writeSheet3); + excelWriter.write(data(1), writeSheet1); + /// 千万别忘记finish 会帮忙关闭流 + excelWriter.finish(); + } + + private List data(int no) { + List list = new ArrayList(); + for (int i = 0; i < 10; i++) { + DemoData data = new DemoData(); + data.setString("字符串" + no + "---" + i); + list.add(data); + } + return list; + } + +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/WriteV34Test.java b/src/test/java/com/alibaba/easyexcel/test/temp/WriteV34Test.java new file mode 100644 index 00000000..cf815292 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/WriteV34Test.java @@ -0,0 +1,91 @@ +package com.alibaba.easyexcel.test.temp; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.easyexcel.test.demo.write.DemoData; +import com.alibaba.easyexcel.test.util.TestFileUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.metadata.style.WriteFont; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; + +/** + * 临时测试 + * + * @author Jiaju Zhuang + **/ +@Ignore +public class WriteV34Test { + + private static final Logger LOGGER = LoggerFactory.getLogger(WriteV34Test.class); + + @Test + public void test() throws Exception { + String fileName = TestFileUtil.getPath() + "handlerStyleWrite" + System.currentTimeMillis() + ".xlsx"; + // 头的策略 + WriteCellStyle headWriteCellStyle = new WriteCellStyle(); + // 背景设置为红色 + headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); + WriteFont headWriteFont = new WriteFont(); + headWriteFont.setFontHeightInPoints((short)20); + headWriteCellStyle.setWriteFont(headWriteFont); + // 内容的策略 + WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); + // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定 + contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); + // 背景绿色 + contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); + WriteFont contentWriteFont = new WriteFont(); + // 字体大小 + contentWriteFont.setFontHeightInPoints((short)20); + contentWriteCellStyle.setWriteFont(contentWriteFont); + // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现 + HorizontalCellStyleStrategy horizontalCellStyleStrategy = + new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); + + // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + EasyExcel.write(fileName,DemoData.class).head(head()).registerWriteHandler(horizontalCellStyleStrategy).sheet("模板") + .doWrite(data(1)); + } + + + private List> head() { + List> list = new ArrayList>(); + List head0 = new ArrayList(); + head0.add("字符串" + System.currentTimeMillis()); + head0.add("再找找"); + List head1 = new ArrayList(); + head1.add("数字" + System.currentTimeMillis()); + List head2 = new ArrayList(); + head2.add("日期" + System.currentTimeMillis()); + List head3 = new ArrayList(); + head3.add("日期" + System.currentTimeMillis()); + list.add(head0); + list.add(head1); + list.add(head2); list.add(head3); + + + return list; + } + + private List data(int no) { + List list = new ArrayList(); + for (int i = 0; i < 10; i++) { + DemoData data = new DemoData(); + data.setString("字符串" + no + "---" + i); + list.add(data); + } + return list; + } + +} 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 e31e74b1..ffabd105 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 @@ -126,6 +126,7 @@ public class Wirte { for (int i = 0; i < 10; i++) { WriteData data = new WriteData(); data.setF(300.35f); + data.setF1(33f); 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 index b9de59b9..2b25bb0a 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteData.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteData.java @@ -11,6 +11,8 @@ import lombok.Data; **/ @Data public class WriteData { - @ContentStyle(locked = true) +// @ContentStyle(locked = true) private float f; +// @ContentStyle(locked = false) + private float f1; } diff --git a/update.md b/update.md index fdb7b140..5374449a 100644 --- a/update.md +++ b/update.md @@ -1,9 +1,23 @@ +# 2.2.4 +* 撤销删除`AbstractMergeStrategy` +* 修改默认用String读取数字不使用科学计数法 通过`useScientificFormat`修改 +* 修复07版仅有样式的空行 默认不忽略的bug +* 写入`sheet`不设置`index`和`name`默认不为0的问题 +* 修复多个`sheet`不按照顺序写入 会乱序的bug [Issue #1332](https://github.com/alibaba/easyexcel/issues/1332) +* 修改head是List时,内容单元格的样式不生效 [Issue #1339](https://github.com/alibaba/easyexcel/issues/1339) +* 修复xls仅公式行 不读取的bug [Issue #1324](https://github.com/alibaba/easyexcel/issues/1324) +* 修复xls直接读取第2页 `NPE` 的bug [Issue #1280](https://github.com/alibaba/easyexcel/issues/1280) +* 修复填充的时候,最后一行中间有空行会创建失败的bug +* 修复`includeColumnIndexes`不包含第列 会无法导出数据的bug [Issue #1346](https://github.com/alibaba/easyexcel/issues/1346) +* 修复`@NumberFormat`注解转换double时可能会丢失精度 [Issue #1306](https://github.com/alibaba/easyexcel/issues/1306) + # 2.2.3 * 修改填充数据空数据的bug [Issue #1274](https://github.com/alibaba/easyexcel/issues/1274) * 回退自定义转换器入参为空 # 2.2.2 * 修改`sheet`事件未调用的bug +* 修复复杂表头不是`index=0`开始 合并异常的bug [Issue #1322](https://github.com/alibaba/easyexcel/issues/1322) # 2.2.1 * 发布正式版