|
|
|
@ -1,6 +1,8 @@
|
|
|
|
|
package ${basePackage}.frame.excel;
|
|
|
|
|
|
|
|
|
|
import com.alibaba.excel.EasyExcel;
|
|
|
|
|
import com.alibaba.excel.context.AnalysisContext;
|
|
|
|
|
import com.alibaba.excel.exception.ExcelDataConvertException;
|
|
|
|
|
import com.alibaba.excel.metadata.Head;
|
|
|
|
|
import com.alibaba.excel.support.ExcelTypeEnum;
|
|
|
|
|
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
|
|
|
@ -14,7 +16,7 @@ import ${basePackage}.frame.excel.handler.HeadWriteHandler;
|
|
|
|
|
import ${basePackage}.frame.excel.handler.WCellWriteHandler;
|
|
|
|
|
import ${basePackage}.frame.excel.handler.WRowWriteHandler;
|
|
|
|
|
import ${basePackage}.frame.excel.handler.WSheetWriteHandler;
|
|
|
|
|
import ${basePackage}.frame.excel.listener.CheckHeadReadListener;
|
|
|
|
|
import ${basePackage}.frame.excel.listener.WReadListener;
|
|
|
|
|
import ${basePackage}.frame.utils.ClassUtil;
|
|
|
|
|
import ${basePackage}.frame.utils.FileUtil;
|
|
|
|
|
import ${basePackage}.frame.utils.ValidationUtil;
|
|
|
|
@ -60,7 +62,7 @@ public class WExcel<T> {
|
|
|
|
|
/**
|
|
|
|
|
* 错误Map key:行号,String:错误集
|
|
|
|
|
*/
|
|
|
|
|
private Map<Integer, String> errMap;
|
|
|
|
|
private Map<Integer, List<String>> errMap;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 样式合集,请参考{@link WSheetWriteHandler#beforeSheetCreate}.
|
|
|
|
@ -103,8 +105,6 @@ public class WExcel<T> {
|
|
|
|
|
.registerWriteHandler(new HeadWriteHandler() {
|
|
|
|
|
@Override
|
|
|
|
|
protected void handlerHead(Head head) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WHead wHead = new WHead(head);
|
|
|
|
|
Field field = fieldMap.get(wHead.getHead().getFieldName());
|
|
|
|
|
|
|
|
|
@ -126,6 +126,16 @@ public class WExcel<T> {
|
|
|
|
|
wHeads.addAll(wHeadMap.values());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 添加数据集
|
|
|
|
|
*
|
|
|
|
|
* @param os 待添加数据集
|
|
|
|
|
* @return WExcel
|
|
|
|
|
*/
|
|
|
|
|
public WExcel addDatas(List<T> os) {
|
|
|
|
|
return addDatas(os, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 添加数据集
|
|
|
|
|
*
|
|
|
|
@ -140,6 +150,16 @@ public class WExcel<T> {
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 添加数据
|
|
|
|
|
*
|
|
|
|
|
* @param o 待添加数据
|
|
|
|
|
* @return WExcel
|
|
|
|
|
*/
|
|
|
|
|
public WExcel addData(T o) {
|
|
|
|
|
return addData(o, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 添加数据
|
|
|
|
|
*
|
|
|
|
@ -154,7 +174,9 @@ public class WExcel<T> {
|
|
|
|
|
if ((validate == null || validate.isEmpty()) && processor != null) {
|
|
|
|
|
List<String> exec = processor.exec(o, this.data.size());
|
|
|
|
|
if (exec != null && exec.size() > 0) {
|
|
|
|
|
errMap.put(data.size() - 1, String.join("\r\n", exec));
|
|
|
|
|
errMap.computeIfAbsent(data.size(), k -> new ArrayList<>());
|
|
|
|
|
List<String> errs = errMap.get(data.size());
|
|
|
|
|
errs.addAll(exec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.data.add(o);
|
|
|
|
@ -171,7 +193,7 @@ public class WExcel<T> {
|
|
|
|
|
/**
|
|
|
|
|
* @return Excel文件字节数组
|
|
|
|
|
*/
|
|
|
|
|
public byte[] getByte() {
|
|
|
|
|
public byte[] getBytes() {
|
|
|
|
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
|
|
|
EasyExcel.write(outputStream)
|
|
|
|
|
.head(this.clazz)
|
|
|
|
@ -179,8 +201,8 @@ public class WExcel<T> {
|
|
|
|
|
.registerConverter(new BooleanConverter())
|
|
|
|
|
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
|
|
|
|
.registerWriteHandler(new WSheetWriteHandler(wHeads, styles))
|
|
|
|
|
.registerWriteHandler(new WRowWriteHandler(wHeads.size(), errMap))
|
|
|
|
|
.registerWriteHandler(new WCellWriteHandler(styles, errMap))
|
|
|
|
|
.registerWriteHandler(new WRowWriteHandler(wHeads, errMap))
|
|
|
|
|
.registerWriteHandler(new WCellWriteHandler(wHeads, styles, errMap))
|
|
|
|
|
.sheet(this.name).doWrite(data);
|
|
|
|
|
return outputStream.toByteArray();
|
|
|
|
|
}
|
|
|
|
@ -191,7 +213,7 @@ public class WExcel<T> {
|
|
|
|
|
* @param file 文件
|
|
|
|
|
*/
|
|
|
|
|
public void toFile(File file) {
|
|
|
|
|
byte[] aByte = getByte();
|
|
|
|
|
byte[] aByte = getBytes();
|
|
|
|
|
FileUtil.writeBytesToFile(aByte, file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -217,6 +239,28 @@ public class WExcel<T> {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param bytes 字节数组
|
|
|
|
|
* @return WExcel
|
|
|
|
|
* @throws TemplateNotMatchException
|
|
|
|
|
* @throws IOException
|
|
|
|
|
*/
|
|
|
|
|
public WExcel<T> read(byte[] bytes) throws TemplateNotMatchException, IOException {
|
|
|
|
|
return read(bytes, ExcelTypeEnum.XLSX, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param bytes 字节数组
|
|
|
|
|
* @param processor 执行器
|
|
|
|
|
* @return WExcel
|
|
|
|
|
* @throws TemplateNotMatchException
|
|
|
|
|
* @throws IOException
|
|
|
|
|
*/
|
|
|
|
|
public WExcel<T> read(byte[] bytes, Processor<T> processor) throws TemplateNotMatchException, IOException {
|
|
|
|
|
return read(bytes, ExcelTypeEnum.XLSX, processor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param bytes 字节数组
|
|
|
|
|
* @param et Excel文件类型
|
|
|
|
|
* @param processor 执行器
|
|
|
|
|
* @return WExcel
|
|
|
|
|
* @throws TemplateNotMatchException
|
|
|
|
@ -227,9 +271,31 @@ public class WExcel<T> {
|
|
|
|
|
return read(stream, et, processor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param in 输入流
|
|
|
|
|
* @return WExcel
|
|
|
|
|
* @throws TemplateNotMatchException
|
|
|
|
|
* @throws IOException
|
|
|
|
|
*/
|
|
|
|
|
public WExcel<T> read(InputStream in) throws TemplateNotMatchException {
|
|
|
|
|
return read(in, ExcelTypeEnum.XLSX, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param in 输入流
|
|
|
|
|
* @param processor 执行器
|
|
|
|
|
* @return WExcel
|
|
|
|
|
* @throws TemplateNotMatchException
|
|
|
|
|
* @throws IOException
|
|
|
|
|
*/
|
|
|
|
|
public WExcel<T> read(InputStream in, Processor<T> processor) throws TemplateNotMatchException {
|
|
|
|
|
return read(in, ExcelTypeEnum.XLSX, processor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param in 输入流
|
|
|
|
|
* @param processor 执行器
|
|
|
|
|
* @param et Excel文件类型
|
|
|
|
|
* @return WExcel
|
|
|
|
|
* @throws TemplateNotMatchException
|
|
|
|
|
* @throws IOException
|
|
|
|
@ -241,35 +307,32 @@ public class WExcel<T> {
|
|
|
|
|
.excelType(et)
|
|
|
|
|
.head(this.clazz)
|
|
|
|
|
.registerConverter(new BooleanConverter())
|
|
|
|
|
.registerReadListener(new CheckHeadReadListener(wHeads, e))
|
|
|
|
|
// .registerReadListener(new AnalysisEventListener<T>() {
|
|
|
|
|
//
|
|
|
|
|
// @Override
|
|
|
|
|
// public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// @Override
|
|
|
|
|
// public void invoke(T o, AnalysisContext analysisContext) {
|
|
|
|
|
// if (processor != null) {
|
|
|
|
|
// List<String> exec = processor.exec(o, data.size());
|
|
|
|
|
// if (exec != null && exec.size() > 0) {
|
|
|
|
|
// errMap.put(data.size(), String.join(",", exec));
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// data.add(o);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// @Override
|
|
|
|
|
// public void doAfterAllAnalysed(AnalysisContext analysisContext) {
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// @Override
|
|
|
|
|
// public boolean hasNext(AnalysisContext context) {
|
|
|
|
|
// return super.hasNext(context);
|
|
|
|
|
// }
|
|
|
|
|
// })
|
|
|
|
|
.registerReadListener(new WReadListener<T>(wHeads, e) {
|
|
|
|
|
@Override
|
|
|
|
|
public void onException(Exception exception, AnalysisContext context) throws Exception {
|
|
|
|
|
if (exception instanceof ExcelDataConvertException) {
|
|
|
|
|
ExcelDataConvertException convertException = (ExcelDataConvertException) exception;
|
|
|
|
|
errMap.computeIfAbsent(data.size(), k -> new ArrayList<>());
|
|
|
|
|
List<String> errs = errMap.get(data.size());
|
|
|
|
|
errs.add(convertException.getCause().getMessage());
|
|
|
|
|
}else {
|
|
|
|
|
super.onException(exception, context);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void invoke(T o) {
|
|
|
|
|
if (processor != null) {
|
|
|
|
|
List<String> exec = processor.exec(o, data.size());
|
|
|
|
|
if (exec != null && exec.size() > 0) {
|
|
|
|
|
errMap.computeIfAbsent(data.size(), k -> new ArrayList<>());
|
|
|
|
|
List<String> errs = errMap.get(data.size());
|
|
|
|
|
errs.addAll(exec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
data.add(o);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.sheet().doRead();
|
|
|
|
|
if (e[0] != null) {
|
|
|
|
|
throw e[0];
|
|
|
|
@ -281,48 +344,17 @@ public class WExcel<T> {
|
|
|
|
|
List<String> exec(T t, int index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) throws TemplateNotMatchException, IOException {
|
|
|
|
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
System.out.println("数据创建开始:" + dateFormat.format(new Date()));
|
|
|
|
|
// 写
|
|
|
|
|
List<DemoData> visitors = new ArrayList<>();
|
|
|
|
|
for (int i = 0; i < 100; i++) {
|
|
|
|
|
DemoData demoData = new DemoData();
|
|
|
|
|
demoData.setStr1("我是标题Str1" + i);
|
|
|
|
|
demoData.setStr2("我是标题Str2" + i);
|
|
|
|
|
demoData.setStr3("我是标题Str3" + i);
|
|
|
|
|
demoData.setStr4("我是标题Str4" + i);
|
|
|
|
|
demoData.setSint((short) 1);
|
|
|
|
|
demoData.setMint(1);
|
|
|
|
|
demoData.setLint(1L);
|
|
|
|
|
demoData.setDbn(0.01);
|
|
|
|
|
demoData.setFln(0.01f);
|
|
|
|
|
demoData.setDate(new Date());
|
|
|
|
|
visitors.add(demoData);
|
|
|
|
|
}
|
|
|
|
|
System.out.println("数据创建完成:" + dateFormat.format(new Date()));
|
|
|
|
|
// new WExcel<>(DemoData.class).addDatas(visitors, null).toFile(new File("D:\\xx.xlsx"));
|
|
|
|
|
System.out.println("数据导出完成:" + dateFormat.format(new Date()));
|
|
|
|
|
|
|
|
|
|
System.out.println();
|
|
|
|
|
|
|
|
|
|
// 读
|
|
|
|
|
System.out.println("数据导入开始:" + dateFormat.format(new Date()));
|
|
|
|
|
WExcel<DemoData> wExcel = new WExcel<>(DemoData.class).read(new File("D:\\xx.xlsx"), new Processor<DemoData>() {
|
|
|
|
|
@Override
|
|
|
|
|
public List<String> exec(DemoData demoData, int index) {
|
|
|
|
|
if (index % 50 == 0) {
|
|
|
|
|
// System.out.println(MapperUtil.toJson(demoData));
|
|
|
|
|
return Arrays.asList("测试,第" + index + "条有错误");
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
System.out.println("数据导入完成:" + dateFormat.format(new Date()));
|
|
|
|
|
System.out.println();
|
|
|
|
|
System.out.println("错误导出开始:" + dateFormat.format(new Date()));
|
|
|
|
|
wExcel.toFile(new File("D:\\xx-err.xlsx"));
|
|
|
|
|
System.out.println("错误导出结束:" + dateFormat.format(new Date()));
|
|
|
|
|
System.out.println();
|
|
|
|
|
/**
|
|
|
|
|
* @return 是否有错
|
|
|
|
|
*/
|
|
|
|
|
public boolean hasError() {
|
|
|
|
|
return !errMap.isEmpty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return 获取名称
|
|
|
|
|
*/
|
|
|
|
|
public String getName() {
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|