alibaba / easyexcel

快速、简洁、解决大文件内存溢出的java处理Excel工具
https://easyexcel.opensource.alibaba.com
Apache License 2.0
32.44k stars 7.54k forks source link

多线程调用excelWriter.write时,出现 java.io.IOException: Stream closed #2358

Closed wulihuawuqia closed 2 years ago

wulihuawuqia commented 2 years ago

建议先去看文档 快速开始常见问题 异常代码

public void test() throws Exception {
        // 方法2 如果写到不同的sheet 同一个对象
        String fileName = TestFileUtil.getPath() + "large" + System.currentTimeMillis() + ".xlsx";
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为红色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)20);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 背景绿色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short)20);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
            new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        ExcelWriter excelWriter = EasyExcel.write(fileName, LargeData.class).registerWriteHandler(
            horizontalCellStyleStrategy).build();
        WriteSheet writeSheet = EasyExcel.writerSheet("1234").build();
        ExecutorService  pool = new ThreadPoolExecutor(4, 8,
            1999, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(100),
            new ThreadPoolExecutor.CallerRunsPolicy());
        CountDownLatch countDownLatch = new CountDownLatch(99);
        excelWriter.write(data20(), writeSheet);
        for (int j = 0; j < 100; j++) {
            pool.submit(() -> {
                try {
                    excelWriter.write(data20(), writeSheet);
                } catch (Exception e) {
                    LOGGER.error("excelWriter.write error", e);
                } finally {
                    countDownLatch.countDown();
                }
                LOGGER.info("fill success. countDownLatch = {}", countDownLatch.getCount());
            });
        }
        countDownLatch.await();
        LOGGER.error("fill end countDownLatch = {}========================================", countDownLatch.getCount());
        excelWriter.finish();
    }

异常提示 2022-03-15 18:48:31.855 ERROR [pool-1-thread-3] com.alibaba.easyexcel.test.temp.WriteLargeTest:79 - excelWriter.write error java.lang.RuntimeException: java.io.IOException: Stream closed at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:148) at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:65) at com.alibaba.excel.util.WorkBookUtil.createRow(WorkBookUtil.java:88) at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.addOneRowOfDataToExcel(ExcelWriteAddExecutor.java:72) at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.add(ExcelWriteAddExecutor.java:58) at com.alibaba.excel.write.ExcelBuilderImpl.addContent(ExcelBuilderImpl.java:59) at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:73) at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:50) at com.alibaba.easyexcel.test.temp.WriteLargeTest.lambda$test$0(WriteLargeTest.java:77) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: java.io.IOException: Stream closed at java.base/java.io.BufferedWriter.ensureOpen(BufferedWriter.java:107) at java.base/java.io.BufferedWriter.write(BufferedWriter.java:224) at java.base/java.io.Writer.write(Writer.java:249) at org.apache.poi.xssf.streaming.SheetDataWriter.beginRow(SheetDataWriter.java:214) at org.apache.poi.xssf.streaming.SheetDataWriter.writeRow(SheetDataWriter.java:204) at org.apache.poi.xssf.streaming.SXSSFSheet.flushOneRow(SXSSFSheet.java:1876) at org.apache.poi.xssf.streaming.SXSSFSheet.flushRows(SXSSFSheet.java:1851) at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:146) ... 14 common frames omitted 建议描述 多线程调用excelWriter.write时,出现 java.io.IOException: Stream closed

knight6236 commented 2 years ago

建议先去看文档 快速开始常见问题 异常代码

public void test() throws Exception {
        // 方法2 如果写到不同的sheet 同一个对象
        String fileName = TestFileUtil.getPath() + "large" + System.currentTimeMillis() + ".xlsx";
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为红色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)20);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 背景绿色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short)20);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
            new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        ExcelWriter excelWriter = EasyExcel.write(fileName, LargeData.class).registerWriteHandler(
            horizontalCellStyleStrategy).build();
        WriteSheet writeSheet = EasyExcel.writerSheet("1234").build();
        ExecutorService  pool = new ThreadPoolExecutor(4, 8,
            1999, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(100),
            new ThreadPoolExecutor.CallerRunsPolicy());
        CountDownLatch countDownLatch = new CountDownLatch(99);
        excelWriter.write(data20(), writeSheet);
        for (int j = 0; j < 100; j++) {
            pool.submit(() -> {
                try {
                    excelWriter.write(data20(), writeSheet);
                } catch (Exception e) {
                    LOGGER.error("excelWriter.write error", e);
                } finally {
                    countDownLatch.countDown();
                }
                LOGGER.info("fill success. countDownLatch = {}", countDownLatch.getCount());
            });
        }
        countDownLatch.await();
        LOGGER.error("fill end countDownLatch = {}========================================", countDownLatch.getCount());
        excelWriter.finish();
    }

异常提示 2022-03-15 18:48:31.855 ERROR [pool-1-thread-3] com.alibaba.easyexcel.test.temp.WriteLargeTest:79 - excelWriter.write error java.lang.RuntimeException: java.io.IOException: Stream closed at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:148) at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:65) at com.alibaba.excel.util.WorkBookUtil.createRow(WorkBookUtil.java:88) at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.addOneRowOfDataToExcel(ExcelWriteAddExecutor.java:72) at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.add(ExcelWriteAddExecutor.java:58) at com.alibaba.excel.write.ExcelBuilderImpl.addContent(ExcelBuilderImpl.java:59) at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:73) at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:50) at com.alibaba.easyexcel.test.temp.WriteLargeTest.lambda$test$0(WriteLargeTest.java:77) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: java.io.IOException: Stream closed at java.base/java.io.BufferedWriter.ensureOpen(BufferedWriter.java:107) at java.base/java.io.BufferedWriter.write(BufferedWriter.java:224) at java.base/java.io.Writer.write(Writer.java:249) at org.apache.poi.xssf.streaming.SheetDataWriter.beginRow(SheetDataWriter.java:214) at org.apache.poi.xssf.streaming.SheetDataWriter.writeRow(SheetDataWriter.java:204) at org.apache.poi.xssf.streaming.SXSSFSheet.flushOneRow(SXSSFSheet.java:1876) at org.apache.poi.xssf.streaming.SXSSFSheet.flushRows(SXSSFSheet.java:1851) at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:146) ... 14 common frames omitted 建议描述 多线程调用excelWriter.write时,出现 java.io.IOException: Stream closed

我也遇到了同样的问题,解决了踢我一jio

zhuangjiaju commented 2 years ago

不支持并发