After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 811 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.8 KiB |
@ -0,0 +1,17 @@
|
||||
package com.alibaba.excel.enums; |
||||
|
||||
/** |
||||
* Direction of writing |
||||
* |
||||
* @author Jiaju Zhuang |
||||
**/ |
||||
public enum WriteDirectionEnum { |
||||
/** |
||||
* Vertical write. |
||||
*/ |
||||
VERTICAL, |
||||
/** |
||||
* Horizontal write. |
||||
*/ |
||||
HORIZONTAL,; |
||||
} |
@ -0,0 +1,17 @@
|
||||
package com.alibaba.excel.enums; |
||||
|
||||
/** |
||||
* Type of template to read when writing |
||||
* |
||||
* @author Jiaju Zhuang |
||||
**/ |
||||
public enum WriteTemplateAnalysisCellTypeEnum { |
||||
/** |
||||
* Common field. |
||||
*/ |
||||
COMMON, |
||||
/** |
||||
* A collection of fields. |
||||
*/ |
||||
COLLECTION,; |
||||
} |
@ -0,0 +1,17 @@
|
||||
package com.alibaba.excel.enums; |
||||
|
||||
/** |
||||
* Enumeration of write methods |
||||
* |
||||
* @author Jiaju Zhuang |
||||
**/ |
||||
public enum WriteTypeEnum { |
||||
/** |
||||
* Add. |
||||
*/ |
||||
ADD, |
||||
/** |
||||
* Fill. |
||||
*/ |
||||
FILL,; |
||||
} |
@ -0,0 +1,196 @@
|
||||
package com.alibaba.excel.util; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.apache.poi.ss.usermodel.Cell; |
||||
import org.apache.poi.ss.usermodel.Row; |
||||
|
||||
import com.alibaba.excel.context.WriteContext; |
||||
import com.alibaba.excel.metadata.CellData; |
||||
import com.alibaba.excel.metadata.Head; |
||||
import com.alibaba.excel.write.handler.CellWriteHandler; |
||||
import com.alibaba.excel.write.handler.RowWriteHandler; |
||||
import com.alibaba.excel.write.handler.SheetWriteHandler; |
||||
import com.alibaba.excel.write.handler.WorkbookWriteHandler; |
||||
import com.alibaba.excel.write.handler.WriteHandler; |
||||
|
||||
/** |
||||
* Write handler utils |
||||
* |
||||
* @author Jiaju Zhuang |
||||
*/ |
||||
public class WriteHandlerUtils { |
||||
|
||||
private WriteHandlerUtils() {} |
||||
|
||||
public static void beforeWorkbookCreate(WriteContext writeContext) { |
||||
List<WriteHandler> handlerList = |
||||
writeContext.writeWorkbookHolder().writeHandlerMap().get(WorkbookWriteHandler.class); |
||||
if (handlerList == null || handlerList.isEmpty()) { |
||||
return; |
||||
} |
||||
for (WriteHandler writeHandler : handlerList) { |
||||
if (writeHandler instanceof WorkbookWriteHandler) { |
||||
((WorkbookWriteHandler)writeHandler).beforeWorkbookCreate(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static void afterWorkbookCreate(WriteContext writeContext) { |
||||
List<WriteHandler> handlerList = |
||||
writeContext.writeWorkbookHolder().writeHandlerMap().get(WorkbookWriteHandler.class); |
||||
if (handlerList == null || handlerList.isEmpty()) { |
||||
return; |
||||
} |
||||
for (WriteHandler writeHandler : handlerList) { |
||||
if (writeHandler instanceof WorkbookWriteHandler) { |
||||
((WorkbookWriteHandler)writeHandler).afterWorkbookCreate(writeContext.writeWorkbookHolder()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static void afterWorkbookDispose(WriteContext writeContext) { |
||||
List<WriteHandler> handlerList = |
||||
writeContext.writeWorkbookHolder().writeHandlerMap().get(WorkbookWriteHandler.class); |
||||
if (handlerList == null || handlerList.isEmpty()) { |
||||
return; |
||||
} |
||||
for (WriteHandler writeHandler : handlerList) { |
||||
if (writeHandler instanceof WorkbookWriteHandler) { |
||||
((WorkbookWriteHandler)writeHandler).afterWorkbookDispose(writeContext.writeWorkbookHolder()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static void beforeSheetCreate(WriteContext writeContext) { |
||||
List<WriteHandler> handlerList = writeContext.writeSheetHolder().writeHandlerMap().get(SheetWriteHandler.class); |
||||
if (handlerList == null || handlerList.isEmpty()) { |
||||
return; |
||||
} |
||||
for (WriteHandler writeHandler : handlerList) { |
||||
if (writeHandler instanceof SheetWriteHandler) { |
||||
((SheetWriteHandler)writeHandler).beforeSheetCreate(writeContext.writeWorkbookHolder(), |
||||
writeContext.writeSheetHolder()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static void afterSheetCreate(WriteContext writeContext) { |
||||
List<WriteHandler> handlerList = writeContext.writeSheetHolder().writeHandlerMap().get(SheetWriteHandler.class); |
||||
if (handlerList == null || handlerList.isEmpty()) { |
||||
return; |
||||
} |
||||
for (WriteHandler writeHandler : handlerList) { |
||||
if (writeHandler instanceof SheetWriteHandler) { |
||||
((SheetWriteHandler)writeHandler).afterSheetCreate(writeContext.writeWorkbookHolder(), |
||||
writeContext.writeSheetHolder()); |
||||
} |
||||
} |
||||
if (null != writeContext.writeWorkbookHolder().getWriteWorkbook().getWriteHandler()) { |
||||
writeContext.writeWorkbookHolder().getWriteWorkbook().getWriteHandler() |
||||
.sheet(writeContext.writeSheetHolder().getSheetNo(), writeContext.writeSheetHolder().getSheet()); |
||||
} |
||||
} |
||||
|
||||
public static void beforeCellCreate(WriteContext writeContext, Row row, Head head, Integer columnIndex, |
||||
Integer relativeRowIndex, Boolean isHead) { |
||||
List<WriteHandler> handlerList = |
||||
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); |
||||
if (handlerList == null || handlerList.isEmpty()) { |
||||
return; |
||||
} |
||||
for (WriteHandler writeHandler : handlerList) { |
||||
if (writeHandler instanceof CellWriteHandler) { |
||||
((CellWriteHandler)writeHandler).beforeCellCreate(writeContext.writeSheetHolder(), |
||||
writeContext.writeTableHolder(), row, head, columnIndex, relativeRowIndex, isHead); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static void afterCellCreate(WriteContext writeContext, Cell cell, Head head, Integer relativeRowIndex, |
||||
Boolean isHead) { |
||||
List<WriteHandler> handlerList = |
||||
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); |
||||
if (handlerList == null || handlerList.isEmpty()) { |
||||
return; |
||||
} |
||||
for (WriteHandler writeHandler : handlerList) { |
||||
if (writeHandler instanceof CellWriteHandler) { |
||||
((CellWriteHandler)writeHandler).afterCellCreate(writeContext.writeSheetHolder(), |
||||
writeContext.writeTableHolder(), cell, head, relativeRowIndex, isHead); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static void afterCellDispose(WriteContext writeContext, CellData cellData, Cell cell, Head head, |
||||
Integer relativeRowIndex, Boolean isHead) { |
||||
List<CellData> cellDataList = new ArrayList<CellData>(); |
||||
if (cell != null) { |
||||
cellDataList.add(cellData); |
||||
} |
||||
afterCellDispose(writeContext, cellDataList, cell, head, relativeRowIndex, isHead); |
||||
} |
||||
|
||||
public static void afterCellDispose(WriteContext writeContext, List<CellData> cellDataList, Cell cell, Head head, |
||||
Integer relativeRowIndex, Boolean isHead) { |
||||
List<WriteHandler> handlerList = |
||||
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); |
||||
if (handlerList == null || handlerList.isEmpty()) { |
||||
return; |
||||
} |
||||
for (WriteHandler writeHandler : handlerList) { |
||||
if (writeHandler instanceof CellWriteHandler) { |
||||
((CellWriteHandler)writeHandler).afterCellDispose(writeContext.writeSheetHolder(), |
||||
writeContext.writeTableHolder(), cellDataList, cell, head, relativeRowIndex, isHead); |
||||
} |
||||
} |
||||
if (null != writeContext.writeWorkbookHolder().getWriteWorkbook().getWriteHandler()) { |
||||
writeContext.writeWorkbookHolder().getWriteWorkbook().getWriteHandler().cell(cell.getRowIndex(), cell); |
||||
} |
||||
} |
||||
|
||||
public static void beforeRowCreate(WriteContext writeContext, Integer rowIndex, Integer relativeRowIndex, |
||||
Boolean isHead) { |
||||
List<WriteHandler> handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(RowWriteHandler.class); |
||||
if (handlerList == null || handlerList.isEmpty()) { |
||||
return; |
||||
} |
||||
for (WriteHandler writeHandler : handlerList) { |
||||
if (writeHandler instanceof RowWriteHandler) { |
||||
((RowWriteHandler)writeHandler).beforeRowCreate(writeContext.writeSheetHolder(), |
||||
writeContext.writeTableHolder(), rowIndex, relativeRowIndex, isHead); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static void afterRowCreate(WriteContext writeContext, Row row, Integer relativeRowIndex, Boolean isHead) { |
||||
List<WriteHandler> handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(RowWriteHandler.class); |
||||
if (handlerList == null || handlerList.isEmpty()) { |
||||
return; |
||||
} |
||||
for (WriteHandler writeHandler : handlerList) { |
||||
if (writeHandler instanceof RowWriteHandler) { |
||||
((RowWriteHandler)writeHandler).afterRowCreate(writeContext.writeSheetHolder(), |
||||
writeContext.writeTableHolder(), row, relativeRowIndex, isHead); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
public static void afterRowDispose(WriteContext writeContext, Row row, Integer relativeRowIndex, Boolean isHead) { |
||||
List<WriteHandler> handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(RowWriteHandler.class); |
||||
if (handlerList == null || handlerList.isEmpty()) { |
||||
return; |
||||
} |
||||
for (WriteHandler writeHandler : handlerList) { |
||||
if (writeHandler instanceof RowWriteHandler) { |
||||
((RowWriteHandler)writeHandler).afterRowDispose(writeContext.writeSheetHolder(), |
||||
writeContext.writeTableHolder(), row, relativeRowIndex, isHead); |
||||
} |
||||
} |
||||
if (null != writeContext.writeWorkbookHolder().getWriteWorkbook().getWriteHandler()) { |
||||
writeContext.writeWorkbookHolder().getWriteWorkbook().getWriteHandler().row(row.getRowNum(), row); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,140 @@
|
||||
package com.alibaba.excel.write.executor; |
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook; |
||||
import org.apache.poi.ss.usermodel.Cell; |
||||
import org.apache.poi.ss.usermodel.ClientAnchor; |
||||
import org.apache.poi.ss.usermodel.CreationHelper; |
||||
import org.apache.poi.ss.usermodel.Drawing; |
||||
import org.apache.poi.ss.usermodel.Sheet; |
||||
|
||||
import com.alibaba.excel.context.WriteContext; |
||||
import com.alibaba.excel.converters.Converter; |
||||
import com.alibaba.excel.converters.ConverterKeyBuild; |
||||
import com.alibaba.excel.enums.CellDataTypeEnum; |
||||
import com.alibaba.excel.exception.ExcelDataConvertException; |
||||
import com.alibaba.excel.metadata.CellData; |
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
||||
import com.alibaba.excel.write.metadata.holder.WriteHolder; |
||||
|
||||
/** |
||||
* Excel write Executor |
||||
* |
||||
* @author Jiaju Zhuang |
||||
*/ |
||||
public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor { |
||||
protected WriteContext writeContext; |
||||
|
||||
public AbstractExcelWriteExecutor(WriteContext writeContext) { |
||||
this.writeContext = writeContext; |
||||
} |
||||
|
||||
protected CellData converterAndSet(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value, |
||||
ExcelContentProperty excelContentProperty) { |
||||
if (value == null) { |
||||
return new CellData(); |
||||
} |
||||
if (value instanceof String && currentWriteHolder.globalConfiguration().getAutoTrim()) { |
||||
value = ((String)value).trim(); |
||||
} |
||||
CellData cellData = convert(currentWriteHolder, clazz, cell, value, excelContentProperty); |
||||
if (cellData.getFormula() != null && cellData.getFormula()) { |
||||
cell.setCellFormula(cellData.getFormulaValue()); |
||||
} |
||||
switch (cellData.getType()) { |
||||
case STRING: |
||||
cell.setCellValue(cellData.getStringValue()); |
||||
return cellData; |
||||
case BOOLEAN: |
||||
cell.setCellValue(cellData.getBooleanValue()); |
||||
return cellData; |
||||
case NUMBER: |
||||
cell.setCellValue(cellData.getNumberValue().doubleValue()); |
||||
return cellData; |
||||
case IMAGE: |
||||
setImageValue(cellData, cell); |
||||
return cellData; |
||||
case EMPTY: |
||||
return cellData; |
||||
default: |
||||
throw new ExcelDataConvertException("Not supported data:" + value + " return type:" + cell.getCellType() |
||||
+ "at row:" + cell.getRow().getRowNum()); |
||||
} |
||||
} |
||||
|
||||
protected CellData convert(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value, |
||||
ExcelContentProperty excelContentProperty) { |
||||
if (value == null) { |
||||
return new CellData(); |
||||
} |
||||
// This means that the user has defined the data.
|
||||
if (value instanceof CellData) { |
||||
CellData cellDataValue = (CellData)value; |
||||
if (cellDataValue.getType() != null) { |
||||
return cellDataValue; |
||||
} else { |
||||
if (cellDataValue.getData() == null) { |
||||
cellDataValue.setType(CellDataTypeEnum.EMPTY); |
||||
return cellDataValue; |
||||
} |
||||
} |
||||
CellData cellDataReturn = doConvert(currentWriteHolder, cellDataValue.getData().getClass(), cell, |
||||
cellDataValue.getData(), excelContentProperty); |
||||
// The formula information is subject to user input
|
||||
if (cellDataValue.getFormula() != null) { |
||||
cellDataReturn.setFormula(cellDataValue.getFormula()); |
||||
cellDataReturn.setFormulaValue(cellDataValue.getFormulaValue()); |
||||
} |
||||
return cellDataReturn; |
||||
} |
||||
return doConvert(currentWriteHolder, clazz, cell, value, excelContentProperty); |
||||
} |
||||
|
||||
private CellData doConvert(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value, |
||||
ExcelContentProperty excelContentProperty) { |
||||
Converter converter = null; |
||||
if (excelContentProperty != null) { |
||||
converter = excelContentProperty.getConverter(); |
||||
} |
||||
if (converter == null) { |
||||
converter = currentWriteHolder.converterMap().get(ConverterKeyBuild.buildKey(clazz)); |
||||
} |
||||
if (converter == null) { |
||||
throw new ExcelDataConvertException( |
||||
"Can not find 'Converter' support class " + clazz.getSimpleName() + "."); |
||||
} |
||||
CellData cellData; |
||||
try { |
||||
cellData = |
||||
converter.convertToExcelData(value, excelContentProperty, currentWriteHolder.globalConfiguration()); |
||||
} catch (Exception e) { |
||||
throw new ExcelDataConvertException("Convert data:" + value + " error,at row:" + cell.getRow().getRowNum(), |
||||
e); |
||||
} |
||||
if (cellData == null || cellData.getType() == null) { |
||||
throw new ExcelDataConvertException( |
||||
"Convert data:" + value + " return null,at row:" + cell.getRow().getRowNum()); |
||||
} |
||||
return cellData; |
||||
} |
||||
|
||||
private void setImageValue(CellData cellData, Cell cell) { |
||||
Sheet sheet = cell.getSheet(); |
||||
int index = sheet.getWorkbook().addPicture(cellData.getImageValue(), HSSFWorkbook.PICTURE_TYPE_PNG); |
||||
Drawing drawing = sheet.getDrawingPatriarch(); |
||||
if (drawing == null) { |
||||
drawing = sheet.createDrawingPatriarch(); |
||||
} |
||||
CreationHelper helper = sheet.getWorkbook().getCreationHelper(); |
||||
ClientAnchor anchor = helper.createClientAnchor(); |
||||
anchor.setDx1(0); |
||||
anchor.setDx2(0); |
||||
anchor.setDy1(0); |
||||
anchor.setDy2(0); |
||||
anchor.setCol1(cell.getColumnIndex()); |
||||
anchor.setCol2(cell.getColumnIndex() + 1); |
||||
anchor.setRow1(cell.getRowIndex()); |
||||
anchor.setRow2(cell.getRowIndex() + 1); |
||||
anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE); |
||||
drawing.createPicture(anchor, index); |
||||
} |
||||
} |
@ -0,0 +1,179 @@
|
||||
package com.alibaba.excel.write.executor; |
||||
|
||||
import java.lang.reflect.Field; |
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.HashSet; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
import org.apache.poi.ss.usermodel.Cell; |
||||
import org.apache.poi.ss.usermodel.Row; |
||||
|
||||
import com.alibaba.excel.context.WriteContext; |
||||
import com.alibaba.excel.enums.HeadKindEnum; |
||||
import com.alibaba.excel.metadata.BaseRowModel; |
||||
import com.alibaba.excel.metadata.CellData; |
||||
import com.alibaba.excel.metadata.Head; |
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
||||
import com.alibaba.excel.util.CollectionUtils; |
||||
import com.alibaba.excel.util.WorkBookUtil; |
||||
import com.alibaba.excel.util.WriteHandlerUtils; |
||||
import com.alibaba.excel.write.metadata.holder.WriteHolder; |
||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; |
||||
|
||||
import net.sf.cglib.beans.BeanMap; |
||||
|
||||
/** |
||||
* Add the data into excel |
||||
* |
||||
* @author Jiaju Zhuang |
||||
*/ |
||||
public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { |
||||
|
||||
public ExcelWriteAddExecutor(WriteContext writeContext) { |
||||
super(writeContext); |
||||
} |
||||
|
||||
public void add(List data) { |
||||
if (CollectionUtils.isEmpty(data)) { |
||||
return; |
||||
} |
||||
WriteSheetHolder writeSheetHolder = writeContext.writeSheetHolder(); |
||||
int newRowIndex = writeSheetHolder.getNewRowIndexAndStartDoWrite(); |
||||
if (writeSheetHolder.isNew() && !writeSheetHolder.getExcelWriteHeadProperty().hasHead()) { |
||||
newRowIndex += writeContext.currentWriteHolder().relativeHeadRowIndex(); |
||||
} |
||||
// BeanMap is out of order,so use fieldList
|
||||
List<Field> fieldList = new ArrayList<Field>(); |
||||
for (int relativeRowIndex = 0; relativeRowIndex < data.size(); relativeRowIndex++) { |
||||
int n = relativeRowIndex + newRowIndex; |
||||
addOneRowOfDataToExcel(data.get(relativeRowIndex), n, relativeRowIndex, fieldList); |
||||
} |
||||
} |
||||
|
||||
private void addOneRowOfDataToExcel(Object oneRowData, int n, int relativeRowIndex, List<Field> fieldList) { |
||||
if (oneRowData == null) { |
||||
return; |
||||
} |
||||
WriteHandlerUtils.beforeRowCreate(writeContext, n, relativeRowIndex, Boolean.FALSE); |
||||
Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), n); |
||||
WriteHandlerUtils.afterRowCreate(writeContext, row, relativeRowIndex, Boolean.FALSE); |
||||
if (oneRowData instanceof List) { |
||||
addBasicTypeToExcel((List)oneRowData, row, relativeRowIndex); |
||||
} else { |
||||
addJavaObjectToExcel(oneRowData, row, relativeRowIndex, fieldList); |
||||
} |
||||
WriteHandlerUtils.afterRowDispose(writeContext, row, relativeRowIndex, Boolean.FALSE); |
||||
} |
||||
|
||||
private void addBasicTypeToExcel(List<Object> oneRowData, Row row, int relativeRowIndex) { |
||||
if (CollectionUtils.isEmpty(oneRowData)) { |
||||
return; |
||||
} |
||||
Map<Integer, Head> headMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap(); |
||||
int dataIndex = 0; |
||||
int cellIndex = 0; |
||||
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) { |
||||
if (dataIndex >= oneRowData.size()) { |
||||
return; |
||||
} |
||||
cellIndex = entry.getKey(); |
||||
Head head = entry.getValue(); |
||||
doAddBasicTypeToExcel(oneRowData, head, row, relativeRowIndex, dataIndex++, cellIndex); |
||||
} |
||||
// Finish
|
||||
if (dataIndex >= oneRowData.size()) { |
||||
return; |
||||
} |
||||
if (cellIndex != 0) { |
||||
cellIndex++; |
||||
} |
||||
int size = oneRowData.size() - dataIndex; |
||||
for (int i = 0; i < size; i++) { |
||||
doAddBasicTypeToExcel(oneRowData, null, row, relativeRowIndex, dataIndex++, cellIndex++); |
||||
} |
||||
} |
||||
|
||||
private void doAddBasicTypeToExcel(List<Object> oneRowData, Head head, Row row, int relativeRowIndex, int dataIndex, |
||||
int cellIndex) { |
||||
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE); |
||||
Cell cell = WorkBookUtil.createCell(row, cellIndex); |
||||
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE); |
||||
Object value = oneRowData.get(dataIndex); |
||||
CellData cellData = converterAndSet(writeContext.currentWriteHolder(), value == null ? null : value.getClass(), |
||||
cell, value, null); |
||||
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE); |
||||
} |
||||
|
||||
private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex, List<Field> fieldList) { |
||||
WriteHolder currentWriteHolder = writeContext.currentWriteHolder(); |
||||
BeanMap beanMap = BeanMap.create(oneRowData); |
||||
Set<String> beanMapHandledSet = new HashSet<String>(); |
||||
int cellIndex = 0; |
||||
// If it's a class it needs to be cast by type
|
||||
if (HeadKindEnum.CLASS.equals(writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadKind())) { |
||||
Map<Integer, Head> headMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap(); |
||||
Map<Integer, ExcelContentProperty> contentPropertyMap = |
||||
writeContext.currentWriteHolder().excelWriteHeadProperty().getContentPropertyMap(); |
||||
for (Map.Entry<Integer, ExcelContentProperty> entry : contentPropertyMap.entrySet()) { |
||||
cellIndex = entry.getKey(); |
||||
ExcelContentProperty excelContentProperty = entry.getValue(); |
||||
String name = excelContentProperty.getField().getName(); |
||||
if (!beanMap.containsKey(name)) { |
||||
continue; |
||||
} |
||||
Head head = headMap.get(cellIndex); |
||||
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE); |
||||
Cell cell = WorkBookUtil.createCell(row, cellIndex); |
||||
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE); |
||||
Object value = beanMap.get(name); |
||||
CellData cellData = converterAndSet(currentWriteHolder, excelContentProperty.getField().getType(), cell, |
||||
value, excelContentProperty); |
||||
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE); |
||||
beanMapHandledSet.add(name); |
||||
} |
||||
} |
||||
// Finish
|
||||
if (beanMapHandledSet.size() == beanMap.size()) { |
||||
return; |
||||
} |
||||
if (cellIndex != 0) { |
||||
cellIndex++; |
||||
} |
||||
Map<String, Field> ignoreMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getIgnoreMap(); |
||||
initFieldList(oneRowData.getClass(), fieldList); |
||||
for (Field field : fieldList) { |
||||
String filedName = field.getName(); |
||||
boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName) |
||||
|| ignoreMap.containsKey(filedName); |
||||
if (uselessData) { |
||||
continue; |
||||
} |
||||
Object value = beanMap.get(filedName); |
||||
if (value == null) { |
||||
continue; |
||||
} |
||||
WriteHandlerUtils.beforeCellCreate(writeContext, row, null, cellIndex, relativeRowIndex, Boolean.FALSE); |
||||
Cell cell = WorkBookUtil.createCell(row, cellIndex++); |
||||
WriteHandlerUtils.afterCellCreate(writeContext, cell, null, relativeRowIndex, Boolean.FALSE); |
||||
CellData cellData = converterAndSet(currentWriteHolder, value.getClass(), cell, value, null); |
||||
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE); |
||||
} |
||||
} |
||||
|
||||
private void initFieldList(Class clazz, List<Field> fieldList) { |
||||
if (!fieldList.isEmpty()) { |
||||
return; |
||||
} |
||||
Class tempClass = clazz; |
||||
while (tempClass != null) { |
||||
if (tempClass != BaseRowModel.class) { |
||||
Collections.addAll(fieldList, tempClass.getDeclaredFields()); |
||||
} |
||||
tempClass = tempClass.getSuperclass(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,9 @@
|
||||
package com.alibaba.excel.write.executor; |
||||
|
||||
/** |
||||
* Excel write Executor |
||||
* |
||||
* @author Jiaju Zhuang |
||||
*/ |
||||
public interface ExcelWriteExecutor { |
||||
} |
@ -0,0 +1,377 @@
|
||||
package com.alibaba.excel.write.executor; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collection; |
||||
import java.util.HashMap; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.apache.poi.ss.usermodel.Cell; |
||||
import org.apache.poi.ss.usermodel.CellStyle; |
||||
import org.apache.poi.ss.usermodel.Row; |
||||
import org.apache.poi.ss.usermodel.Sheet; |
||||
|
||||
import com.alibaba.excel.context.WriteContext; |
||||
import com.alibaba.excel.enums.WriteDirectionEnum; |
||||
import com.alibaba.excel.enums.WriteTemplateAnalysisCellTypeEnum; |
||||
import com.alibaba.excel.exception.ExcelGenerateException; |
||||
import com.alibaba.excel.metadata.CellData; |
||||
import com.alibaba.excel.metadata.Head; |
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
||||
import com.alibaba.excel.util.CollectionUtils; |
||||
import com.alibaba.excel.util.StringUtils; |
||||
import com.alibaba.excel.util.WriteHandlerUtils; |
||||
import com.alibaba.excel.write.metadata.fill.AnalysisCell; |
||||
import com.alibaba.excel.write.metadata.fill.FillConfig; |
||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; |
||||
|
||||
import net.sf.cglib.beans.BeanMap; |
||||
|
||||
/** |
||||
* Fill the data into excel |
||||
* |
||||
* @author Jiaju Zhuang |
||||
*/ |
||||
public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
||||
|
||||
private static final String ESCAPE_FILL_PREFIX = "\\\\\\{"; |
||||
private static final String ESCAPE_FILL_SUFFIX = "\\\\\\}"; |
||||
private static final String FILL_PREFIX = "{"; |
||||
private static final String FILL_SUFFIX = "}"; |
||||
private static final char IGNORE_CHAR = '\\'; |
||||
private static final String COLLECTION_PREFIX = "."; |
||||
/** |
||||
* Fields to replace in the template |
||||
*/ |
||||
private Map<Integer, List<AnalysisCell>> templateAnalysisCache = new HashMap<Integer, List<AnalysisCell>>(8); |
||||
/** |
||||
* Collection fields to replace in the template |
||||
*/ |
||||
private Map<Integer, List<AnalysisCell>> templateCollectionAnalysisCache = |
||||
new HashMap<Integer, List<AnalysisCell>>(8); |
||||
/** |
||||
* Style cache for collection fields |
||||
*/ |
||||
private Map<Integer, Map<AnalysisCell, CellStyle>> collectionFieldStyleCache = |
||||
new HashMap<Integer, Map<AnalysisCell, CellStyle>>(8); |
||||
/** |
||||
* Last index cache for collection fields |
||||
*/ |
||||
private Map<Integer, Map<AnalysisCell, Integer>> collectionLastIndexCache = |
||||
new HashMap<Integer, Map<AnalysisCell, Integer>>(8); |
||||
|
||||
public ExcelWriteFillExecutor(WriteContext writeContext) { |
||||
super(writeContext); |
||||
} |
||||
|
||||
public void fill(Object data, FillConfig fillConfig) { |
||||
if (fillConfig == null) { |
||||
fillConfig = FillConfig.builder().build(true); |
||||
} |
||||
fillConfig.init(); |
||||
if (data instanceof Collection) { |
||||
List<AnalysisCell> analysisCellList = readTemplateData(templateCollectionAnalysisCache); |
||||
Collection collectionData = (Collection)data; |
||||
if (CollectionUtils.isEmpty(collectionData)) { |
||||
return; |
||||
} |
||||
Iterator iterator = collectionData.iterator(); |
||||
if (WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection()) && fillConfig.getForceNewRow()) { |
||||
shiftRows(collectionData.size(), analysisCellList); |
||||
} |
||||
while (iterator.hasNext()) { |
||||
doFill(analysisCellList, iterator.next(), fillConfig); |
||||
} |
||||
} else { |
||||
doFill(readTemplateData(templateAnalysisCache), data, fillConfig); |
||||
} |
||||
} |
||||
|
||||
private void shiftRows(int size, List<AnalysisCell> analysisCellList) { |
||||
if (CollectionUtils.isEmpty(analysisCellList)) { |
||||
return; |
||||
} |
||||
int maxRowIndex = 0; |
||||
Integer sheetNo = writeContext.writeSheetHolder().getSheetNo(); |
||||
Map<AnalysisCell, Integer> collectionLastIndexMap = collectionLastIndexCache.get(sheetNo); |
||||
for (AnalysisCell analysisCell : analysisCellList) { |
||||
if (collectionLastIndexMap != null) { |
||||
Integer lastRowIndex = collectionLastIndexMap.get(analysisCell); |
||||
if (lastRowIndex != null) { |
||||
if (lastRowIndex > maxRowIndex) { |
||||
maxRowIndex = lastRowIndex; |
||||
} |
||||
continue; |
||||
} |
||||
} |
||||
if (analysisCell.getRowIndex() > maxRowIndex) { |
||||
maxRowIndex = analysisCell.getRowIndex(); |
||||
} |
||||
} |
||||
Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet(); |
||||
int lastRowIndex = cachedSheet.getLastRowNum(); |
||||
if (maxRowIndex >= lastRowIndex) { |
||||
return; |
||||
} |
||||
Sheet sheet = writeContext.writeSheetHolder().getCachedSheet(); |
||||
int number = size; |
||||
if (collectionLastIndexMap == null) { |
||||
number--; |
||||
} |
||||
sheet.shiftRows(maxRowIndex + 1, lastRowIndex, number); |
||||
for (AnalysisCell analysisCell : templateAnalysisCache.get(writeContext.writeSheetHolder().getSheetNo())) { |
||||
if (analysisCell.getRowIndex() > maxRowIndex) { |
||||
analysisCell.setRowIndex(analysisCell.getRowIndex() + number); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void doFill(List<AnalysisCell> analysisCellList, Object oneRowData, FillConfig fillConfig) { |
||||
Map dataMap; |
||||
if (oneRowData instanceof Map) { |
||||
dataMap = (Map)oneRowData; |
||||
} else { |
||||
dataMap = BeanMap.create(oneRowData); |
||||
} |
||||
WriteSheetHolder writeSheetHolder = writeContext.writeSheetHolder(); |
||||
Map<String, ExcelContentProperty> fieldNameContentPropertyMap = |
||||
writeContext.currentWriteHolder().excelWriteHeadProperty().getFieldNameContentPropertyMap(); |
||||
for (AnalysisCell analysisCell : analysisCellList) { |
||||
Cell cell = getOneCell(analysisCell, fillConfig); |
||||
if (analysisCell.getOnlyOneVariable()) { |
||||
String variable = analysisCell.getVariableList().get(0); |
||||
if (!dataMap.containsKey(variable)) { |
||||
continue; |
||||
} |
||||
Object value = dataMap.get(variable); |
||||
CellData cellData = converterAndSet(writeSheetHolder, value == null ? null : value.getClass(), cell, |
||||
value, fieldNameContentPropertyMap.get(variable)); |
||||
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, null, Boolean.FALSE); |
||||
} else { |
||||
StringBuilder cellValueBuild = new StringBuilder(); |
||||
int index = 0; |
||||
List<CellData> cellDataList = new ArrayList<CellData>(); |
||||
for (String variable : analysisCell.getVariableList()) { |
||||
cellValueBuild.append(analysisCell.getPrepareDataList().get(index++)); |
||||
if (!dataMap.containsKey(variable)) { |
||||
continue; |
||||
} |
||||
Object value = dataMap.get(variable); |
||||
CellData cellData = convert(writeSheetHolder, value == null ? null : value.getClass(), cell, value, |
||||
fieldNameContentPropertyMap.get(variable)); |
||||
cellDataList.add(cellData); |
||||
switch (cellData.getType()) { |
||||
case STRING: |
||||
cellValueBuild.append(cellData.getStringValue()); |
||||
break; |
||||
case BOOLEAN: |
||||
cellValueBuild.append(cellData.getBooleanValue()); |
||||
break; |
||||
case NUMBER: |
||||
cellValueBuild.append(cellData.getNumberValue()); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
cellValueBuild.append(analysisCell.getPrepareDataList().get(index)); |
||||
cell.setCellValue(cellValueBuild.toString()); |
||||
WriteHandlerUtils.afterCellDispose(writeContext, cellDataList, cell, null, null, Boolean.FALSE); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private Cell getOneCell(AnalysisCell analysisCell, FillConfig fillConfig) { |
||||
Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet(); |
||||
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) { |
||||
return cachedSheet.getRow(analysisCell.getRowIndex()).getCell(analysisCell.getColumnIndex()); |
||||
} |
||||
Integer sheetNo = writeContext.writeSheetHolder().getSheetNo(); |
||||
Sheet sheet = writeContext.writeSheetHolder().getSheet(); |
||||
|
||||
Map<AnalysisCell, Integer> collectionLastIndexMap = collectionLastIndexCache.get(sheetNo); |
||||
if (collectionLastIndexMap == null) { |
||||
collectionLastIndexMap = new HashMap<AnalysisCell, Integer>(16); |
||||
collectionLastIndexCache.put(sheetNo, collectionLastIndexMap); |
||||
} |
||||
boolean isOriginalCell = false; |
||||
Integer lastRowIndex; |
||||
Integer lastColumnIndex; |
||||
switch (fillConfig.getDirection()) { |
||||
case VERTICAL: |
||||
lastRowIndex = collectionLastIndexMap.get(analysisCell); |
||||
if (lastRowIndex == null) { |
||||
lastRowIndex = analysisCell.getRowIndex(); |
||||
collectionLastIndexMap.put(analysisCell, lastRowIndex); |
||||
isOriginalCell = true; |
||||
} else { |
||||
collectionLastIndexMap.put(analysisCell, ++lastRowIndex); |
||||
} |
||||
lastColumnIndex = analysisCell.getColumnIndex(); |
||||
break; |
||||
case HORIZONTAL: |
||||
lastRowIndex = analysisCell.getRowIndex(); |
||||
lastColumnIndex = collectionLastIndexMap.get(analysisCell); |
||||
if (lastColumnIndex == null) { |
||||
lastColumnIndex = analysisCell.getColumnIndex(); |
||||
collectionLastIndexMap.put(analysisCell, lastColumnIndex); |
||||
isOriginalCell = true; |
||||
} else { |
||||
collectionLastIndexMap.put(analysisCell, ++lastColumnIndex); |
||||
} |
||||
break; |
||||
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); |
||||
} |
||||
WriteHandlerUtils.afterRowCreate(writeContext, row, null, Boolean.FALSE); |
||||
} |
||||
} |
||||
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); |
||||
} |
||||
|
||||
Map<AnalysisCell, CellStyle> collectionFieldStyleMap = collectionFieldStyleCache.get(sheetNo); |
||||
if (collectionFieldStyleMap == null) { |
||||
collectionFieldStyleMap = new HashMap<AnalysisCell, CellStyle>(16); |
||||
collectionFieldStyleCache.put(sheetNo, collectionFieldStyleMap); |
||||
} |
||||
if (isOriginalCell) { |
||||
collectionFieldStyleMap.put(analysisCell, cell.getCellStyle()); |
||||
} else { |
||||
CellStyle cellStyle = collectionFieldStyleMap.get(analysisCell); |
||||
if (cellStyle != null) { |
||||
cell.setCellStyle(cellStyle); |
||||
} |
||||
} |
||||
return cell; |
||||
} |
||||
|
||||
private List<AnalysisCell> readTemplateData(Map<Integer, List<AnalysisCell>> analysisCache) { |
||||
Integer sheetNo = writeContext.writeSheetHolder().getSheetNo(); |
||||
List<AnalysisCell> analysisCellList = analysisCache.get(sheetNo); |
||||
if (analysisCellList != null) { |
||||
return analysisCellList; |
||||
} |
||||
Sheet sheet = writeContext.writeSheetHolder().getCachedSheet(); |
||||
analysisCellList = new ArrayList<AnalysisCell>(); |
||||
List<AnalysisCell> collectionAnalysisCellList = new ArrayList<AnalysisCell>(); |
||||
for (int i = 0; i <= sheet.getLastRowNum(); i++) { |
||||
Row row = sheet.getRow(i); |
||||
if (row == null) { |
||||
continue; |
||||
} |
||||
for (int j = 0; j < row.getLastCellNum(); j++) { |
||||
Cell cell = row.getCell(j); |
||||
if (cell == null) { |
||||
continue; |
||||
} |
||||
prepareData(cell.getStringCellValue(), analysisCellList, collectionAnalysisCellList, i, j); |
||||
} |
||||
} |
||||
templateAnalysisCache.put(sheetNo, analysisCellList); |
||||
templateCollectionAnalysisCache.put(sheetNo, collectionAnalysisCellList); |
||||
return analysisCache.get(sheetNo); |
||||
} |
||||
|
||||
private void prepareData(String value, List<AnalysisCell> analysisCellList, |
||||
List<AnalysisCell> collectionAnalysisCellList, int rowIndex, int columnIndex) { |
||||
if (StringUtils.isEmpty(value)) { |
||||
return; |
||||
} |
||||
AnalysisCell analysisCell = null; |
||||
int startIndex = 0; |
||||
int length = value.length(); |
||||
int lastPrepareDataIndex = 0; |
||||
out: |
||||
while (startIndex < length) { |
||||
int prefixIndex = value.indexOf(FILL_PREFIX, startIndex); |
||||
if (prefixIndex < 0) { |
||||
break out; |
||||
} |
||||
if (prefixIndex != 0) { |
||||
char prefixPrefixChar = value.charAt(prefixIndex - 1); |
||||
if (prefixPrefixChar == IGNORE_CHAR) { |
||||
startIndex = prefixIndex + 1; |
||||
continue; |
||||
} |
||||
} |
||||
int suffixIndex = -1; |
||||
while (suffixIndex == -1 && startIndex < length) { |
||||
suffixIndex = value.indexOf(FILL_SUFFIX, startIndex + 1); |
||||
if (suffixIndex < 0) { |
||||
break out; |
||||
} |
||||
startIndex = suffixIndex + 1; |
||||
char prefixSuffixChar = value.charAt(suffixIndex - 1); |
||||
if (prefixSuffixChar == IGNORE_CHAR) { |
||||
suffixIndex = -1; |
||||
} |
||||
} |
||||
if (analysisCell == null) { |
||||
analysisCell = new AnalysisCell(); |
||||
analysisCell.setRowIndex(rowIndex); |
||||
analysisCell.setColumnIndex(columnIndex); |
||||
analysisCell.setOnlyOneVariable(Boolean.TRUE); |
||||
List<String> variableList = new ArrayList<String>(); |
||||
analysisCell.setVariableList(variableList); |
||||
List<String> prepareDataList = new ArrayList<String>(); |
||||
analysisCell.setPrepareDataList(prepareDataList); |
||||
analysisCell.setCellType(WriteTemplateAnalysisCellTypeEnum.COMMON); |
||||
} |
||||
String variable = value.substring(prefixIndex + 1, suffixIndex); |
||||
if (StringUtils.isEmpty(variable)) { |
||||
continue; |
||||
} |
||||
if (variable.startsWith(COLLECTION_PREFIX)) { |
||||
variable = variable.substring(1); |
||||
if (StringUtils.isEmpty(variable)) { |
||||
continue; |
||||
} |
||||
analysisCell.setCellType(WriteTemplateAnalysisCellTypeEnum.COLLECTION); |
||||
} |
||||
analysisCell.getVariableList().add(variable); |
||||
if (lastPrepareDataIndex == prefixIndex) { |
||||
analysisCell.getPrepareDataList().add(StringUtils.EMPTY); |
||||
} else { |
||||
analysisCell.getPrepareDataList() |
||||
.add(convertPrepareData(value.substring(lastPrepareDataIndex, prefixIndex))); |
||||
analysisCell.setOnlyOneVariable(Boolean.FALSE); |
||||
} |
||||
lastPrepareDataIndex = suffixIndex + 1; |
||||
} |
||||
if (analysisCell != null) { |
||||
if (lastPrepareDataIndex == length) { |
||||
analysisCell.getPrepareDataList().add(StringUtils.EMPTY); |
||||
} else { |
||||
analysisCell.getPrepareDataList().add(convertPrepareData(value.substring(lastPrepareDataIndex))); |
||||
analysisCell.setOnlyOneVariable(Boolean.FALSE); |
||||
} |
||||
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) { |
||||
analysisCellList.add(analysisCell); |
||||
} else { |
||||
collectionAnalysisCellList.add(analysisCell); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private String convertPrepareData(String prepareData) { |
||||
prepareData = prepareData.replaceAll(ESCAPE_FILL_PREFIX, FILL_PREFIX); |
||||
prepareData = prepareData.replaceAll(ESCAPE_FILL_SUFFIX, FILL_SUFFIX); |
||||
return prepareData; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,83 @@
|
||||
package com.alibaba.excel.write.metadata.fill; |
||||
|
||||
import com.alibaba.excel.enums.WriteDirectionEnum; |
||||
|
||||
/** |
||||
* Fill config |
||||
* |
||||
* @author Jiaju Zhuang |
||||
**/ |
||||
public class FillConfig { |
||||
private WriteDirectionEnum direction; |
||||
/** |
||||
* Create a new row each time you use the list parameter.The default create if necessary. |
||||
* <p> |
||||
* Warnning:If you use <code>forceNewRow</code> set true, will not be able to use asynchronous write file, simply |
||||
* say the whole file will be stored in memory. |
||||
*/ |
||||
private Boolean forceNewRow; |
||||
private boolean hasInit; |
||||
|
||||
public WriteDirectionEnum getDirection() { |
||||
return direction; |
||||
} |
||||
|
||||
public void setDirection(WriteDirectionEnum direction) { |
||||
this.direction = direction; |
||||
} |
||||
|
||||
public Boolean getForceNewRow() { |
||||
return forceNewRow; |
||||
} |
||||
|
||||
public void setForceNewRow(Boolean forceNewRow) { |
||||
this.forceNewRow = forceNewRow; |
||||
} |
||||
|
||||
public void init() { |
||||
if (hasInit) { |
||||
return; |
||||
} |
||||
if (direction == null) { |
||||
direction = WriteDirectionEnum.VERTICAL; |
||||
} |
||||
if (forceNewRow == null) { |
||||
forceNewRow = Boolean.FALSE; |
||||
} |
||||
hasInit = true; |
||||
} |
||||
|
||||
public static FillConfigBuilder builder() { |
||||
return new FillConfigBuilder(); |
||||
} |
||||
|
||||
public static class FillConfigBuilder { |
||||
private FillConfig fillConfig; |
||||
|
||||
FillConfigBuilder() { |
||||
this.fillConfig = new FillConfig(); |
||||
} |
||||
|
||||
public FillConfigBuilder direction(WriteDirectionEnum direction) { |
||||
fillConfig.setDirection(direction); |
||||
return this; |
||||
} |
||||
|
||||
public FillConfigBuilder forceNewRow(Boolean forceNewRow) { |
||||
fillConfig.setForceNewRow(forceNewRow); |
||||
return this; |
||||
} |
||||
|
||||
public FillConfig build() { |
||||
return build(true); |
||||
} |
||||
|
||||
public FillConfig build(boolean autoInit) { |
||||
if (autoInit) { |
||||
fillConfig.init(); |
||||
} |
||||
return fillConfig; |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
package com.alibaba.easyexcel.test.demo.fill; |
||||
|
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author Jiaju Zhuang |
||||
*/ |
||||
@Data |
||||
public class FillData { |
||||
private String name; |
||||
private double number; |
||||
} |
@ -0,0 +1,181 @@
|
||||
package com.alibaba.easyexcel.test.demo.fill; |
||||
|
||||
import java.io.File; |
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.Ignore; |
||||
import org.junit.Test; |
||||
|
||||
import com.alibaba.easyexcel.test.util.TestFileUtil; |
||||
import com.alibaba.excel.EasyExcel; |
||||
import com.alibaba.excel.ExcelWriter; |
||||
import com.alibaba.excel.enums.WriteDirectionEnum; |
||||
import com.alibaba.excel.write.metadata.WriteSheet; |
||||
import com.alibaba.excel.write.metadata.fill.FillConfig; |
||||
|
||||
/** |
||||
* 写的填充写法 |
||||
* |
||||
* @author Jiaju Zhuang |
||||
*/ |
||||
@Ignore |
||||
public class FillTest { |
||||
/** |
||||
* 最简单的填充 |
||||
*/ |
||||
@Test |
||||
public void simpleFill() { |
||||
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
|
||||
String templateFileName = |
||||
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "simple.xlsx"; |
||||
|
||||
// 方案1 根据对象填充
|
||||
String fileName = TestFileUtil.getPath() + "simpleFill" + System.currentTimeMillis() + ".xlsx"; |
||||
// 这里 会填充到第一个sheet, 然后文件流会自动关闭
|
||||
FillData fillData = new FillData(); |
||||
fillData.setName("张三"); |
||||
fillData.setNumber(5.2); |
||||
EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(fillData); |
||||
|
||||
// 方案2 根据Map填充
|
||||
fileName = TestFileUtil.getPath() + "simpleFill" + System.currentTimeMillis() + ".xlsx"; |
||||
// 这里 会填充到第一个sheet, 然后文件流会自动关闭
|
||||
Map<String, Object> map = new HashMap<String, Object>(); |
||||
map.put("name", "张三"); |
||||
map.put("number", 5.2); |
||||
EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(map); |
||||
} |
||||
|
||||
/** |
||||
* 填充列表 |
||||
*/ |
||||
@Test |
||||
public void listFill() { |
||||
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
|
||||
// 填充list 的时候还要注意 模板中{.} 多了个点 表示list
|
||||
String templateFileName = |
||||
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "list.xlsx"; |
||||
|
||||
// 方案1 一下子全部放到内存里面 并填充
|
||||
String fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx"; |
||||
// 这里 会填充到第一个sheet, 然后文件流会自动关闭
|
||||
EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(data()); |
||||
|
||||
// 方案2 分多次 填充 会使用文件缓存(省内存)
|
||||
fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx"; |
||||
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); |
||||
WriteSheet writeSheet = EasyExcel.writerSheet().build(); |
||||
excelWriter.fill(data(), writeSheet); |
||||
excelWriter.fill(data(), writeSheet); |
||||
// 千万别忘记关闭流
|
||||
excelWriter.finish(); |
||||
} |
||||
|
||||
/** |
||||
* 复杂的填充 |
||||
*/ |
||||
@Test |
||||
public void complexFill() { |
||||
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
|
||||
// {} 代表普通变量 {.} 代表是list的变量
|
||||
String templateFileName = |
||||
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "complex.xlsx"; |
||||
|
||||
String fileName = TestFileUtil.getPath() + "complexFill" + System.currentTimeMillis() + ".xlsx"; |
||||
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); |
||||
WriteSheet writeSheet = EasyExcel.writerSheet().build(); |
||||
// 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。
|
||||
// forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了,所以慎用
|
||||
// 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
|
||||
// 如果数据量大 list不是最后一行 参照下一个
|
||||
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build(); |
||||
excelWriter.fill(data(), fillConfig, writeSheet); |
||||
excelWriter.fill(data(), fillConfig, writeSheet); |
||||
Map<String, Object> map = new HashMap<String, Object>(); |
||||
map.put("date", "2019年10月9日13:28:28"); |
||||
map.put("total", 1000); |
||||
excelWriter.fill(map, writeSheet); |
||||
excelWriter.finish(); |
||||
} |
||||
|
||||
/** |
||||
* 数据量大的复杂填充 |
||||
* <p> |
||||
* 这里的解决方案是 确保模板list为最后一行,然后再拼接table.还有03版没救,只能刚正面加内存。 |
||||
*/ |
||||
@Test |
||||
public void complexFillWithTable() { |
||||
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
|
||||
// {} 代表普通变量 {.} 代表是list的变量
|
||||
// 这里模板 删除了list以后的数据,也就是统计的这一行
|
||||
String templateFileName = |
||||
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "complexFillWithTable.xlsx"; |
||||
|
||||
String fileName = TestFileUtil.getPath() + "complexFillWithTable" + System.currentTimeMillis() + ".xlsx"; |
||||
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); |
||||
WriteSheet writeSheet = EasyExcel.writerSheet().build(); |
||||
// 直接写入数据
|
||||
excelWriter.fill(data(), writeSheet); |
||||
excelWriter.fill(data(), writeSheet); |
||||
|
||||
// 写入list之前的数据
|
||||
Map<String, Object> map = new HashMap<String, Object>(); |
||||
map.put("date", "2019年10月9日13:28:28"); |
||||
excelWriter.fill(map, writeSheet); |
||||
|
||||
// list 后面还有个统计 想办法手动写入
|
||||
// 这里偷懒直接用list 也可以用对象
|
||||
List<List<String>> totalListList = new ArrayList<List<String>>(); |
||||
List<String> totalList = new ArrayList<String>(); |
||||
totalListList.add(totalList); |
||||
totalList.add(null); |
||||
totalList.add(null); |
||||
totalList.add(null); |
||||
// 第四列
|
||||
totalList.add("统计:1000"); |
||||
// 这里是write 别和fill 搞错了
|
||||
excelWriter.write(totalListList, writeSheet); |
||||
excelWriter.finish(); |
||||
// 总体上写法比较复杂 但是也没有想到好的版本 异步的去写入excel 不支持行的删除和移动,也不支持备注这种的写入,所以也排除了可以
|
||||
// 新建一个 然后一点点复制过来的方案,最后导致list需要新增行的时候,后面的列的数据没法后移,后续会继续想想解决方案
|
||||
} |
||||
|
||||
/** |
||||
* 横向的填充 |
||||
*/ |
||||
@Test |
||||
public void horizontalFill() { |
||||
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
|
||||
// {} 代表普通变量 {.} 代表是list的变量
|
||||
String templateFileName = |
||||
TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "horizontal.xlsx"; |
||||
|
||||
String fileName = TestFileUtil.getPath() + "horizontalFill" + System.currentTimeMillis() + ".xlsx"; |
||||
ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); |
||||
WriteSheet writeSheet = EasyExcel.writerSheet().build(); |
||||
FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build(); |
||||
excelWriter.fill(data(), fillConfig, writeSheet); |
||||
excelWriter.fill(data(), fillConfig, 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() { |
||||
List<FillData> list = new ArrayList<FillData>(); |
||||
for (int i = 0; i < 10; i++) { |
||||
FillData fillData = new FillData(); |
||||
list.add(fillData); |
||||
fillData.setName("张三"); |
||||
fillData.setNumber(5.2); |
||||
} |
||||
return list; |
||||
} |
||||
} |