1、问题发现
2、分析问题
1) 分析源码
private File dir; @Override public File createTempFile(String prefix, String suffix) throws IOException { // Identify and create our temp dir, if needed if (dir == null) { dir = new File(System.getProperty("java.io.tmpdir"), "poifiles"); dir.mkdir(); if (System.getProperty("poi.keep.tmp.files") == null) dir.deleteOnExit(); } // Generate a unique new filename File newFile = File.createTempFile(prefix, suffix, dir); // Set the delete on exit flag, unless explicitly disabled if (System.getProperty("poi.keep.tmp.files") == null) newFile.deleteOnExit(); // All done return newFile; }
我们没有改变java.io.tmpdir的默认值,故默认/tmp。 故excel依赖的临时目录为/tmp/poifiles,而且此目录只有第一次使用时创建。后续linux服务器自动清理了一次/tmp目录,把/tmp/poifiles目录删除了。导致找不到依赖的临时目录。
首先我说一下这个类它默认的临时文件存放目录:
windows下:AppData\Local\Temp\poifiles文件夹下,生成一个叫poi-sxssf-sheet**************的文件
Linux系统下:会在/tmp/poifiles文件下生成该临时文件
3、解决问题
1)可以重启应用,治标不整根。
2)重新设置java.io.tmpdir的默认值
@Component public class ExcelConfig { private final static Logger logger = LoggerFactory.getLogger(ExcelConfig.class); @Value("${customconfig.applicationTmpPath}") private String applicationTmpPath; /** * 设置使用SXSSFWorkbook对象导出excel报表时,TempFile使用的临时目录,代替{java.io.tmpdir} */ @PostConstruct public void setExcelSXSSFWorkbookTmpPath() { String excelSXSSFWorkbookTmpPath = applicationTmpPath + "/poifiles"; File dir = new File(excelSXSSFWorkbookTmpPath); if (!dir.exists()) { dir.mkdirs(); } TempFile.setTempFileCreationStrategy(new TempFile.DefaultTempFileCreationStrategy(dir)); logger.info("setExcelSXSSFWorkbookTmpPath={}", excelSXSSFWorkbookTmpPath); } }
注:临时文件可以通过调用
workbook.dispose(); 删除
3)检查poi依赖的临时目录,如果不存在,先创建。我们使用poi时先检查临时目录下是否存在poifiles目录,不存在就创建。