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()方法最后再手动关闭流

经验分享 程序员 微信小程序 职场和发展