easypoi导出报流被关闭Stream closed问题记录
遇到问题的情况是
多次调用easypoi导出接口就会报以下错误
报错:
java.io.IOException: Stream closed
或
cn.afterturn.easypoi.exception.excel.ExcelExportException: Excel导出错误
at cn.afterturn.easypoi.excel.export.base.BaseExportService.createCells(BaseExportService.java:153)
at cn.afterturn.easypoi.excel.export.ExcelBatchExportService.appendData(ExcelBatchExportService.java:108)
at com.wissun.mall.common.utils.ExcelUtils.exportBigExcel(ExcelUtils.java:106)
at com.wissun.mall.service.impl.SdkDistributorIncomeDailyServiceImpl.exportDistributorIncomeStatistics(SdkDistributorIncomeDailyServiceImpl.java:78)
at com.wissun.mall.api.controller.statistics.DistributorIncomeStatisticsController.exportDistributorIncomeStatistics(DistributorIncomeStatisticsController.java:74)
at com.wissun.mall.api.controller.statistics.DistributorIncomeStatisticsController$$FastClassBySpringCGLIB$$ee250fbe.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)
at com.wissun.mall.handler.aspect.BusinessOperateAspect.doAround(BusinessOperateAspect.java:95)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
问题代码
public static Workbook exportBigExcel(ExportParams entity, Class<?> pojoClass, Collection<?> dataSet) throws IOException {
ExcelBatchExportService batachServer = ExcelBatchExportService
.getExcelBatchExportService(entity, pojoClass);
return batachServer.appendData(dataSet);
}
workbook.write(response.getOutputStream());
自己遇到的原因以及解决方法如下
因为在ExcelBatchExportService类中缓存了线程变量
public static ExcelBatchExportService getExcelBatchExportService(ExportParams entity, Class<?> pojoClass) {
if (THREAD_LOCAL.get() == null) {
ExcelBatchExportService batchServer = new ExcelBatchExportService();
batchServer.init(entity, pojoClass);
//就是这一句,缓存在了本地线程中
THREAD_LOCAL.set(batchServer);
}
return (ExcelBatchExportService)THREAD_LOCAL.get();
}
解决方法:在每次执行完导出后需要执行:closeExportBigExcel(),删除线程缓存
/**
* 关闭excel导出Service对象,清空本地线程缓存
*/
public static void closeExportBigExcel() {
ExcelBatchExportService batchService = ExcelBatchExportService.getCurrentExcelBatchExportService();
if (batchService != null) {
batchService.closeExportBigExcel();
}
}
最终代码
public static Workbook exportBigExcel(ExportParams entity, Class<?> pojoClass, Collection<?> dataSet) throws IOException {
ExcelBatchExportService batachServer = ExcelBatchExportService
.getExcelBatchExportService(entity, pojoClass);
return batachServer.appendData(dataSet);
}
//执行完数据写入excel后,关闭(删除)ExcelBatchExportService 对象
closeExportBigExcel();
workbook.write(response.getOutputStream());