Obecnie używamy XSSF do eksportowania zapisów przechowywanych w DB do Excela i pobierania go. Zgodnie z naszym wymaganiem, musimy zezwolić użytkownikowi na pobranie 3 milionów rekordów.
W XSSF mamy do czynienia z OutOfMemoryError: przekroczono limit narzutów GC.
Zrobiłem kilka badań i dowiedziałem się, że XSSF jestgłodny pamięci. Czy ktoś może mi zaproponować lepszy sposób na osiągnięcie mojego wymagania. Należy pamiętać, że muszę pobrać dane w formacie Excela i nie chcę pisać bezpośrednio na żadnym dysku.
Odpowiedzi:
0 dla odpowiedzi № 1Możesz użyć POI API. Udało nam się zaimplementować przesyłanie strumienioweduże pliki Excela w naszych programach za pomocą API POI. Ważne jest, aby zachować rozmiar wiersza, który jest przechowywany w pamięci na niskim poziomie, reszta jest w zasadzie wykonywana na dysku.
Możesz także ustawić: SXSSFWorkbook.setCompressTempFiles, aby zapobiec tymczasowemu powiększaniu się plików XML na dysku.
Z flushRows () możesz ręcznie opróżnić rzędy na dysk.
Jest to jednak wolniejsze. Ale jeśli pamięć jest ograniczeniem, jedyną opcją.
Pamiętaj, że niektóre metody uzyskują dostęp do wierszy w sposób niejawny. Jeśli te wiersze zostały już zamienione na dysk, napotkasz także błędy. Uważam, że API służy tylko do pisania dużych plików programu Excel.
public static void main(String[] args) throws Throwable {
SXSSFWorkbook wb = new SXSSFWorkbook();
wb.setCompressTempFiles(true);
SXSSFSheet sh = (SXSSFSheet) wb.getSheetAt(0);
sh.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk, this is also the default
for(int i= 1; i < 100000; i++){
Row row = sh.createRow(i); // do something with the row
}
}