Browse Source

增加写回调可以自定义样式

bugfix
jipengfei.jpf 6 years ago
parent
commit
59acbf0c8d
  1. 20
      src/main/java/com/alibaba/excel/EasyExcelFactory.java
  2. 34
      src/main/java/com/alibaba/excel/ExcelWriter.java
  3. 27
      src/main/java/com/alibaba/excel/context/WriteContext.java
  4. 35
      src/main/java/com/alibaba/excel/event/WriteHandler.java
  5. 23
      src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
  6. 47
      src/test/java/com/alibaba/easyexcel/test/WriteTest.java
  7. 59
      src/test/java/com/alibaba/easyexcel/test/listen/AfterWriteHandlerImpl.java

20
src/main/java/com/alibaba/excel/EasyExcelFactory.java

@ -2,6 +2,7 @@ package com.alibaba.excel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.event.WriteHandler;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
@ -97,4 +98,23 @@ public class EasyExcelFactory {
return new ExcelWriter(temp, outputStream, typeEnum, needHead);
}
/**
* Get ExcelWriter with a template file
*
* @param temp Append data after a POI file , Can be nullthe template POI filesystem that contains the
* Workbook stream)
* @param outputStream the java OutputStream you wish to write the data to
* @param typeEnum 03 or 07
* @param needHead
* @param handler User-defined callback
* @return new ExcelWriter
*/
public static ExcelWriter getWriterWithTempAndHandler(InputStream temp,
OutputStream outputStream,
ExcelTypeEnum typeEnum,
boolean needHead,
WriteHandler handler) {
return new ExcelWriter(temp, outputStream, typeEnum, needHead, handler);
}
}

34
src/main/java/com/alibaba/excel/ExcelWriter.java

@ -1,5 +1,6 @@
package com.alibaba.excel;
import com.alibaba.excel.event.WriteHandler;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
@ -17,7 +18,7 @@ import java.util.List;
* This object can perform the following two functions.
* <pre>
* 1. Create a new empty Excel workbook, write the data to the stream after the data is filled.
* 2. Edit existing Excel, write the original Excel file, or write it to other places.
* 2. Edit existing Excel, write the original Excel file, or write it to other places.{@link ExcelWriter(InputStream , OutputStream , ExcelTypeEnum , boolean )}
* </pre>
* @author jipengfei
*/
@ -39,7 +40,7 @@ public class ExcelWriter {
/**
* @param generateParam
* @since easyexcel 0.0.1
* @since easyexcel 0.0.1 Use {@link new ExcelWrite(int, int, int)
*/
@Deprecated
public ExcelWriter(GenerateParam generateParam) {
@ -55,7 +56,7 @@ public class ExcelWriter {
* @param needHead Do you need to write the header to the file?
*/
public ExcelWriter(OutputStream outputStream, ExcelTypeEnum typeEnum, boolean needHead) {
excelBuilder = new ExcelBuilderImpl(null, outputStream, typeEnum, needHead);
excelBuilder = new ExcelBuilderImpl(null, outputStream, typeEnum, needHead, null);
}
/**
@ -65,11 +66,24 @@ public class ExcelWriter {
* @param typeEnum 03 or 07
*/
public ExcelWriter(InputStream templateInputStream, OutputStream outputStream, ExcelTypeEnum typeEnum,Boolean needHead) {
excelBuilder = new ExcelBuilderImpl(templateInputStream,outputStream, typeEnum, needHead);
excelBuilder = new ExcelBuilderImpl(templateInputStream,outputStream, typeEnum, needHead, null);
}
/**
* Write data to a sheet
* Create new writer
* @param templateInputStream Append data after a POI file ,Can be nullthe template POI filesystem that contains the Workbook stream)
* @param outputStream the java OutputStream you wish to write the data to
* @param typeEnum 03 or 07
* @param writeHandler User-defined callback
*/
public ExcelWriter(InputStream templateInputStream, OutputStream outputStream, ExcelTypeEnum typeEnum, Boolean needHead,
WriteHandler writeHandler) {
excelBuilder = new ExcelBuilderImpl(templateInputStream,outputStream, typeEnum, needHead,writeHandler);
}
/**
* Write data(List<? extends BaseRowModel>) to a sheet
* @param data Data to be written
* @param sheet Write to this sheet
* @return this current writer
@ -97,7 +111,7 @@ public class ExcelWriter {
/**
*
* Write data to a sheet
* Write data(List<List<String>>) to a sheet
* @param data Data to be written
* @param sheet Write to this sheet
* @return this
@ -108,7 +122,7 @@ public class ExcelWriter {
}
/**
* Write data to a sheet
* Write data(List<List<String>>) to a sheet
* @param data Data to be written
* @param sheet Write to this sheet
* @return this
@ -119,7 +133,7 @@ public class ExcelWriter {
}
/**
* Write data to a sheet
* Write data(List<? extends BaseRowModel>) to a sheet
* @param data Data to be written
* @param sheet Write to this sheet
* @param table Write to this table
@ -131,7 +145,7 @@ public class ExcelWriter {
}
/**
* Write data to a sheet
* Write data(List<List<String>>) to a sheet
* @param data Data to be written
* @param sheet Write to this sheet
* @param table Write to this table
@ -156,7 +170,7 @@ public class ExcelWriter {
}
/**
* Write data to a sheet
* Write data(List<List<Object>>) to a sheet
* @param data Data to be written
* @param sheet Write to this sheet
* @param table Write to this table

27
src/main/java/com/alibaba/excel/context/WriteContext.java

@ -1,5 +1,6 @@
package com.alibaba.excel.context;
import com.alibaba.excel.event.WriteHandler;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.ExcelHeadProperty;
import com.alibaba.excel.metadata.Table;
@ -7,10 +8,7 @@ import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.StyleUtil;
import com.alibaba.excel.util.WorkBookUtil;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import java.io.IOException;
@ -91,12 +89,20 @@ public class WriteContext {
private boolean needHead = Boolean.TRUE;
private WriteHandler afterWriteHandler;
public WriteHandler getAfterWriteHandler() {
return afterWriteHandler;
}
public WriteContext(InputStream templateInputStream, OutputStream out, ExcelTypeEnum excelType,
boolean needHead) throws IOException {
boolean needHead, WriteHandler afterWriteHandler) throws IOException {
this.needHead = needHead;
this.outputStream = out;
this.afterWriteHandler = afterWriteHandler;
this.workbook = WorkBookUtil.createWorkBook(templateInputStream, excelType);
this.defaultCellStyle = StyleUtil.buildDefaultCellStyle(this.workbook);
}
/**
@ -110,6 +116,9 @@ public class WriteContext {
this.currentSheet = workbook.getSheetAt(sheet.getSheetNo() - 1);
} catch (Exception e) {
this.currentSheet = WorkBookUtil.createSheet(workbook, sheet);
if (null != afterWriteHandler) {
this.afterWriteHandler.sheet(sheet.getSheetNo(), currentSheet);
}
}
buildSheetStyle(currentSheet, sheet.getColumnWidthMap());
/** **/
@ -161,6 +170,9 @@ public class WriteContext {
int i = startRow;
for (; i < this.excelHeadProperty.getRowNum() + startRow; i++) {
Row row = WorkBookUtil.createRow(currentSheet, i);
if (null != afterWriteHandler) {
this.afterWriteHandler.row(i, row);
}
addOneRowOfHeadDataToExcel(row, this.excelHeadProperty.getHeadByRowNum(i - startRow));
}
}
@ -177,7 +189,10 @@ public class WriteContext {
private void addOneRowOfHeadDataToExcel(Row row, List<String> headByRowNum) {
if (headByRowNum != null && headByRowNum.size() > 0) {
for (int i = 0; i < headByRowNum.size(); i++) {
WorkBookUtil.createCell(row, i, getCurrentHeadCellStyle(), headByRowNum.get(i));
Cell cell = WorkBookUtil.createCell(row, i, getCurrentHeadCellStyle(), headByRowNum.get(i));
if (null != afterWriteHandler) {
this.afterWriteHandler.cell(i, cell);
}
}
}
}

35
src/main/java/com/alibaba/excel/event/WriteHandler.java

@ -0,0 +1,35 @@
package com.alibaba.excel.event;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
/**
*
* @author jipengfei
*/
public interface WriteHandler {
/**
* Custom operation after creating each sheet
*
* @param sheetNo
* @param sheet
*/
void sheet(int sheetNo, Sheet sheet);
/**
* Custom operation after creating each row
*
* @param rowNum
* @param row
*/
void row(int rowNum, Row row);
/**
* Custom operation after creating each cell
* @param cellNum
* @param cell
*/
void cell(int cellNum, Cell cell);
}

23
src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java

@ -1,6 +1,7 @@
package com.alibaba.excel.write;
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.event.WriteHandler;
import com.alibaba.excel.exception.ExcelGenerateException;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.ExcelColumnProperty;
@ -12,6 +13,7 @@ import com.alibaba.excel.util.POITempFile;
import com.alibaba.excel.util.TypeUtil;
import com.alibaba.excel.util.WorkBookUtil;
import net.sf.cglib.beans.BeanMap;
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.util.CellRangeAddress;
@ -23,6 +25,7 @@ import java.util.List;
/**
* @author jipengfei
* @date 2017/05/27
*/
public class ExcelBuilderImpl implements ExcelBuilder {
@ -31,11 +34,11 @@ public class ExcelBuilderImpl implements ExcelBuilder {
public ExcelBuilderImpl(InputStream templateInputStream,
OutputStream out,
ExcelTypeEnum excelType,
boolean needHead) {
boolean needHead, WriteHandler writeHandler) {
try {
//初始化时候创建临时缓存目录,用于规避POI在并发写bug
POITempFile.createPOIFilesDirectory();
context = new WriteContext(templateInputStream, out, excelType, needHead);
context = new WriteContext(templateInputStream, out, excelType, needHead, writeHandler);
} catch (Exception e) {
throw new RuntimeException(e);
}
@ -99,10 +102,13 @@ public class ExcelBuilderImpl implements ExcelBuilder {
}
for (int i = 0; i < oneRowData.size(); i++) {
Object cellValue = oneRowData.get(i);
WorkBookUtil.createCell(row, i, context.getCurrentContentStyle(), cellValue, TypeUtil.isNum(cellValue));
Cell cell = WorkBookUtil.createCell(row, i, context.getCurrentContentStyle(), cellValue,
TypeUtil.isNum(cellValue));
if (null != context.getAfterWriteHandler()) {
context.getAfterWriteHandler().cell(i, cell);
}
}
}
private void addJavaObjectToExcel(Object oneRowData, Row row) {
int i = 0;
@ -113,7 +119,11 @@ public class ExcelBuilderImpl implements ExcelBuilder {
excelHeadProperty.getFormat());
CellStyle cellStyle = baseRowModel.getStyle(i) != null ? baseRowModel.getStyle(i)
: context.getCurrentContentStyle();
WorkBookUtil.createCell(row, i, cellStyle, cellValue, TypeUtil.isNum(excelHeadProperty.getField()));
Cell cell = WorkBookUtil.createCell(row, i, cellStyle, cellValue,
TypeUtil.isNum(excelHeadProperty.getField()));
if (null != context.getAfterWriteHandler()) {
context.getAfterWriteHandler().cell(i, cell);
}
i++;
}
@ -121,6 +131,9 @@ public class ExcelBuilderImpl implements ExcelBuilder {
private void addOneRowOfDataToExcel(Object oneRowData, int n) {
Row row = WorkBookUtil.createRow(context.getCurrentSheet(), n);
if (null != context.getAfterWriteHandler()) {
context.getAfterWriteHandler().row(n, row);
}
if (oneRowData instanceof List) {
addBasicTypeToExcel((List)oneRowData, row);
} else {

47
src/test/java/com/alibaba/easyexcel/test/WriteTest.java

@ -1,5 +1,6 @@
package com.alibaba.easyexcel.test;
import com.alibaba.easyexcel.test.listen.AfterWriteHandlerImpl;
import com.alibaba.easyexcel.test.model.WriteModel;
import com.alibaba.easyexcel.test.util.FileUtil;
import com.alibaba.excel.EasyExcelFactory;
@ -105,6 +106,52 @@ public class WriteTest {
}
@Test
public void writeV2007WithTemplateAndHandler() throws IOException {
InputStream inputStream = FileUtil.getResourcesFileInputStream("temp.xlsx");
OutputStream out = new FileOutputStream("/Users/jipengfei/2007.xlsx");
ExcelWriter writer = EasyExcelFactory.getWriterWithTempAndHandler(inputStream,out,ExcelTypeEnum.XLSX,true,
new AfterWriteHandlerImpl());
//写第一个sheet, sheet1 数据全是List<String> 无模型映射关系
Sheet sheet1 = new Sheet(1, 3);
sheet1.setSheetName("第一个sheet");
sheet1.setStartRow(20);
//设置列宽 设置每列的宽度
Map columnWidth = new HashMap();
columnWidth.put(0,10000);columnWidth.put(1,40000);columnWidth.put(2,10000);columnWidth.put(3,10000);
sheet1.setColumnWidthMap(columnWidth);
sheet1.setHead(createTestListStringHead());
//or 设置自适应宽度
//sheet1.setAutoWidth(Boolean.TRUE);
writer.write1(createTestListObject(), sheet1);
//写第二个sheet sheet2 模型上打有表头的注解,合并单元格
Sheet sheet2 = new Sheet(2, 3, WriteModel.class, "第二个sheet", null);
sheet2.setTableStyle(createTableStyle());
sheet2.setStartRow(20);
writer.write(createTestListJavaMode(), sheet2);
//写第三个sheet包含多个table情况
Sheet sheet3 = new Sheet(3, 0);
sheet3.setSheetName("第三个sheet");
sheet3.setStartRow(30);
Table table1 = new Table(1);
table1.setHead(createTestListStringHead());
writer.write1(createTestListObject(), sheet3, table1);
//写sheet2 模型上打有表头的注解
Table table2 = new Table(2);
table2.setTableStyle(createTableStyle());
table2.setClazz(WriteModel.class);
writer.write(createTestListJavaMode(), sheet3, table2);
writer.finish();
out.close();
}
@Test
public void writeV2003() throws IOException {

59
src/test/java/com/alibaba/easyexcel/test/listen/AfterWriteHandlerImpl.java

@ -0,0 +1,59 @@
package com.alibaba.easyexcel.test.listen;
import com.alibaba.excel.event.WriteHandler;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
public class AfterWriteHandlerImpl implements WriteHandler {
//
CellStyle cellStyle;
@Override
public void sheet(int sheetNo, Sheet sheet) {
Workbook workbook = sheet.getWorkbook();
//要锁定单元格需先为此表单设置保护密码,设置之后此表单默认为所有单元格锁定,可使用setLocked(false)为指定单元格设置不锁定。
//设置表单保护密码
sheet.protectSheet("your password");
//创建样式
cellStyle = workbook.createCellStyle();
//设置是否锁
cellStyle.setLocked(false);
}
@Override
public void row(int rowNum, Row row) {
Workbook workbook = row.getSheet().getWorkbook();
//设置行高
row.setHeight((short)20);
}
@Override
public void cell(int cellNum, Cell cell) {
Workbook workbook = cell.getSheet().getWorkbook();
Sheet currentSheet = cell.getSheet();
if (cellNum == 4 && cell.getRowIndex() == 30) {
//设置样式
//注意:样式最好采用公用样式,样式在创建sheet后创建,如果有多个样式也需要在创建sheet时候创建后面直接使用,不要每个Cell Create 一个样式,不然会导致报错 The maximum number
// of Cell Styles was exceeded.
cell.setCellStyle(cellStyle);
//设置备注
Drawing draw = currentSheet.createDrawingPatriarch();
Comment comment = draw.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, 4, 25, 9, 30));
XSSFRichTextString rtf = new XSSFRichTextString("添加批注内容收到货死的死哦多胡搜idsad是否会杜甫的范德萨发!1111");
Font commentFormatter = workbook.createFont();
commentFormatter.setFontName("宋体");
//设置字体大小
commentFormatter.setFontHeightInPoints((short)9);
rtf.applyFont(commentFormatter);
comment.setString(rtf);
comment.setAuthor("ceshi");
cell.setCellComment(comment);
}
}
}
Loading…
Cancel
Save