POI或者JXL在導出大量數據的時候,因爲它們將每個單元格生都成一個Cell對象,因此很容易致使內存溢出。app
一、經過jx1最新版本的採用臨時文件寫入EXCEL功能,設定臨時文件的位置,能夠有效的避免內存溢出:this
wbSetting.setUseTemporaryFileDuringWrite(true);
wbSetting.setTemporaryFileDuringWriteDirectory(new File(excelPath));//臨時文件夾的位置
二、EXCEL獲取的list集合先讀取數據總行數,再經過ROWNUM進行控制,設定每次讀取多少行數據,好比一個List設定爲50000;excel
WorkbookSettings wbSetting = new WorkbookSettings();
wbSetting.setUseTemporaryFileDuringWrite(true);
wbSetting.setTemporaryFileDuringWriteDirectory(new File(excelPath));//臨時文件夾的位置
workbook = Workbook.createWorkbook(new File(fullPath),wbSetting);
int returnCount=0;
if(null!=pager)
{
returnCount = BrasDatabase.getReturnCount(pager.getStartTime(),
pager.getEndTime(), pager);
}
if (returnCount > 0) {
pager.setPageSize(50000);
pager.setTotalRows(returnCount);// 獲取總行數
pager.setNewTotalPages(pager.getTotalRows()); // 總頁數
for (int i = 1; i <= pager.getTotalPages(); i++) {
pager.setCurrentPage(i); // 當前頁面d
List<BrasAuth> list = BrasDatabase
.getBrasAuthResultByIpToExcelList(pager
.getStartTime(), pager.getEndTime(), pager);
this.createExcel(list,excelFilePath);
list.clear();
}
}
三、在寫入EXCEL的時候,將讀取的LIST分割,每50000條數據生成一個EXCEL的sheet(一個sheet最多能存儲60000多行數據),再寫入,寫入的時候,若是設置了採用臨時文件寫入的話,jx1會自動採用生成臨時文件的方式寫入EXCEL:orm
for(int i=1;i<=list.size();i++)
{
if(i%50000==0)
{
sheetName=format.format(new Date());
toExcel(list.subList(reNum, i),sheetName);
reNum=i;
}
}對象
------------------------------------------------------------------------------------------------------------------------------圖片
寫文本格式的Excel文件,而不是用POI等生成二進制的文件, 能夠避免建立大批量的對象時內存溢出.代碼以下能夠做爲參考:
第一種格式,CSV,最簡單的,格式最差,最基本的行列,不能合併,不能設置着色,
第二種,HTML格式的,如:"<TABLE>....</TABLE>"這樣的文本,後輟名改成XLS就能夠了,能夠設置跨行列的合併,能夠着色,圖片沒試過,估計是能夠的,還能夠設置單元格對齊,單元格的格式等內存
public static boolean createExcelFileByStream(String path, List list) {
try {
//定義表頭
String userxlsinfo = "序號\t用戶ID\t姓名\t手機\t留言信息";
File file = new File("c:\\streamExcel.xls");
if (file.isFile()) {
file.mkdir();
}
FileOutputStream out = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(out, "GB2312");
BufferedWriter bw = new BufferedWriter(osw);
// 建立表頭
String sheader = userxlsinfo;
sheader += "\r\n";
bw.write(sheader);
if (list != null) {
// List list 此處能夠遍歷list對象
for (int i = 0; i < 5; i++) {
StringBuffer mess = new StringBuffer();
// 用戶信息
mess.append((i + 1) + "\t");
mess.append((i + 1) + "\t");
mess.append((i + 1) + "\t");
mess.append((i + 1) + "\t");
mess.append((i + 1) + "\t");
mess.append("\r\n");
System.out.println(i);
bw.write(mess.toString());
}
}
bw.close();
osw.close();
out.close();
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
注意:表頭部分和數據部分的間隔必定要用'\t ' 若是改用','號則導出文件用excel打開展現會有問題get