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目錄,不存在就創建。