Browse Source

修改测试bug

2.1.x
Jiaju Zhuang 4 years ago
parent
commit
f99c198df7
  1. 3
      src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java
  2. 12
      src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
  3. 6
      src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java
  4. 2
      src/main/java/com/alibaba/excel/analysis/v03/handlers/DummyRecordHandler.java
  5. 7
      src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java
  6. 19
      src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java
  7. 2
      src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java
  8. 10
      src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
  9. 67
      src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java
  10. 149
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java
  11. 19
      src/main/java/com/alibaba/excel/write/metadata/fill/AnalysisCell.java
  12. 44
      src/main/java/com/alibaba/excel/write/metadata/fill/FillWrapper.java
  13. 10
      src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatTest.java
  14. 44
      src/test/java/com/alibaba/easyexcel/test/core/fill/FillDataTest.java
  15. 8
      src/test/java/com/alibaba/easyexcel/test/core/head/ListHeadDataListener.java
  16. 33
      src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java
  17. 22
      src/test/java/com/alibaba/easyexcel/test/temp/FillTempTest.java
  18. 15
      src/test/java/com/alibaba/easyexcel/test/temp/TempFillData.java
  19. 4
      src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java
  20. BIN
      src/test/resources/demo/fill/composite.xlsx
  21. BIN
      src/test/resources/fill/composite.xls
  22. BIN
      src/test/resources/fill/composite.xlsx
  23. 2
      update.md

3
src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java

@ -59,8 +59,7 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
} }
private void choiceExcelExecutor(ReadWorkbook readWorkbook) throws Exception { private void choiceExcelExecutor(ReadWorkbook readWorkbook) throws Exception {
ExcelTypeEnum excelType = ExcelTypeEnum excelType = ExcelTypeEnum.valueOf(readWorkbook);
ExcelTypeEnum.valueOf(readWorkbook.getFile(), readWorkbook.getInputStream(), readWorkbook.getExcelType());
switch (excelType) { switch (excelType) {
case XLS: case XLS:
POIFSFileSystem poifsFileSystem; POIFSFileSystem poifsFileSystem;

12
src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java

@ -56,6 +56,7 @@ import com.alibaba.excel.analysis.v03.handlers.StringRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.TextObjectRecordHandler; import com.alibaba.excel.analysis.v03.handlers.TextObjectRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelAnalysisStopException;
import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder; import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder;
@ -108,9 +109,14 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor {
@Override @Override
public List<ReadSheet> sheetList() { public List<ReadSheet> sheetList() {
if (xlsReadContext.readWorkbookHolder().getActualSheetDataList() == null) { try {
LOGGER.warn("Getting the 'sheetList' before reading will cause the file to be read twice."); if (xlsReadContext.readWorkbookHolder().getActualSheetDataList() == null) {
new XlsListSheetListener(xlsReadContext).execute(); new XlsListSheetListener(xlsReadContext).execute();
}
} catch (ExcelAnalysisStopException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Custom stop!");
}
} }
return xlsReadContext.readWorkbookHolder().getActualSheetDataList(); return xlsReadContext.readWorkbookHolder().getActualSheetDataList();
} }

6
src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java

@ -23,10 +23,14 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
@Override @Override
public void processRecord(XlsReadContext xlsReadContext, Record record) { 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);
return;
}
if (br.getType() != BOFRecord.TYPE_WORKSHEET) { if (br.getType() != BOFRecord.TYPE_WORKSHEET) {
return; return;
} }
XlsReadWorkbookHolder xlsReadWorkbookHolder = xlsReadContext.xlsReadWorkbookHolder();
// Init read sheet Data // Init read sheet Data
initReadSheetDataList(xlsReadWorkbookHolder); initReadSheetDataList(xlsReadWorkbookHolder);
Integer readSheetIndex = xlsReadWorkbookHolder.getReadSheetIndex(); Integer readSheetIndex = xlsReadWorkbookHolder.getReadSheetIndex();

2
src/main/java/com/alibaba/excel/analysis/v03/handlers/DummyRecordHandler.java

@ -8,6 +8,7 @@ import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.RowTypeEnum;
import com.alibaba.excel.metadata.Cell; import com.alibaba.excel.metadata.Cell;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder; import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
@ -30,6 +31,7 @@ public class DummyRecordHandler extends AbstractXlsRecordHandler implements Igno
xlsReadContext.readSheetHolder().getGlobalConfiguration(), xlsReadSheetHolder.getCellMap())); xlsReadContext.readSheetHolder().getGlobalConfiguration(), xlsReadSheetHolder.getCellMap()));
xlsReadContext.analysisEventProcessor().endRow(xlsReadContext); xlsReadContext.analysisEventProcessor().endRow(xlsReadContext);
xlsReadSheetHolder.setCellMap(new LinkedHashMap<Integer, Cell>()); xlsReadSheetHolder.setCellMap(new LinkedHashMap<Integer, Cell>());
xlsReadSheetHolder.setTempRowType(RowTypeEnum.EMPTY);
} else if (record instanceof MissingCellDummyRecord) { } else if (record instanceof MissingCellDummyRecord) {
MissingCellDummyRecord mcdr = (MissingCellDummyRecord)record; MissingCellDummyRecord mcdr = (MissingCellDummyRecord)record;
xlsReadSheetHolder.getCellMap().put(mcdr.getColumn(), xlsReadSheetHolder.getCellMap().put(mcdr.getColumn(),

7
src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java

@ -11,6 +11,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Cell; import com.alibaba.excel.metadata.Cell;
@ -52,6 +53,12 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler implements Ig
case NUMERIC: case NUMERIC:
tempCellData.setType(CellDataTypeEnum.NUMBER); tempCellData.setType(CellDataTypeEnum.NUMBER);
tempCellData.setNumberValue(BigDecimal.valueOf(frec.getValue())); tempCellData.setNumberValue(BigDecimal.valueOf(frec.getValue()));
Integer dataFormat =
xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(frec);
tempCellData.setDataFormat(dataFormat);
tempCellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat,
xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatString(frec),
xlsReadContext.readSheetHolder().getGlobalConfiguration().getLocale()));
cellMap.put((int)frec.getColumn(), tempCellData); cellMap.put((int)frec.getColumn(), tempCellData);
break; break;
case ERROR: case ERROR:

19
src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java

@ -20,14 +20,25 @@ public class RowTagHandler extends AbstractXlsxTagHandler {
@Override @Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) { public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
xlsxReadContext.readRowHolder( int rowIndex = PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_R));
new ReadRowHolder(PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_R)), Integer lastIndex = xlsxReadContext.readSheetHolder().getRowIndex();
RowTypeEnum.DATA, xlsxReadContext.readSheetHolder().getGlobalConfiguration(), null)); if (lastIndex != null) {
while (lastIndex + 1 < rowIndex) {
xlsxReadContext.readRowHolder(new ReadRowHolder(lastIndex + 1, RowTypeEnum.EMPTY,
xlsxReadContext.readSheetHolder().getGlobalConfiguration(), new LinkedHashMap<Integer, Cell>()));
xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext);
xlsxReadContext.xlsxReadSheetHolder().setCellMap(new LinkedHashMap<Integer, Cell>());
lastIndex++;
}
}
xlsxReadContext.readSheetHolder().setRowIndex(rowIndex);
} }
@Override @Override
public void endElement(XlsxReadContext xlsxReadContext, String name) { public void endElement(XlsxReadContext xlsxReadContext, String name) {
xlsxReadContext.readRowHolder().setCellMap(xlsxReadContext.xlsxReadSheetHolder().getCellMap()); xlsxReadContext.readRowHolder(new ReadRowHolder(xlsxReadContext.readSheetHolder().getRowIndex(),
RowTypeEnum.DATA, xlsxReadContext.readSheetHolder().getGlobalConfiguration(),
xlsxReadContext.xlsxReadSheetHolder().getCellMap()));
xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext); xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext);
xlsxReadContext.xlsxReadSheetHolder().setCellMap(new LinkedHashMap<Integer, Cell>()); xlsxReadContext.xlsxReadSheetHolder().setCellMap(new LinkedHashMap<Integer, Cell>());
} }

2
src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java

@ -205,9 +205,9 @@ public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder<Exce
* @return * @return
*/ */
public <T> List<T> doReadAllSync() { public <T> List<T> doReadAllSync() {
ExcelReader excelReader = build();
SyncReadListener syncReadListener = new SyncReadListener(); SyncReadListener syncReadListener = new SyncReadListener();
registerReadListener(syncReadListener); registerReadListener(syncReadListener);
ExcelReader excelReader = build();
excelReader.readAll(); excelReader.readAll();
excelReader.finish(); excelReader.finish();
return (List<T>)syncReadListener.getList(); return (List<T>)syncReadListener.getList();

10
src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java

@ -1,6 +1,5 @@
package com.alibaba.excel.read.metadata.holder; package com.alibaba.excel.read.metadata.holder;
import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashSet; import java.util.HashSet;
@ -126,16 +125,9 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
super(readWorkbook, null, readWorkbook.getConvertAllFiled()); super(readWorkbook, null, readWorkbook.getConvertAllFiled());
this.readWorkbook = readWorkbook; this.readWorkbook = readWorkbook;
if (readWorkbook.getInputStream() != null) { if (readWorkbook.getInputStream() != null) {
if (readWorkbook.getInputStream().markSupported()) { this.inputStream = readWorkbook.getInputStream();
this.inputStream = readWorkbook.getInputStream();
} else {
this.inputStream = new BufferedInputStream(readWorkbook.getInputStream());
}
} }
this.file = readWorkbook.getFile(); this.file = readWorkbook.getFile();
if (file == null && inputStream == null) {
throw new ExcelAnalysisException("File and inputStream must be a non-null.");
}
if (readWorkbook.getMandatoryUseInputStream() == null) { if (readWorkbook.getMandatoryUseInputStream() == null) {
this.mandatoryUseInputStream = Boolean.FALSE; this.mandatoryUseInputStream = Boolean.FALSE;
} else { } else {

67
src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java

@ -3,12 +3,13 @@ package com.alibaba.excel.support;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.apache.poi.poifs.filesystem.FileMagic; import org.apache.poi.poifs.filesystem.FileMagic;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelCommonException; import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.read.metadata.ReadWorkbook;
/** /**
* @author jipengfei * @author jipengfei
@ -29,44 +30,56 @@ public enum ExcelTypeEnum {
this.setValue(value); this.setValue(value);
} }
public static ExcelTypeEnum valueOf(File file, InputStream inputStream, ExcelTypeEnum excelType) { public static ExcelTypeEnum valueOf(ReadWorkbook readWorkbook) {
ExcelTypeEnum excelType = readWorkbook.getExcelType();
if (excelType != null) {
return excelType;
}
File file = readWorkbook.getFile();
InputStream inputStream = readWorkbook.getInputStream();
if (file == null && inputStream == null) {
throw new ExcelAnalysisException("File and inputStream must be a non-null.");
}
try { try {
FileMagic fileMagic;
if (file != null) { if (file != null) {
if (!file.exists()) {
throw new ExcelAnalysisException("File " + file.getAbsolutePath() + " not exists.");
}
String fileName = file.getName();
if (fileName.endsWith(XLSX.getValue())) {
return XLSX;
} else if (fileName.endsWith(XLS.getValue())) {
return XLS;
}
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file)); BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
try { try {
fileMagic = FileMagic.valueOf(bufferedInputStream); return recognitionExcelType(bufferedInputStream);
} finally { } finally {
bufferedInputStream.close(); bufferedInputStream.close();
} }
if (!FileMagic.OLE2.equals(fileMagic) && !FileMagic.OOXML.equals(fileMagic)) {
String fileName = file.getName();
if (fileName.endsWith(XLSX.getValue())) {
return XLSX;
} else if (fileName.endsWith(XLS.getValue())) {
return XLS;
} else {
throw new ExcelCommonException("Unknown excel type.");
}
}
} else {
fileMagic = FileMagic.valueOf(inputStream);
} }
if (FileMagic.OLE2.equals(fileMagic)) { if (!inputStream.markSupported()) {
return XLS; inputStream = new BufferedInputStream(inputStream);
} readWorkbook.setInputStream(inputStream);
if (FileMagic.OOXML.equals(fileMagic)) {
return XLSX;
}
} catch (IOException e) {
if (excelType != null) {
return excelType;
} }
return recognitionExcelType(inputStream);
} catch (ExcelCommonException e) {
throw e;
} catch (ExcelAnalysisException e) {
throw e;
} catch (Exception e) {
throw new ExcelCommonException( throw new ExcelCommonException(
"Convert excel format exception.You can try specifying the 'excelType' yourself", e); "Convert excel format exception.You can try specifying the 'excelType' yourself", e);
} }
if (excelType != null) { }
return excelType;
private static ExcelTypeEnum recognitionExcelType(InputStream inputStream) throws Exception {
FileMagic fileMagic = FileMagic.valueOf(inputStream);
if (FileMagic.OLE2.equals(fileMagic)) {
return XLS;
}
if (FileMagic.OOXML.equals(fileMagic)) {
return XLSX;
} }
throw new ExcelCommonException( throw new ExcelCommonException(
"Convert excel format exception.You can try specifying the 'excelType' yourself"); "Convert excel format exception.You can try specifying the 'excelType' yourself");

149
src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java

@ -27,6 +27,7 @@ import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.util.WriteHandlerUtils; import com.alibaba.excel.util.WriteHandlerUtils;
import com.alibaba.excel.write.metadata.fill.AnalysisCell; import com.alibaba.excel.write.metadata.fill.AnalysisCell;
import com.alibaba.excel.write.metadata.fill.FillConfig; import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import net.sf.cglib.beans.BeanMap; import net.sf.cglib.beans.BeanMap;
@ -47,28 +48,36 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
/** /**
* Fields to replace in the template * Fields to replace in the template
*/ */
private Map<Integer, List<AnalysisCell>> templateAnalysisCache = new HashMap<Integer, List<AnalysisCell>>(8); private Map<String, List<AnalysisCell>> templateAnalysisCache = new HashMap<String, List<AnalysisCell>>(8);
/** /**
* Collection fields to replace in the template * Collection fields to replace in the template
*/ */
private Map<Integer, List<AnalysisCell>> templateCollectionAnalysisCache = private Map<String, List<AnalysisCell>> templateCollectionAnalysisCache =
new HashMap<Integer, List<AnalysisCell>>(8); new HashMap<String, List<AnalysisCell>>(8);
/** /**
* Style cache for collection fields * Style cache for collection fields
*/ */
private Map<Integer, Map<AnalysisCell, CellStyle>> collectionFieldStyleCache = private Map<String, Map<AnalysisCell, CellStyle>> collectionFieldStyleCache =
new HashMap<Integer, Map<AnalysisCell, CellStyle>>(8); new HashMap<String, Map<AnalysisCell, CellStyle>>(8);
/** /**
* Row height cache for collection * Row height cache for collection
*/ */
private Map<Integer, Short> collectionRowHeightCache = new HashMap<Integer, Short>(8); private Map<String, Short> collectionRowHeightCache = new HashMap<String, Short>(8);
/** /**
* Last index cache for collection fields * Last index cache for collection fields
*/ */
private Map<Integer, Map<AnalysisCell, Integer>> collectionLastIndexCache = private Map<String, Map<AnalysisCell, Integer>> collectionLastIndexCache =
new HashMap<Integer, Map<AnalysisCell, Integer>>(8); new HashMap<String, Map<AnalysisCell, Integer>>(8);
private Map<Integer, Integer> relativeRowIndexMap = new HashMap<Integer, Integer>(8); private Map<String, Integer> relativeRowIndexMap = new HashMap<String, Integer>(8);
/**
* The data prefix that is populated this time
*/
private String currentDataPrefix;
/**
* The unique data encoding for this fill
*/
private String currentUniqueDataFlag;
public ExcelWriteFillExecutor(WriteContext writeContext) { public ExcelWriteFillExecutor(WriteContext writeContext) {
super(writeContext); super(writeContext);
@ -79,9 +88,22 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
fillConfig = FillConfig.builder().build(true); fillConfig = FillConfig.builder().build(true);
} }
fillConfig.init(); fillConfig.init();
if (data instanceof Collection) {
Object realData;
if (data instanceof FillWrapper) {
FillWrapper fillWrapper = (FillWrapper)data;
currentDataPrefix = fillWrapper.getName();
realData = fillWrapper.getCollectionData();
} else {
realData = data;
currentDataPrefix = null;
}
currentUniqueDataFlag = uniqueDataFlag(writeContext.writeSheetHolder().getSheetNo(), currentDataPrefix);
// processing data
if (realData instanceof Collection) {
List<AnalysisCell> analysisCellList = readTemplateData(templateCollectionAnalysisCache); List<AnalysisCell> analysisCellList = readTemplateData(templateCollectionAnalysisCache);
Collection collectionData = (Collection)data; Collection collectionData = (Collection)realData;
if (CollectionUtils.isEmpty(collectionData)) { if (CollectionUtils.isEmpty(collectionData)) {
return; return;
} }
@ -93,7 +115,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
doFill(analysisCellList, iterator.next(), fillConfig, getRelativeRowIndex()); doFill(analysisCellList, iterator.next(), fillConfig, getRelativeRowIndex());
} }
} else { } else {
doFill(readTemplateData(templateAnalysisCache), data, fillConfig, null); doFill(readTemplateData(templateAnalysisCache), realData, fillConfig, null);
} }
} }
@ -102,8 +124,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
return; return;
} }
int maxRowIndex = 0; int maxRowIndex = 0;
Integer sheetNo = writeContext.writeSheetHolder().getSheetNo(); Map<AnalysisCell, Integer> collectionLastIndexMap = collectionLastIndexCache.get(currentUniqueDataFlag);
Map<AnalysisCell, Integer> collectionLastIndexMap = collectionLastIndexCache.get(sheetNo);
for (AnalysisCell analysisCell : analysisCellList) { for (AnalysisCell analysisCell : analysisCellList) {
if (collectionLastIndexMap != null) { if (collectionLastIndexMap != null) {
Integer lastRowIndex = collectionLastIndexMap.get(analysisCell); Integer lastRowIndex = collectionLastIndexMap.get(analysisCell);
@ -132,7 +153,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
return; return;
} }
sheet.shiftRows(maxRowIndex + 1, lastRowIndex, number, true, false); sheet.shiftRows(maxRowIndex + 1, lastRowIndex, number, true, false);
for (AnalysisCell analysisCell : templateAnalysisCache.get(writeContext.writeSheetHolder().getSheetNo())) { for (AnalysisCell analysisCell : templateAnalysisCache.get(currentUniqueDataFlag)) {
if (analysisCell.getRowIndex() > maxRowIndex) { if (analysisCell.getRowIndex() > maxRowIndex) {
analysisCell.setRowIndex(analysisCell.getRowIndex() + number); analysisCell.setRowIndex(analysisCell.getRowIndex() + number);
} }
@ -206,14 +227,13 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
} }
private Integer getRelativeRowIndex() { private Integer getRelativeRowIndex() {
Integer sheetNo = writeContext.writeSheetHolder().getSheetNo(); Integer relativeRowIndex = relativeRowIndexMap.get(currentUniqueDataFlag);
Integer relativeRowIndex = relativeRowIndexMap.get(sheetNo);
if (relativeRowIndex == null) { if (relativeRowIndex == null) {
relativeRowIndex = 0; relativeRowIndex = 0;
} else { } else {
relativeRowIndex++; relativeRowIndex++;
} }
relativeRowIndexMap.put(sheetNo, relativeRowIndex); relativeRowIndexMap.put(currentUniqueDataFlag, relativeRowIndex);
return relativeRowIndex; return relativeRowIndex;
} }
@ -222,13 +242,12 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) { if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) {
return cachedSheet.getRow(analysisCell.getRowIndex()).getCell(analysisCell.getColumnIndex()); return cachedSheet.getRow(analysisCell.getRowIndex()).getCell(analysisCell.getColumnIndex());
} }
Integer sheetNo = writeContext.writeSheetHolder().getSheetNo();
Sheet sheet = writeContext.writeSheetHolder().getSheet(); Sheet sheet = writeContext.writeSheetHolder().getSheet();
Map<AnalysisCell, Integer> collectionLastIndexMap = collectionLastIndexCache.get(sheetNo); Map<AnalysisCell, Integer> collectionLastIndexMap = collectionLastIndexCache.get(currentUniqueDataFlag);
if (collectionLastIndexMap == null) { if (collectionLastIndexMap == null) {
collectionLastIndexMap = new HashMap<AnalysisCell, Integer>(16); collectionLastIndexMap = new HashMap<AnalysisCell, Integer>(16);
collectionLastIndexCache.put(sheetNo, collectionLastIndexMap); collectionLastIndexCache.put(currentUniqueDataFlag, collectionLastIndexMap);
} }
boolean isOriginalCell = false; boolean isOriginalCell = false;
Integer lastRowIndex; Integer lastRowIndex;
@ -269,10 +288,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
} else { } else {
row = sheet.createRow(lastRowIndex); row = sheet.createRow(lastRowIndex);
} }
checkRowHeight(analysisCell, fillConfig, isOriginalCell, row, sheetNo); checkRowHeight(analysisCell, fillConfig, isOriginalCell, row);
WriteHandlerUtils.afterRowCreate(writeContext, row, null, Boolean.FALSE); WriteHandlerUtils.afterRowCreate(writeContext, row, null, Boolean.FALSE);
} else { } else {
checkRowHeight(analysisCell, fillConfig, isOriginalCell, row, sheetNo); checkRowHeight(analysisCell, fillConfig, isOriginalCell, row);
} }
} }
Cell cell = row.getCell(lastColumnIndex); Cell cell = row.getCell(lastColumnIndex);
@ -282,10 +301,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
WriteHandlerUtils.afterCellCreate(writeContext, cell, null, null, Boolean.FALSE); WriteHandlerUtils.afterCellCreate(writeContext, cell, null, null, Boolean.FALSE);
} }
Map<AnalysisCell, CellStyle> collectionFieldStyleMap = collectionFieldStyleCache.get(sheetNo); Map<AnalysisCell, CellStyle> collectionFieldStyleMap = collectionFieldStyleCache.get(currentUniqueDataFlag);
if (collectionFieldStyleMap == null) { if (collectionFieldStyleMap == null) {
collectionFieldStyleMap = new HashMap<AnalysisCell, CellStyle>(16); collectionFieldStyleMap = new HashMap<AnalysisCell, CellStyle>(16);
collectionFieldStyleCache.put(sheetNo, collectionFieldStyleMap); collectionFieldStyleCache.put(currentUniqueDataFlag, collectionFieldStyleMap);
} }
if (isOriginalCell) { if (isOriginalCell) {
collectionFieldStyleMap.put(analysisCell, cell.getCellStyle()); collectionFieldStyleMap.put(analysisCell, cell.getCellStyle());
@ -298,31 +317,27 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
return cell; return cell;
} }
private void checkRowHeight(AnalysisCell analysisCell, FillConfig fillConfig, boolean isOriginalCell, Row row, private void checkRowHeight(AnalysisCell analysisCell, FillConfig fillConfig, boolean isOriginalCell, Row row) {
Integer sheetNo) { if (!analysisCell.getFirstRow() || !WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection())) {
if (!analysisCell.getFirstColumn() || !WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection())) {
return; return;
} }
if (isOriginalCell) { if (isOriginalCell) {
collectionRowHeightCache.put(sheetNo, row.getHeight()); collectionRowHeightCache.put(currentUniqueDataFlag, row.getHeight());
return; return;
} }
Short rowHeight = collectionRowHeightCache.get(sheetNo); Short rowHeight = collectionRowHeightCache.get(currentUniqueDataFlag);
if (rowHeight != null) { if (rowHeight != null) {
row.setHeight(rowHeight); row.setHeight(rowHeight);
} }
} }
private List<AnalysisCell> readTemplateData(Map<Integer, List<AnalysisCell>> analysisCache) { private List<AnalysisCell> readTemplateData(Map<String, List<AnalysisCell>> analysisCache) {
Integer sheetNo = writeContext.writeSheetHolder().getSheetNo(); List<AnalysisCell> analysisCellList = analysisCache.get(currentUniqueDataFlag);
List<AnalysisCell> analysisCellList = analysisCache.get(sheetNo);
if (analysisCellList != null) { if (analysisCellList != null) {
return analysisCellList; return analysisCellList;
} }
Sheet sheet = writeContext.writeSheetHolder().getCachedSheet(); Sheet sheet = writeContext.writeSheetHolder().getCachedSheet();
analysisCellList = new ArrayList<AnalysisCell>(); Map<String, Set<Integer>> firstRowCache = new HashMap<String, Set<Integer>>(8);
List<AnalysisCell> collectionAnalysisCellList = new ArrayList<AnalysisCell>();
Set<Integer> firstColumnCache = new HashSet<Integer>();
for (int i = 0; i <= sheet.getLastRowNum(); i++) { for (int i = 0; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i); Row row = sheet.getRow(i);
if (row == null) { if (row == null) {
@ -333,32 +348,26 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
if (cell == null) { if (cell == null) {
continue; continue;
} }
String preparedData = String preparedData = prepareData(cell, i, j, firstRowCache);
prepareData(cell, analysisCellList, collectionAnalysisCellList, i, j, firstColumnCache);
// Prevent empty data from not being replaced // Prevent empty data from not being replaced
if (preparedData != null) { if (preparedData != null) {
cell.setCellValue(preparedData); cell.setCellValue(preparedData);
} }
} }
} }
templateAnalysisCache.put(sheetNo, analysisCellList); return analysisCache.get(currentUniqueDataFlag);
templateCollectionAnalysisCache.put(sheetNo, collectionAnalysisCellList);
return analysisCache.get(sheetNo);
} }
/** /**
* To prepare data * To prepare data
* *
* @param cell * @param cell
* @param analysisCellList
* @param collectionAnalysisCellList
* @param rowIndex * @param rowIndex
* @param columnIndex * @param columnIndex
* @param firstColumnCache * @param firstRowCache
* @return Returns the data that the cell needs to replace * @return Returns the data that the cell needs to replace
*/ */
private String prepareData(Cell cell, List<AnalysisCell> analysisCellList, private String prepareData(Cell cell, int rowIndex, int columnIndex, Map<String, Set<Integer>> firstRowCache) {
List<AnalysisCell> collectionAnalysisCellList, int rowIndex, int columnIndex, Set<Integer> firstColumnCache) {
if (!CellType.STRING.equals(cell.getCellTypeEnum())) { if (!CellType.STRING.equals(cell.getCellTypeEnum())) {
return null; return null;
} }
@ -404,8 +413,12 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
if (StringUtils.isEmpty(variable)) { if (StringUtils.isEmpty(variable)) {
continue; continue;
} }
if (variable.startsWith(COLLECTION_PREFIX)) { int collectPrefixIndex = variable.indexOf(COLLECTION_PREFIX);
variable = variable.substring(1); if (collectPrefixIndex > -1) {
if (collectPrefixIndex != 0) {
analysisCell.setPrefix(variable.substring(0, collectPrefixIndex));
}
variable = variable.substring(collectPrefixIndex + 1);
if (StringUtils.isEmpty(variable)) { if (StringUtils.isEmpty(variable)) {
continue; continue;
} }
@ -422,13 +435,13 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
} }
lastPrepareDataIndex = suffixIndex + 1; lastPrepareDataIndex = suffixIndex + 1;
} }
return dealAnalysisCell(analysisCell, value, rowIndex, lastPrepareDataIndex, length, analysisCellList, return dealAnalysisCell(analysisCell, value, rowIndex, lastPrepareDataIndex, length, firstRowCache,
collectionAnalysisCellList, firstColumnCache, preparedData); preparedData);
} }
private String dealAnalysisCell(AnalysisCell analysisCell, String value, int rowIndex, int lastPrepareDataIndex, private String dealAnalysisCell(AnalysisCell analysisCell, String value, int rowIndex, int lastPrepareDataIndex,
int length, List<AnalysisCell> analysisCellList, List<AnalysisCell> collectionAnalysisCellList, int length, Map<String, Set<Integer>> firstRowCache, StringBuilder preparedData) {
Set<Integer> firstColumnCache, StringBuilder preparedData) { Integer sheetNo = writeContext.writeSheetHolder().getSheetNo();
if (analysisCell != null) { if (analysisCell != null) {
if (lastPrepareDataIndex == length) { if (lastPrepareDataIndex == length) {
analysisCell.getPrepareDataList().add(StringUtils.EMPTY); analysisCell.getPrepareDataList().add(StringUtils.EMPTY);
@ -436,12 +449,29 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
analysisCell.getPrepareDataList().add(convertPrepareData(value.substring(lastPrepareDataIndex))); analysisCell.getPrepareDataList().add(convertPrepareData(value.substring(lastPrepareDataIndex)));
analysisCell.setOnlyOneVariable(Boolean.FALSE); analysisCell.setOnlyOneVariable(Boolean.FALSE);
} }
String uniqueDataFlag = uniqueDataFlag(sheetNo, analysisCell.getPrefix());
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) { if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) {
List<AnalysisCell> analysisCellList = templateAnalysisCache.get(uniqueDataFlag);
if (analysisCellList == null) {
analysisCellList = new ArrayList<AnalysisCell>();
templateAnalysisCache.put(uniqueDataFlag, analysisCellList);
}
analysisCellList.add(analysisCell); analysisCellList.add(analysisCell);
} else { } else {
if (!firstColumnCache.contains(rowIndex)) { Set<Integer> uniqueFirstRowCache = firstRowCache.get(uniqueDataFlag);
analysisCell.setFirstColumn(Boolean.TRUE); if (uniqueFirstRowCache == null) {
firstColumnCache.add(rowIndex); uniqueFirstRowCache = new HashSet<Integer>();
firstRowCache.put(uniqueDataFlag, uniqueFirstRowCache);
}
if (!uniqueFirstRowCache.contains(rowIndex)) {
analysisCell.setFirstRow(Boolean.TRUE);
uniqueFirstRowCache.add(rowIndex);
}
List<AnalysisCell> collectionAnalysisCellList = templateCollectionAnalysisCache.get(uniqueDataFlag);
if (collectionAnalysisCellList == null) {
collectionAnalysisCellList = new ArrayList<AnalysisCell>();
templateCollectionAnalysisCache.put(uniqueDataFlag, collectionAnalysisCellList);
} }
collectionAnalysisCellList.add(analysisCell); collectionAnalysisCellList.add(analysisCell);
} }
@ -460,7 +490,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
List<String> prepareDataList = new ArrayList<String>(); List<String> prepareDataList = new ArrayList<String>();
analysisCell.setPrepareDataList(prepareDataList); analysisCell.setPrepareDataList(prepareDataList);
analysisCell.setCellType(WriteTemplateAnalysisCellTypeEnum.COMMON); analysisCell.setCellType(WriteTemplateAnalysisCellTypeEnum.COMMON);
analysisCell.setFirstColumn(Boolean.FALSE); analysisCell.setFirstRow(Boolean.FALSE);
return analysisCell; return analysisCell;
} }
@ -470,4 +500,11 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
return prepareData; return prepareData;
} }
private String uniqueDataFlag(Integer sheetNo, String wrapperName) {
if (StringUtils.isEmpty(wrapperName)) {
return sheetNo.toString() + "-";
}
return sheetNo + "-" + wrapperName;
}
} }

19
src/main/java/com/alibaba/excel/write/metadata/fill/AnalysisCell.java

@ -16,7 +16,8 @@ public class AnalysisCell {
private List<String> prepareDataList; private List<String> prepareDataList;
private Boolean onlyOneVariable; private Boolean onlyOneVariable;
private WriteTemplateAnalysisCellTypeEnum cellType; private WriteTemplateAnalysisCellTypeEnum cellType;
private Boolean firstColumn; private String prefix;
private Boolean firstRow;
public int getColumnIndex() { public int getColumnIndex() {
return columnIndex; return columnIndex;
@ -58,6 +59,14 @@ public class AnalysisCell {
this.onlyOneVariable = onlyOneVariable; this.onlyOneVariable = onlyOneVariable;
} }
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public WriteTemplateAnalysisCellTypeEnum getCellType() { public WriteTemplateAnalysisCellTypeEnum getCellType() {
return cellType; return cellType;
} }
@ -66,12 +75,12 @@ public class AnalysisCell {
this.cellType = cellType; this.cellType = cellType;
} }
public Boolean getFirstColumn() { public Boolean getFirstRow() {
return firstColumn; return firstRow;
} }
public void setFirstColumn(Boolean firstColumn) { public void setFirstRow(Boolean firstRow) {
this.firstColumn = firstColumn; this.firstRow = firstRow;
} }
@Override @Override

44
src/main/java/com/alibaba/excel/write/metadata/fill/FillWrapper.java

@ -0,0 +1,44 @@
package com.alibaba.excel.write.metadata.fill;
import java.util.Collection;
/**
* Multiple lists are supported when packing
*
* @author Jiaju Zhuang
**/
public class FillWrapper {
/**
* The collection prefix that needs to be filled.
*/
private String name;
/**
* Data that needs to be filled.
*/
private Collection collectionData;
public FillWrapper(Collection collectionData) {
this.collectionData = collectionData;
}
public FillWrapper(String name, Collection collectionData) {
this.name = name;
this.collectionData = collectionData;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Collection getCollectionData() {
return collectionData;
}
public void setCollectionData(Collection collectionData) {
this.collectionData = collectionData;
}
}

10
src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatTest.java

@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory;
import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
/** /**
* *
@ -44,9 +45,10 @@ public class DateFormatTest {
private void readCn(File file) { private void readCn(File file) {
List<DateFormatData> list = List<DateFormatData> list =
EasyExcel.read(file, DateFormatData.class, null).locale(Locale.CHINA).sheet().doReadSync(); EasyExcel.read(file, DateFormatData.class, null).locale(Locale.CHINA).sheet().doReadSync();
System.out.println(JSON.toJSONString(list));
for (DateFormatData data : list) { for (DateFormatData data : list) {
Assert.assertEquals(data.getDate(), data.getDateStringCn()); Assert.assertEquals(data.getDateStringCn(), data.getDate());
Assert.assertEquals(data.getNumber(), data.getNumberStringCn()); Assert.assertEquals(data.getNumberStringCn(), data.getNumber());
} }
} }
@ -54,8 +56,8 @@ public class DateFormatTest {
List<DateFormatData> list = List<DateFormatData> list =
EasyExcel.read(file, DateFormatData.class, null).locale(Locale.US).sheet().doReadSync(); EasyExcel.read(file, DateFormatData.class, null).locale(Locale.US).sheet().doReadSync();
for (DateFormatData data : list) { for (DateFormatData data : list) {
Assert.assertEquals(data.getDate(), data.getDateStringUs()); Assert.assertEquals(data.getDateStringUs(), data.getDate());
Assert.assertEquals(data.getNumber(), data.getNumberStringUs()); Assert.assertEquals(data.getNumberStringUs(), data.getNumber());
} }
} }
} }

44
src/test/java/com/alibaba/easyexcel/test/core/fill/FillDataTest.java

@ -19,6 +19,7 @@ import com.alibaba.excel.enums.WriteDirectionEnum;
import com.alibaba.excel.write.merge.LoopMergeStrategy; import com.alibaba.excel.write.merge.LoopMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig; import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
/** /**
* *
@ -39,6 +40,10 @@ public class FillDataTest {
private static File horizontalFillTemplate07; private static File horizontalFillTemplate07;
private static File fileHorizontal03; private static File fileHorizontal03;
private static File horizontalFillTemplate03; private static File horizontalFillTemplate03;
private static File fileComposite07;
private static File compositeFillTemplate07;
private static File fileComposite03;
private static File compositeFillTemplate03;
@BeforeClass @BeforeClass
public static void init() { public static void init() {
@ -54,6 +59,10 @@ public class FillDataTest {
horizontalFillTemplate07 = TestFileUtil.readFile("fill" + File.separator + "horizontal.xlsx"); horizontalFillTemplate07 = TestFileUtil.readFile("fill" + File.separator + "horizontal.xlsx");
fileHorizontal03 = TestFileUtil.createNewFile("fillHorizontal03.xls"); fileHorizontal03 = TestFileUtil.createNewFile("fillHorizontal03.xls");
horizontalFillTemplate03 = TestFileUtil.readFile("fill" + File.separator + "horizontal.xls"); horizontalFillTemplate03 = TestFileUtil.readFile("fill" + File.separator + "horizontal.xls");
fileComposite07 = TestFileUtil.createNewFile("fileComposite07.xlsx");
compositeFillTemplate07 = TestFileUtil.readFile("fill" + File.separator + "composite.xlsx");
fileComposite03 = TestFileUtil.createNewFile("fileComposite03.xls");
compositeFillTemplate03 = TestFileUtil.readFile("fill" + File.separator + "composite.xls");
} }
@Test @Test
@ -86,6 +95,41 @@ public class FillDataTest {
horizontalFill(fileHorizontal03, horizontalFillTemplate03); horizontalFill(fileHorizontal03, horizontalFillTemplate03);
} }
@Test
public void t07CompositeFill07() {
compositeFill(fileComposite07, compositeFillTemplate07);
}
@Test
public void t08CompositeFill03() {
compositeFill(fileComposite03, compositeFillTemplate03);
}
private void compositeFill(File file, File template) {
ExcelWriter excelWriter = EasyExcel.write(file).withTemplate(template).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet);
excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet);
excelWriter.fill(new FillWrapper("data2", data()), writeSheet);
excelWriter.fill(new FillWrapper("data2", data()), writeSheet);
excelWriter.fill(new FillWrapper("data3", data()), writeSheet);
excelWriter.fill(new FillWrapper("data3", data()), writeSheet);
Map<String, Object> map = new HashMap<String, Object>();
map.put("date", "2019年10月9日13:28:28");
excelWriter.fill(map, writeSheet);
excelWriter.finish();
List<Object> list = EasyExcel.read(file).ignoreEmptyRow(false).sheet().headRowNumber(0).doReadSync();
Map<String, String> map0 = (Map<String, String>)list.get(0);
Assert.assertEquals("张三", map0.get(21));
Map<String, String> map27 = (Map<String, String>)list.get(27);
Assert.assertEquals("张三", map27.get(0));
Map<String, String> map29 = (Map<String, String>)list.get(29);
Assert.assertEquals("张三", map29.get(3));
}
private void horizontalFill(File file, File template) { private void horizontalFill(File file, File template) {
ExcelWriter excelWriter = EasyExcel.write(file).withTemplate(template).build(); ExcelWriter excelWriter = EasyExcel.write(file).withTemplate(template).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build(); WriteSheet writeSheet = EasyExcel.writerSheet().build();

8
src/test/java/com/alibaba/easyexcel/test/core/head/ListHeadDataListener.java

@ -29,10 +29,10 @@ public class ListHeadDataListener extends AnalysisEventListener<Map<Integer, Str
public void doAfterAllAnalysed(AnalysisContext context) { public void doAfterAllAnalysed(AnalysisContext context) {
Assert.assertEquals(list.size(), 1); Assert.assertEquals(list.size(), 1);
Map<Integer, String> data = list.get(0); Map<Integer, String> data = list.get(0);
Assert.assertEquals(data.get(0), "字符串0"); Assert.assertEquals("字符串0", data.get(0));
Assert.assertEquals(data.get(1), "1.0"); Assert.assertEquals("1", data.get(1));
Assert.assertEquals(data.get(2), "2020-01-01 01:01:01"); Assert.assertEquals("2020-01-01 01:01:01", data.get(2));
Assert.assertEquals(data.get(3), "额外数据"); Assert.assertEquals("额外数据", data.get(3));
LOGGER.debug("First row:{}", JSON.toJSONString(list.get(0))); LOGGER.debug("First row:{}", JSON.toJSONString(list.get(0)));
} }
} }

33
src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java

@ -15,6 +15,7 @@ import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.WriteDirectionEnum; import com.alibaba.excel.enums.WriteDirectionEnum;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig; import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
/** /**
* 写的填充写法 * 写的填充写法
@ -179,6 +180,38 @@ public class FillTest {
excelWriter.finish(); excelWriter.finish();
} }
/**
* 组合填充填充
*
* @since 2.2.0
*/
@Test
public void compositeFill() {
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量 {前缀.} 前缀可以区分不同的list
String templateFileName =
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "composite.xlsx";
String fileName = TestFileUtil.getPath() + "compositeFill" + System.currentTimeMillis() + ".xlsx";
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
// 如果有多个list 模板上必须有{前缀.} 这里的前缀就是 data1,然后多个list必须用 FillWrapper包裹
excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet);
excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet);
excelWriter.fill(new FillWrapper("data2", data()), writeSheet);
excelWriter.fill(new FillWrapper("data2", data()), writeSheet);
excelWriter.fill(new FillWrapper("data3", data()), writeSheet);
excelWriter.fill(new FillWrapper("data3", data()), writeSheet);
Map<String, Object> map = new HashMap<String, Object>();
map.put("date", "2019年10月9日13:28:28");
excelWriter.fill(map, writeSheet);
// 别忘记关闭流
excelWriter.finish();
}
private List<FillData> data() { private List<FillData> data() {
List<FillData> list = new ArrayList<FillData>(); List<FillData> list = new ArrayList<FillData>();
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {

22
src/test/java/com/alibaba/easyexcel/test/temp/FillTempTest.java

@ -14,7 +14,6 @@ import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
/** /**
* 写的填充写法 * 写的填充写法
@ -34,18 +33,12 @@ public class FillTempTest {
public void complexFill() { public void complexFill() {
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替 // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量 // {} 代表普通变量 {.} 代表是list的变量
String templateFileName = "D:\\test\\complex.xlsx"; String templateFileName = "D:\\test\\simple.xlsx";
String fileName = TestFileUtil.getPath() + "complexFill" + System.currentTimeMillis() + ".xlsx"; String fileName = TestFileUtil.getPath() + "complexFill" + System.currentTimeMillis() + ".xlsx";
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build(); WriteSheet writeSheet = EasyExcel.writerSheet().build();
// 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。 excelWriter.fill(teamp(), writeSheet);
// forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了,所以慎用
// 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
// 如果数据量大 list不是最后一行 参照下一个
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
excelWriter.fill(data(), fillConfig, writeSheet);
// excelWriter.fill(data2(), fillConfig, writeSheet);
Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> map = new HashMap<String, Object>();
map.put("date", "2019年10月9日13:28:28"); map.put("date", "2019年10月9日13:28:28");
map.put("total", 1000); map.put("total", 1000);
@ -106,6 +99,17 @@ public class FillTempTest {
return list; return list;
} }
private List<TempFillData> teamp() {
List<TempFillData> list = new ArrayList<TempFillData>();
for (int i = 0; i < 10; i++) {
TempFillData fillData = new TempFillData();
list.add(fillData);
fillData.setName("张三");
fillData.setNumber(5.2);
}
return list;
}
private List<FillData> data() { private List<FillData> data() {
List<FillData> list = new ArrayList<FillData>(); List<FillData> list = new ArrayList<FillData>();
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {

15
src/test/java/com/alibaba/easyexcel/test/temp/TempFillData.java

@ -0,0 +1,15 @@
package com.alibaba.easyexcel.test.temp;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import lombok.Data;
/**
* @author Jiaju Zhuang
*/
@Data
@ContentRowHeight(30)
public class TempFillData {
private String name;
private double number;
}

4
src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java

@ -24,10 +24,10 @@ public class CommentTest {
@Test @Test
public void comment() throws Exception { public void comment() throws Exception {
File file = new File("D:\\test\\comment.xls"); File file = new File("D:\\test\\listHead07.xlsx");
List<Map<Integer, CellData>> datas = EasyExcel.read(file).doReadAllSync(); List<Map<Integer, CellData>> datas = EasyExcel.read(file).doReadAllSync();
for (Map<Integer, CellData> data : datas) { for (Map<Integer, CellData> data : datas) {
LOGGER.info("数据:{}", JSON.toJSONString(data.get(0))); LOGGER.info("数据:{}", JSON.toJSONString(data));
} }
} }

BIN
src/test/resources/demo/fill/composite.xlsx

Binary file not shown.

BIN
src/test/resources/fill/composite.xls

Binary file not shown.

BIN
src/test/resources/fill/composite.xlsx

Binary file not shown.

2
update.md

@ -13,7 +13,7 @@
* 兼容部分比较特殊的excel * 兼容部分比较特殊的excel
* 同时传入了`List<List<String>>`和`class`的head,会通过index去匹配注解 * 同时传入了`List<List<String>>`和`class`的head,会通过index去匹配注解
* 修复读取转换器的并发问题 * 修复读取转换器的并发问题
* * 填充支持多个List对象
# 2.1.4 # 2.1.4
* 新增参数`useDefaultListener` 可以排除默认对象转换 * 新增参数`useDefaultListener` 可以排除默认对象转换

Loading…
Cancel
Save