diff --git a/pom.xml b/pom.xml index 90838f33..514464b1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.alibaba easyexcel - 2.1.0-beta2 + 2.1.0-beta3 jar easyexcel diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java index 6e1f435d..72a27e7f 100644 --- a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java +++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java @@ -129,26 +129,28 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { } ReadWorkbookHolder readWorkbookHolder = analysisContext.readWorkbookHolder(); + Throwable throwable = null; + try { if (readWorkbookHolder.getReadCache() != null) { readWorkbookHolder.getReadCache().destroy(); } } catch (Throwable t) { - throwCanNotCloseIo(t); + throwable = t; } try { if (readWorkbookHolder.getOpcPackage() != null) { readWorkbookHolder.getOpcPackage().revert(); } } catch (Throwable t) { - throwCanNotCloseIo(t); + throwable = t; } try { if (readWorkbookHolder.getPoifsFileSystem() != null) { readWorkbookHolder.getPoifsFileSystem().close(); } } catch (Throwable t) { - throwCanNotCloseIo(t); + throwable = t; } try { if (analysisContext.readWorkbookHolder().getAutoCloseStream() @@ -156,17 +158,21 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { readWorkbookHolder.getInputStream().close(); } } catch (Throwable t) { - throwCanNotCloseIo(t); + throwable = t; } try { if (readWorkbookHolder.getTempFile() != null) { FileUtils.delete(readWorkbookHolder.getTempFile()); } } catch (Throwable t) { - throwCanNotCloseIo(t); + throwable = t; } clearEncrypt03(); + + if (throwable != null) { + throw new ExcelAnalysisException("Can not close IO", throwable); + } } private void clearEncrypt03() { @@ -177,10 +183,6 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { Biff8EncryptionKey.setCurrentUserPassword(null); } - private void throwCanNotCloseIo(Throwable t) { - throw new ExcelAnalysisException("Can not close IO", t); - } - @Override public ExcelReadExecutor excelExecutor() { return excelReadExecutor; diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java index dd468b4b..a30b4260 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java @@ -15,7 +15,6 @@ import javax.xml.parsers.SAXParserFactory; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.usermodel.XSSFRelation; @@ -35,7 +34,6 @@ import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.SheetUtils; -import com.alibaba.excel.util.StringUtils; /** * diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index ffacd521..f136ea09 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java @@ -179,6 +179,7 @@ public class WriteContextImpl implements WriteContext { Row row = WorkBookUtil.createRow(writeSheetHolder.getSheet(), i); WriteHandlerUtils.afterRowCreate(this, row, relativeRowIndex, Boolean.TRUE); addOneRowOfHeadDataToExcel(row, excelWriteHeadProperty.getHeadMap(), relativeRowIndex); + WriteHandlerUtils.afterRowDispose(this, row, relativeRowIndex, Boolean.FALSE); } } @@ -197,8 +198,7 @@ public class WriteContextImpl implements WriteContext { Cell cell = row.createCell(columnIndex); WriteHandlerUtils.afterCellCreate(this, cell, head, relativeRowIndex, Boolean.TRUE); cell.setCellValue(head.getHeadNameList().get(relativeRowIndex)); - CellData cellData = null; - WriteHandlerUtils.afterCellDispose(this, cellData, cell, head, relativeRowIndex, Boolean.TRUE); + WriteHandlerUtils.afterCellDispose(this, (CellData)null, cell, head, relativeRowIndex, Boolean.TRUE); } } @@ -261,12 +261,13 @@ public class WriteContextImpl implements WriteContext { if (writeWorkbookHolder == null) { return; } + Throwable throwable = null; boolean isOutputStreamEncrypt = false; try { isOutputStreamEncrypt = doOutputStreamEncrypt07(); } catch (Throwable t) { - throwCanNotCloseIo(t); + throwable = t; } if (!isOutputStreamEncrypt) { @@ -274,7 +275,7 @@ public class WriteContextImpl implements WriteContext { writeWorkbookHolder.getWorkbook().write(writeWorkbookHolder.getOutputStream()); writeWorkbookHolder.getWorkbook().close(); } catch (Throwable t) { - throwCanNotCloseIo(t); + throwable = t; } } @@ -284,7 +285,7 @@ public class WriteContextImpl implements WriteContext { ((SXSSFWorkbook)workbook).dispose(); } } catch (Throwable t) { - throwCanNotCloseIo(t); + throwable = t; } try { @@ -292,14 +293,14 @@ public class WriteContextImpl implements WriteContext { writeWorkbookHolder.getOutputStream().close(); } } catch (Throwable t) { - throwCanNotCloseIo(t); + throwable = t; } if (!isOutputStreamEncrypt) { try { doFileEncrypt07(); } catch (Throwable t) { - throwCanNotCloseIo(t); + throwable = t; } } @@ -308,20 +309,20 @@ public class WriteContextImpl implements WriteContext { writeWorkbookHolder.getTempTemplateInputStream().close(); } } catch (Throwable t) { - throwCanNotCloseIo(t); + throwable = t; } clearEncrypt03(); + if (throwable != null) { + throw new ExcelGenerateException("Can not close IO", throwable); + } + if (LOGGER.isDebugEnabled()) { LOGGER.debug("Finished write."); } } - private void throwCanNotCloseIo(Throwable t) { - throw new ExcelGenerateException("Can not close IO", t); - } - @Override public Sheet getCurrentSheet() { return writeSheetHolder.getSheet(); 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 69211617..9d6a5442 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java @@ -17,14 +17,15 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.format.DateTimeFormat; import com.alibaba.excel.annotation.format.NumberFormat; -import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.alibaba.excel.converters.AutoConverter; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.exception.ExcelCommonException; import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.Holder; import com.alibaba.excel.util.StringUtils; +import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder; /** * Define the header attribute of excel @@ -46,7 +47,6 @@ public class ExcelHeadProperty { * The number of rows in the line with the most rows */ private int headRowNumber; - /** * Configuration header information */ @@ -64,7 +64,7 @@ public class ExcelHeadProperty { */ private Map ignoreMap; - public ExcelHeadProperty(Class headClazz, List> head, Boolean convertAllFiled) { + public ExcelHeadProperty(Holder holder, Class headClazz, List> head, Boolean convertAllFiled) { this.headClazz = headClazz; headMap = new TreeMap(); contentPropertyMap = new TreeMap(); @@ -73,14 +73,21 @@ public class ExcelHeadProperty { headKind = HeadKindEnum.NONE; headRowNumber = 0; if (head != null && !head.isEmpty()) { + int headIndex = 0; for (int i = 0; i < head.size(); i++) { - headMap.put(i, new Head(i, null, head.get(i), Boolean.FALSE, Boolean.TRUE)); - contentPropertyMap.put(i, null); + if (holder instanceof AbstractWriteHolder) { + if (((AbstractWriteHolder)holder).ignore(null, i)) { + continue; + } + } + headMap.put(headIndex, new Head(headIndex, null, head.get(i), Boolean.FALSE, Boolean.TRUE)); + contentPropertyMap.put(headIndex, null); + headIndex++; } headKind = HeadKindEnum.STRING; } else { // convert headClazz to head - initColumnProperties(convertAllFiled); + initColumnProperties(holder, convertAllFiled); } initHeadRowNumber(); if (LOGGER.isDebugEnabled()) { @@ -108,7 +115,7 @@ public class ExcelHeadProperty { } } - private void initColumnProperties(Boolean convertAllFiled) { + private void initColumnProperties(Holder holder, Boolean convertAllFiled) { if (headClazz == null) { return; } @@ -161,20 +168,37 @@ public class ExcelHeadProperty { int index = 0; for (Field field : defaultFieldList) { while (customFiledMap.containsKey(index)) { - initOneColumnProperty(index, customFiledMap.get(index), Boolean.TRUE); + Field customFiled = customFiledMap.get(index); customFiledMap.remove(index); + if (!initOneColumnProperty(holder, index, customFiled, Boolean.TRUE)) { + index++; + } + } + if (!initOneColumnProperty(holder, index, field, Boolean.FALSE)) { index++; } - initOneColumnProperty(index, field, Boolean.FALSE); - index++; } for (Map.Entry entry : customFiledMap.entrySet()) { - initOneColumnProperty(entry.getKey(), entry.getValue(), Boolean.TRUE); + initOneColumnProperty(holder, entry.getKey(), entry.getValue(), Boolean.TRUE); } headKind = HeadKindEnum.CLASS; } - private void initOneColumnProperty(int index, Field field, Boolean forceIndex) { + /** + * Initialization column property + * + * @param holder + * @param index + * @param field + * @param forceIndex + * @return Ignore current field + */ + private boolean initOneColumnProperty(Holder holder, int index, Field field, Boolean forceIndex) { + if (holder instanceof AbstractWriteHolder) { + if (((AbstractWriteHolder)holder).ignore(field.getName(), index)) { + return true; + } + } ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); List tmpHeadList = new ArrayList(); boolean notForceName = excelProperty == null || excelProperty.value().length <= 0 @@ -206,6 +230,7 @@ public class ExcelHeadProperty { headMap.put(index, head); contentPropertyMap.put(index, excelContentProperty); fieldNameContentPropertyMap.put(field.getName(), excelContentProperty); + return false; } public Class getHeadClazz() { diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java index 4ca8d63c..a748f32c 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java @@ -70,7 +70,7 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH } // Initialization property - this.excelReadHeadProperty = new ExcelReadHeadProperty(getClazz(), getHead(), convertAllFiled); + this.excelReadHeadProperty = new ExcelReadHeadProperty(this, getClazz(), getHead(), convertAllFiled); if (readBasicParameter.getHeadRowNumber() == null) { if (parentAbstractReadHolder == null) { if (excelReadHeadProperty.hasHead()) { diff --git a/src/main/java/com/alibaba/excel/read/metadata/property/ExcelReadHeadProperty.java b/src/main/java/com/alibaba/excel/read/metadata/property/ExcelReadHeadProperty.java index fdc5562d..1b7ae17c 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/property/ExcelReadHeadProperty.java +++ b/src/main/java/com/alibaba/excel/read/metadata/property/ExcelReadHeadProperty.java @@ -2,6 +2,7 @@ package com.alibaba.excel.read.metadata.property; import java.util.List; +import com.alibaba.excel.metadata.Holder; import com.alibaba.excel.metadata.property.ExcelHeadProperty; /** @@ -11,7 +12,7 @@ import com.alibaba.excel.metadata.property.ExcelHeadProperty; */ public class ExcelReadHeadProperty extends ExcelHeadProperty { - public ExcelReadHeadProperty(Class headClazz, List> head, Boolean convertAllFiled) { - super(headClazz, head, convertAllFiled); + public ExcelReadHeadProperty(Holder holder, Class headClazz, List> head, Boolean convertAllFiled) { + super(holder, headClazz, head, convertAllFiled); } } diff --git a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java index bcec5234..186708c9 100644 --- a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java +++ b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java @@ -31,12 +31,21 @@ public class WorkBookUtil { if (writeWorkbookHolder.getTempTemplateInputStream() != null) { XSSFWorkbook xssfWorkbook = new XSSFWorkbook(writeWorkbookHolder.getTempTemplateInputStream()); writeWorkbookHolder.setCachedWorkbook(xssfWorkbook); - writeWorkbookHolder.setWorkbook(new SXSSFWorkbook(xssfWorkbook, ROW_ACCESS_WINDOW_SIZE)); + if (writeWorkbookHolder.getInMemory()) { + writeWorkbookHolder.setWorkbook(xssfWorkbook); + } else { + writeWorkbookHolder.setWorkbook(new SXSSFWorkbook(xssfWorkbook, ROW_ACCESS_WINDOW_SIZE)); + } return; } - SXSSFWorkbook sxssWorkbook = new SXSSFWorkbook(ROW_ACCESS_WINDOW_SIZE); - writeWorkbookHolder.setCachedWorkbook(sxssWorkbook); - writeWorkbookHolder.setWorkbook(sxssWorkbook); + Workbook workbook = null; + if (writeWorkbookHolder.getInMemory()) { + workbook = new XSSFWorkbook(); + } else { + workbook = new SXSSFWorkbook(ROW_ACCESS_WINDOW_SIZE); + } + writeWorkbookHolder.setCachedWorkbook(workbook); + writeWorkbookHolder.setWorkbook(workbook); return; } HSSFWorkbook hssfWorkbook; 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 82de0381..8af1e62c 100644 --- a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java +++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java @@ -4,6 +4,7 @@ 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; @@ -103,6 +104,48 @@ public class ExcelWriterBuilder { return this; } + /** + * Write excel in memory. Default false,the cache file is created and finally written to excel. + *

+ * Comment and RichTextString are only supported in memory mode. + */ + public ExcelWriterBuilder inMemory(Boolean inMemory) { + writeWorkbook.setInMemory(inMemory); + 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; + } + /** * The default is all excel objects.if true , you can use {@link com.alibaba.excel.annotation.ExcelIgnore} ignore a * field. if false , you must use {@link com.alibaba.excel.annotation.ExcelProperty} to use a filed. 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 26acff51..50f230ae 100644 --- a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java +++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java @@ -1,6 +1,7 @@ package com.alibaba.excel.write.builder; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import com.alibaba.excel.ExcelWriter; @@ -135,6 +136,38 @@ 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; } 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 eca1fe07..40ca58b9 100644 --- a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterTableBuilder.java +++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterTableBuilder.java @@ -1,6 +1,7 @@ package com.alibaba.excel.write.builder; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import com.alibaba.excel.ExcelWriter; @@ -128,6 +129,39 @@ 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; } 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 8843e2cc..0fa0cae2 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java @@ -98,6 +98,9 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { private void doAddBasicTypeToExcel(List oneRowData, Head head, Row row, int relativeRowIndex, int dataIndex, int cellIndex) { + if (writeContext.currentWriteHolder().ignore(null, cellIndex)) { + return; + } WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE); Cell cell = WorkBookUtil.createCell(row, cellIndex); WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE); @@ -121,6 +124,9 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { cellIndex = entry.getKey(); ExcelContentProperty excelContentProperty = entry.getValue(); String name = excelContentProperty.getField().getName(); + if (writeContext.currentWriteHolder().ignore(name, cellIndex)) { + continue; + } if (!beanMap.containsKey(name)) { continue; } @@ -147,7 +153,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { for (Field field : fieldList) { String filedName = field.getName(); boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName) - || ignoreMap.containsKey(filedName); + || ignoreMap.containsKey(filedName) || writeContext.currentWriteHolder().ignore(filedName, cellIndex); if (uselessData) { continue; } 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 388fc770..75a88105 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java @@ -9,6 +9,7 @@ import java.util.Map; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; @@ -141,6 +142,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { Cell cell = getOneCell(analysisCell, fillConfig); if (analysisCell.getOnlyOneVariable()) { String variable = analysisCell.getVariableList().get(0); + if (writeContext.currentWriteHolder().ignore(variable, analysisCell.getColumnIndex())) { + continue; + } if (!dataMap.containsKey(variable)) { continue; } @@ -154,6 +158,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { List cellDataList = new ArrayList(); for (String variable : analysisCell.getVariableList()) { cellValueBuild.append(analysisCell.getPrepareDataList().get(index++)); + if (writeContext.currentWriteHolder().ignore(variable, analysisCell.getColumnIndex())) { + continue; + } if (!dataMap.containsKey(variable)) { continue; } @@ -279,11 +286,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { if (cell == null) { continue; } - boolean needFill = - prepareData(cell.getStringCellValue(), analysisCellList, collectionAnalysisCellList, i, j); + String preparedData = prepareData(cell, analysisCellList, collectionAnalysisCellList, i, j); // Prevent empty data from not being replaced - if (needFill) { - cell.setCellValue(StringUtils.EMPTY); + if (preparedData != null) { + cell.setCellValue(preparedData); } } } @@ -295,18 +301,23 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { /** * To prepare data * - * @param value + * @param cell * @param analysisCellList * @param collectionAnalysisCellList * @param rowIndex * @param columnIndex - * @return Is a cell to be filled + * @return Returns the data that the cell needs to replace */ - private boolean prepareData(String value, List analysisCellList, + private String prepareData(Cell cell, List analysisCellList, List collectionAnalysisCellList, int rowIndex, int columnIndex) { + if (!CellType.STRING.equals(cell.getCellTypeEnum())) { + return null; + } + String value = cell.getStringCellValue(); if (StringUtils.isEmpty(value)) { - return false; + return null; } + StringBuilder preparedData = new StringBuilder(); AnalysisCell analysisCell = null; int startIndex = 0; int length = value.length(); @@ -354,8 +365,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { if (lastPrepareDataIndex == prefixIndex) { analysisCell.getPrepareDataList().add(StringUtils.EMPTY); } else { - analysisCell.getPrepareDataList() - .add(convertPrepareData(value.substring(lastPrepareDataIndex, prefixIndex))); + String data = convertPrepareData(value.substring(lastPrepareDataIndex, prefixIndex)); + preparedData.append(data); + analysisCell.getPrepareDataList().add(data); analysisCell.setOnlyOneVariable(Boolean.FALSE); } lastPrepareDataIndex = suffixIndex + 1; @@ -372,9 +384,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { } else { collectionAnalysisCellList.add(analysisCell); } - return true; + return preparedData.toString(); } - return false; + return null; } private AnalysisCell initAnalysisCell(Integer rowIndex, Integer columnIndex) { diff --git a/src/main/java/com/alibaba/excel/write/metadata/WriteBasicParameter.java b/src/main/java/com/alibaba/excel/write/metadata/WriteBasicParameter.java index 2689cd98..61115aff 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/WriteBasicParameter.java +++ b/src/main/java/com/alibaba/excel/write/metadata/WriteBasicParameter.java @@ -1,6 +1,7 @@ package com.alibaba.excel.write.metadata; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import com.alibaba.excel.metadata.BasicParameter; @@ -28,6 +29,22 @@ public class WriteBasicParameter extends BasicParameter { * Use the default style.Default is true. */ private Boolean useDefaultStyle; + /** + * Ignore the custom columns. + */ + private Collection excludeColumnIndexes; + /** + * Ignore the custom columns. + */ + private Collection excludeColumnFiledNames; + /** + * Only output the custom columns. + */ + private Collection includeColumnIndexes; + /** + * Only output the custom columns. + */ + private Collection includeColumnFiledNames; public Integer getRelativeHeadRowIndex() { return relativeHeadRowIndex; @@ -60,4 +77,36 @@ public class WriteBasicParameter extends BasicParameter { public void setUseDefaultStyle(Boolean useDefaultStyle) { this.useDefaultStyle = useDefaultStyle; } + + public Collection getExcludeColumnIndexes() { + return excludeColumnIndexes; + } + + public void setExcludeColumnIndexes(Collection excludeColumnIndexes) { + this.excludeColumnIndexes = excludeColumnIndexes; + } + + public Collection getExcludeColumnFiledNames() { + return excludeColumnFiledNames; + } + + public void setExcludeColumnFiledNames(Collection excludeColumnFiledNames) { + this.excludeColumnFiledNames = excludeColumnFiledNames; + } + + public Collection getIncludeColumnIndexes() { + return includeColumnIndexes; + } + + public void setIncludeColumnIndexes(Collection includeColumnIndexes) { + this.includeColumnIndexes = includeColumnIndexes; + } + + public Collection getIncludeColumnFiledNames() { + return includeColumnFiledNames; + } + + public void setIncludeColumnFiledNames(Collection includeColumnFiledNames) { + this.includeColumnFiledNames = includeColumnFiledNames; + } } diff --git a/src/main/java/com/alibaba/excel/write/metadata/WriteWorkbook.java b/src/main/java/com/alibaba/excel/write/metadata/WriteWorkbook.java index 7d9ebcd6..738299af 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/WriteWorkbook.java +++ b/src/main/java/com/alibaba/excel/write/metadata/WriteWorkbook.java @@ -43,7 +43,7 @@ public class WriteWorkbook extends WriteBasicParameter { */ private File templateFile; /** - * Default trueuseDefaultStyle + * Default true. */ private Boolean autoCloseStream; /** @@ -57,6 +57,12 @@ public class WriteWorkbook extends WriteBasicParameter { * */ private String password; + /** + * Write excel in memory. Default false,the cache file is created and finally written to excel. + *

+ * Comment and RichTextString are only supported in memory mode. + */ + private Boolean inMemory; /** * The default is all excel objects.Default is true. *

@@ -155,4 +161,12 @@ public class WriteWorkbook extends WriteBasicParameter { public void setPassword(String password) { this.password = password; } + + public Boolean getInMemory() { + return inMemory; + } + + public void setInMemory(Boolean inMemory) { + this.inMemory = inMemory; + } } 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 72f5f9be..b28f267b 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 @@ -1,6 +1,7 @@ package com.alibaba.excel.write.metadata.holder; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -65,6 +66,22 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ * Use the default style.Default is true. */ private Boolean useDefaultStyle; + /** + * Ignore the custom columns. + */ + private Collection excludeColumnIndexes; + /** + * Ignore the custom columns. + */ + private Collection excludeColumnFiledNames; + /** + * Only output the custom columns. + */ + private Collection includeColumnIndexes; + /** + * Only output the custom columns. + */ + private Collection includeColumnFiledNames; public AbstractWriteHolder(WriteBasicParameter writeBasicParameter, AbstractWriteHolder parentAbstractWriteHolder, Boolean convertAllFiled) { @@ -110,8 +127,29 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ this.useDefaultStyle = writeBasicParameter.getUseDefaultStyle(); } + if (writeBasicParameter.getExcludeColumnFiledNames() == null && parentAbstractWriteHolder != null) { + this.excludeColumnFiledNames = parentAbstractWriteHolder.getExcludeColumnFiledNames(); + } else { + this.excludeColumnFiledNames = writeBasicParameter.getExcludeColumnFiledNames(); + } + if (writeBasicParameter.getExcludeColumnIndexes() == null && parentAbstractWriteHolder != null) { + this.excludeColumnIndexes = parentAbstractWriteHolder.getExcludeColumnIndexes(); + } else { + this.excludeColumnIndexes = writeBasicParameter.getExcludeColumnIndexes(); + } + if (writeBasicParameter.getIncludeColumnFiledNames() == null && parentAbstractWriteHolder != null) { + this.includeColumnFiledNames = parentAbstractWriteHolder.getIncludeColumnFiledNames(); + } else { + this.includeColumnFiledNames = writeBasicParameter.getIncludeColumnFiledNames(); + } + if (writeBasicParameter.getIncludeColumnIndexes() == null && parentAbstractWriteHolder != null) { + this.includeColumnIndexes = parentAbstractWriteHolder.getIncludeColumnIndexes(); + } else { + this.includeColumnIndexes = writeBasicParameter.getIncludeColumnIndexes(); + } + // Initialization property - this.excelWriteHeadProperty = new ExcelWriteHeadProperty(getClazz(), getHead(), convertAllFiled); + this.excelWriteHeadProperty = new ExcelWriteHeadProperty(this, getClazz(), getHead(), convertAllFiled); // Compatible with old code compatibleOldCode(writeBasicParameter); @@ -148,7 +186,6 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ getConverterMap().put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter); } } - } /** @@ -343,6 +380,27 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ return result; } + @Override + public boolean ignore(String fieldName, Integer columnIndex) { + if (fieldName != null) { + if (includeColumnFiledNames != null && !includeColumnFiledNames.contains(fieldName)) { + return true; + } + if (excludeColumnFiledNames != null && excludeColumnFiledNames.contains(fieldName)) { + return true; + } + } + if (columnIndex != null) { + if (includeColumnIndexes != null && !includeColumnIndexes.contains(columnIndex)) { + return true; + } + if (excludeColumnIndexes != null && excludeColumnIndexes.contains(columnIndex)) { + return true; + } + } + return false; + } + public Boolean getNeedHead() { return needHead; } @@ -383,6 +441,38 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ this.useDefaultStyle = useDefaultStyle; } + public Collection getExcludeColumnIndexes() { + return excludeColumnIndexes; + } + + public void setExcludeColumnIndexes(Collection excludeColumnIndexes) { + this.excludeColumnIndexes = excludeColumnIndexes; + } + + public Collection getExcludeColumnFiledNames() { + return excludeColumnFiledNames; + } + + public void setExcludeColumnFiledNames(Collection excludeColumnFiledNames) { + this.excludeColumnFiledNames = excludeColumnFiledNames; + } + + public Collection getIncludeColumnIndexes() { + return includeColumnIndexes; + } + + public void setIncludeColumnIndexes(Collection includeColumnIndexes) { + this.includeColumnIndexes = includeColumnIndexes; + } + + public Collection getIncludeColumnFiledNames() { + return includeColumnFiledNames; + } + + public void setIncludeColumnFiledNames(Collection includeColumnFiledNames) { + this.includeColumnFiledNames = includeColumnFiledNames; + } + @Override public ExcelWriteHeadProperty excelWriteHeadProperty() { return getExcelWriteHeadProperty(); diff --git a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteHolder.java index 53c11dba..8f2ae7e2 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteHolder.java +++ b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteHolder.java @@ -28,6 +28,15 @@ public interface WriteHolder extends ConfigurationHolder { */ Map, List> writeHandlerMap(); + /** + * Is to determine if a field needs to be ignored + * + * @param fieldName + * @param columnIndex + * @return + */ + boolean ignore(String fieldName, Integer columnIndex); + /** * Whether a header is required for the currently operated cell * 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 7614489f..4de6ade6 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 @@ -97,6 +97,12 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { * Whether the encryption */ private String password; + /** + * Write excel in memory. Default false,the cache file is created and finally written to excel. + *

+ * Comment and RichTextString are only supported in memory mode. + */ + private Boolean inMemory; public WriteWorkbookHolder(WriteWorkbook writeWorkbook) { super(writeWorkbook, null, writeWorkbook.getConvertAllFiled()); @@ -137,6 +143,11 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { } this.hasBeenInitializedSheet = new HashMap(); this.password = writeWorkbook.getPassword(); + if (writeWorkbook.getInMemory() == null) { + this.inMemory = Boolean.FALSE; + } else { + this.inMemory = writeWorkbook.getInMemory(); + } } private void copyTemplate() throws IOException { @@ -262,6 +273,14 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { this.password = password; } + public Boolean getInMemory() { + return inMemory; + } + + public void setInMemory(Boolean inMemory) { + this.inMemory = inMemory; + } + @Override public HolderEnum holderType() { return HolderEnum.WORKBOOK; 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 fbd33c4e..b1ba891e 100644 --- a/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java +++ b/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java @@ -17,6 +17,7 @@ import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.metadata.CellRange; import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.Holder; import com.alibaba.excel.metadata.property.ColumnWidthProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelHeadProperty; @@ -31,8 +32,8 @@ public class ExcelWriteHeadProperty extends ExcelHeadProperty { private RowHeightProperty headRowHeightProperty; private RowHeightProperty contentRowHeightProperty; - public ExcelWriteHeadProperty(Class headClazz, List> head, Boolean convertAllFiled) { - super(headClazz, head, convertAllFiled); + public ExcelWriteHeadProperty(Holder holder, Class headClazz, List> head, Boolean convertAllFiled) { + super(holder, headClazz, head, convertAllFiled); if (getHeadKind() != HeadKindEnum.CLASS) { return; } diff --git a/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java index 006927f9..463fea00 100644 --- a/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java @@ -21,7 +21,7 @@ import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; */ public class LongestMatchColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy { - private static final int MAX_COLUMN_WIDTH = 256; + private static final int MAX_COLUMN_WIDTH = 255; private static final Map> CACHE = new HashMap>(8); diff --git a/src/test/java/com/alibaba/easyexcel/test/core/fill/FillData.java b/src/test/java/com/alibaba/easyexcel/test/core/fill/FillData.java index 13dfa17a..dcdf23f7 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/fill/FillData.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/fill/FillData.java @@ -15,4 +15,5 @@ public class FillData { @NumberFormat("#") @ExcelProperty(converter = DoubleStringConverter.class) private double number; + private String empty; } 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 2582f105..ff30ae26 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 @@ -4,7 +4,9 @@ import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.IndexedColors; @@ -62,6 +64,35 @@ public class WriteTest { excelWriter.finish(); } + /** + * 根据参数只导出指定列 + *

+ * 1. 创建excel对应的实体对象 参照{@link DemoData} + *

+ * 2. 根据自己或者排除自己需要的列 + *

+ * 3. 直接写即可 + */ + @Test + public void excludeOrIncludeWrite() { + String fileName = TestFileUtil.getPath() + "excludeOrIncludeWrite" + System.currentTimeMillis() + ".xlsx"; + + // 根据用户传入字段 假设我们要忽略 date + Set excludeColumnFiledNames = new HashSet(); + excludeColumnFiledNames.add("date"); + // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + EasyExcel.write(fileName, DemoData.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet("模板") + .doWrite(data()); + + fileName = TestFileUtil.getPath() + "excludeOrIncludeWrite" + System.currentTimeMillis() + ".xlsx"; + // 根据用户传入字段 假设我们只要导出 date + Set includeColumnFiledNames = new HashSet(); + includeColumnFiledNames.add("date"); + // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + EasyExcel.write(fileName, DemoData.class).includeColumnFiledNames(includeColumnFiledNames).sheet("模板") + .doWrite(data()); + } + /** * 指定写入的列 *

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 49240d1b..698dc063 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 @@ -19,6 +19,7 @@ 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.style.row.SimpleRowHeightStyleStrategy; import com.alibaba.fastjson.JSON; import net.sf.cglib.beans.BeanMap; @@ -49,7 +50,8 @@ 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) + .registerWriteHandler(new SimpleRowHeightStyleStrategy((short)150, (short)120)).sheet("模板").doWrite(data()); } private List> head() { diff --git a/src/test/resources/fill/simple.xls b/src/test/resources/fill/simple.xls index ea66e944..317ef6de 100644 Binary files a/src/test/resources/fill/simple.xls and b/src/test/resources/fill/simple.xls differ diff --git a/src/test/resources/fill/simple.xlsx b/src/test/resources/fill/simple.xlsx index be1753cb..a441eba8 100644 Binary files a/src/test/resources/fill/simple.xlsx and b/src/test/resources/fill/simple.xlsx differ diff --git a/update.md b/update.md index d2c0cbb0..1eb3717e 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,11 @@ +# 2.1.0-beta3 +* 支持强行指定在内存处理,以支持备注、RichTextString等的写入 +* 修复关闭流失败,可能会不删除临时文件的问题 +* 支持根据参数自定义导出列 +* 修改最长匹配策略的最大长度 [Issue #734](https://github.com/alibaba/easyexcel/issues/734) +* 修复策略头未生效的bug [Issue #735](https://github.com/alibaba/easyexcel/issues/735) +* 修复填充的时候有数字会异常 + # 2.1.0-beta2 * 修改模板通过流创建报错的bug * 修复空数据未替换掉的bug