問題:使用poi導出excel,數據量過大致使內存溢出java
解決思路:一、多sheet導出apache
二、生成多個excel打包下載app
三、生成csv下載dom
本文使用的是第二個思路,代碼以下:工具
poiUtil工具類測試
package com.rratchet.scala.ms.util; import org.apache.poi.hssf.usermodel.*; import javax.servlet.http.HttpServletResponse; import java.io.*; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * poi 公用方法 */ public class PoiUtil { /** * 導出excel * @param sheetName * @param title * @param values * @param response * @param fileName * @param charsetName */ public static void exportExcel(String sheetName, String []title, String [][]values, HttpServletResponse response, String fileName,String charsetName){ // 第一步,建立一個HSSFWorkbook,對應一個Excel文件 HSSFWorkbook wb= new HSSFWorkbook(); createContent( wb,sheetName,title,values); //響應到客戶端 try { fileName = new String(fileName.getBytes(charsetName),"ISO8859-1"); response.setContentType("application/octet-stream;charset="+charsetName); response.setHeader("Content-Disposition", "attachment;filename="+ fileName); response.addHeader("Pargam", "no-cache"); response.addHeader("Cache-Control", "no-cache"); OutputStream os = response.getOutputStream(); wb.write(os); os.flush(); os.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 建立excel * @param sheetName sheet名 * @param title 標題 * @param values 內容 * @param fileName 文件名 * @param filePath 文件地址 * @return excel保存路徑 * @throws Exception */ public static String createExcel(String sheetName, String []title, String [][]values,String fileName,String filePath){ String resultPath=filePath+"/"+fileName; // 第一步,建立一個HSSFWorkbook,對應一個Excel文件 HSSFWorkbook wb= new HSSFWorkbook(); createContent( wb,sheetName,title,values); //判斷是否存在目錄. 不存在則建立 isChartPathExist(filePath); //建立Excel文件 isFileExist(filePath+"/"+fileName); try{ FileOutputStream output=new FileOutputStream(filePath+"/"+fileName); wb.write(output);//寫入磁盤 output.close(); }catch (Exception e){ resultPath=""; e.printStackTrace(); } return resultPath; } /** * 建立excel內容 * @param wb * @param sheetName * @param title * @param values */ private static void createContent(HSSFWorkbook wb, String sheetName, String []title, String [][]values){ // 第二步,在workbook中添加一個sheet,對應Excel文件中的sheet HSSFSheet sheet = wb.createSheet(sheetName); // 第三步,在sheet中添加表頭第0行,注意老版本poi對Excel的行數列數有限制 HSSFRow row = sheet.createRow(0); // 第四步,建立單元格,並設置值表頭 設置表頭居中 HSSFCellStyle style = wb.createCellStyle(); // 建立一個居中格式 style.setAlignment(HorizontalAlignment.CENTER); //聲明列對象 HSSFCell cell = null; //建立標題 for(int i=0;i<title.length;i++){ cell = row.createCell(i); cell.setCellValue(title[i]); cell.setCellStyle(style); } //建立內容 for(int i=0;i<values.length;i++){ row = sheet.createRow(i + 1); for(int j=0;j<values[i].length;j++){ //將內容按順序賦給對應的列對象 row.createCell(j).setCellValue(values[i][j]); } } } /** * 判斷文件夾是否存在,若是不存在則新建 * * @param dirPath 文件夾路徑 */ private static void isChartPathExist(String dirPath) { File file = new File(dirPath); if (!file.exists()) { file.mkdirs(); } } /** * 判斷文件是否存在,不存在則建立文件 * @param dirPath */ public static void isFileExist(String dirPath){ File file = new File(dirPath); if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } } }
fileUtil工具類spa
/** * 壓縮文件(zip) * @param srcFiles * @param zippath * @throws Exception */ public static void Zip(List<File> srcFiles , String zippath)throws Exception { File file=new File(zippath); if(!file.exists()){ file.createNewFile(); } FileOutputStream out = new FileOutputStream(file); long start = System.currentTimeMillis(); ZipOutputStream zos = null ; try { zos = new ZipOutputStream(out); for (File srcFile : srcFiles) { byte[] buf = new byte[4096 * 1024]; zos.putNextEntry(new ZipEntry(srcFile.getName())); int len; FileInputStream in = new FileInputStream(srcFile); while ((len = in.read(buf)) != -1){ zos.write(buf, 0, len); } zos.closeEntry(); in.close(); } long end = System.currentTimeMillis(); System.out.println("壓縮完成,耗時:" + (end - start) +" ms"); } catch (Exception e) { throw new RuntimeException("zip error from ZipUtils",e); }finally{ if(zos != null){ try { zos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** *獲取路徑下全部文件(遞歸遍歷) * @param fileList * @param path * @throws Exception */ public static void getFiles(List<File>fileList, String path){ try { File file = new File(path); if(file.isDirectory()){ File []files = file.listFiles(); for(File fileIndex:files){ //若是這個文件是目錄,則進行遞歸搜索 if(fileIndex.isDirectory()){ getFiles(fileList,fileIndex.getPath()); }else { //若是文件是普通文件,則將文件句柄放入集合中 fileList.add(fileIndex); } } } }catch (Exception e){ e.printStackTrace(); } }
測試方法scala
public static void main(String[] args) throws IOException { String filePath="D:/home/"+UUID.randomUUID().toString(); String[] titles = {"上傳時間", "鏈接時間"}; for(int i=0;i<5;i++){ String time = DateUtil.getDateyyyymmddFormat(new Date()); //excel文件名 String fileName = "鏈接記錄_" + i + ".xls"; //sheet名 String sheetName = time; String[][] content = new String[20][2]; for (int j = 0; j < 20; j++) { content[j][0] = "20190-05-29"+"_"+j; content[j][1] = "s"+j; } PoiUtil.createExcel(sheetName,titles, content, fileName, filePath); } List<File> list=new ArrayList<>(); //遞歸獲取文件夾下全部內容 FileUtils.getFiles(list,filePath); try { FileUtils.Zip(list,"D:/home/測試.zip"); //刪除生成的excel FileUtils.deleteFolderAndFile(filePath); } catch (Exception e) { e.printStackTrace(); } }