poi或者jxl在匯出大量資料的時候,由於它們將每乙個單元格生都成乙個cell物件,所以很容易導致記憶體溢位。解決這個問題,唯一的辦法是弄清楚excel的二進位制格式(汗),並且用流的方式讀寫excel。poi和jxl其實提供了二進位制方式讀寫excel的api,只是因為缺少文件和例項,所以使用的人不多。我編寫了這個簡單的合併excel的類,它只適合合併結構相同的多個excel檔案。好在這個功能已經可以解決資料匯出產生oom的問題:將資料分批匯出然後合併。
下面的**使用poi3.1,合併11個3000多行的文件用時約6秒,我實在找不到更多的測試用的文件了。
@suppresswarnings("unchecked")
public class xlsmergeutil
listrootrecords = getrecords(inputs[0]);
workbook workbook = workbook.createworkbook(rootrecords);
listsheets = getsheets(workbook, rootrecords);
if(sheets == null || sheets.size() == 0)
//以第一篇文件的最後乙個sheet為根,以後的資料都追加在這個sheet後面
sheet rootsheet = sheets.get(sheets.size() - 1);
int rootrows = getrowsofsheet(rootsheet); //記錄第一篇文件的行數,以後的行數在此基礎上增加
rootsheet.setloc(rootsheet.getdimsloc());
mapmap = new hashmap(10000);
for (int i = 1; i < inputs.length; i++)
//sst記錄,sst儲存xls檔案中唯一的string,各個string都是對應著sst記錄的索引
else if (record.getsid() == sstrecord.sid)
} else if (record.getsid() == labelsstrecord.sid)
//追加valuecell
if (record instanceof cellvaluerecordinte***ce)
}rootrows += rowsofcurxls;
}byte data = getbytes(workbook, sheets.toarray(new sheet[0]));
write(out, data);
}static void write(outputstream out, byte data) catch (ioexception e) finally catch (ioexception e) }}
static listgetsheets(workbook workbook, list records)
sheets.add(sh);
}return sheets;
}static int getrows(listrecords)
}return row;
}static int getrowsofsheet(sheet sheet)
return rows;
}@suppresswarnings("deprecation")
static listgetrecords(inputstream input) catch (ioexception e) ", e.getmessage());
e.printstacktrace();
}return collections.empty_list;
}static void convertlabelrecords(list records, int offset, workbook workbook) }}
public static byte getbytes(workbook workbook, sheet sheets)
int totalsize = workbook.getsize();
// pre-calculate all the sheet sizes and set bof indexes
int estimatedsheetsizes = new int[nsheets];
for (int k = 0; k < nsheets; k++)
byte retval = new byte[totalsize];
int pos = workbook.serialize(0, retval);
for (int k = 0; k < nsheets; k++)
pos += serializedsize;
}return retval;
}public static void main(string args) throws exception
outputstream out = new fileoutputstream(path + "xx.xls");
long t1 = system.currenttimemillis();
merge(inputs, out);
system.out.println(system.currenttimemillis() - t1);//簡陋的測試一下時間}}
解決大批量資料匯出Excel產生記憶體溢位的方案
poi或者jxl在匯出大量資料的時候,由於它們將每乙個單元格生都成乙個cell物件,所以很容易導致記憶體溢位。解決這個問題,唯一的辦法是弄清楚excel的二進位制格式 汗 並且用流的方式讀寫excel。poi和jxl其實提供了二進位制方式讀寫excel的api,只是因為缺少文件和例項,所以使用的人不...
solr大批量資料匯出
需求 有100個core,每個core4000w資料量。把所有資料匯出來。方案1.直接對每個core通過httpsolrclient先取出總條數,然後通過每次分頁讀n行,直到讀完,這個方案肯定不行,因為越到後面,讀取速度越慢,不用想都要很長時間。方案2.深度分頁 通過游標,可以使分頁速度很快。sol...
關於SXSSFWorkbook匯出大批量資料的問題
前段時間做了乙個匯出大批量資料的功能,但是由於資料過多使用sxssfworkbook會出現記憶體溢位的問題,主要有兩個地方容易溢位。1.乙個是從資料看讀取資料到記憶體時溢位,基本資料超過20w或者2m時會溢位 這個時候改 xms1024m xmx1024m xx permsize 512m xx m...