easyexcel 使用遇到“Can not close IO”异常处理
easyexcel 使用遇到“Can not close IO”异常处理
出现问题的最初代码如下:
主要是用easyexcel写入一堆excel表,最后在封装到zipOutputStream中输出压缩包文件
for (Map.Entry<String, PromoteLeaderExportDto> entry : map.entrySet()) {
OutputStream out = new ByteArrayOutputStream();
PromoteLeaderExportDto value = entry.getValue();
ClassPathResource classPathResource;
if ("绿色通道".equals(value.getApplyTypeName())) {
classPathResource = new ClassPathResource("模板01.xls");
} else {
classPathResource = new ClassPathResource("模板02.xls");
}
String k = entry.getKey();
//构建一个excel对象,这里注意type要是xls不能是xlsx,否则下面的写入后流会关闭,导致报错
excelWriter = EasyExcel.write(out).withTemplate(classPathResource.getInputStream()).build();
WriteSheet writeSheet = EasyExcel.writerSheet().registerWriteHandler(new EasyExcelHandler()).build();
excelWriter.fill(value, writeSheet);
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
List<QualityItemExportDto> qualityItemExportDtoList = value.getQualityItemExportDtoList();
excelWriter.fill(qualityItemExportDtoList, fillConfig, writeSheet);
Workbook workbook = excelWriter.writeContext().writeWorkbookHolder().getWorkbook();
workbook.write(out);
//创建压缩文件
ins[i] = outputStream2InputStream(out);
paths[i]=k;
i++;
}
ZipPlusUitl.zip(paths,ins,zipOutputStream);
zipOutputStream.flush();
然后运行的时候报错 Can not close IO. Stream closed
处理方法
首先找到问题点,重新dug,搜索报错点在那里加上断点
然后方法最开始打上断点
继续,重新调用接口
进入断点一步一步,到这里捕获异常,java.io.IOException: Stream closed
流关闭了,咋还能写入呢,所以就会异常被捕获,抛出Can not close IO.
我处理方式
重写一个plus继承ExcelWriter
public class ExcelWriterPlus extends ExcelWriter {
public ExcelWriterPlus(WriteWorkbook writeWorkbook) {
super(writeWorkbook);
}
@Override
protected void finalize() {
}
}
重写一个plus继承ExcelWriterBuilder (为了上面好实现)
public class ExcelWriterBuilderPlus extends ExcelWriterBuilder {
private WriteWorkbook writeWorkbook=new WriteWorkbook();
public static ExcelWriterBuilderPlus write(OutputStream outputStream) {
return write(outputStream, null);
}
public static ExcelWriterBuilderPlus write(OutputStream outputStream, Class head) {
ExcelWriterBuilderPlus excelWriterBuilder = new ExcelWriterBuilderPlus();
excelWriterBuilder.file(outputStream);
if (head != null) {
excelWriterBuilder.head(head);
}
return excelWriterBuilder;
}
@Override
public ExcelWriterBuilderPlus withTemplate(InputStream templateInputStream) {
writeWorkbook.setTemplateInputStream(templateInputStream);
return this;
}
@Override
public ExcelWriterPlus build() {
return new ExcelWriterPlus(writeWorkbook);
}
主要目的是让gc调用finalize(),ExcelWriter不对这个方法重写,避免去执行finish()方法最后再手动关闭流