2015-11-18 6 views
6

Ich muss große Excel-Dateien lesen und ihre Daten in meine Anwendung importieren.Apache POI Streaming (SXSSF) zum Lesen

Da POI eine große Menge an Heap in Anspruch nimmt, oft zu arbeiten werfen OutOfMemory Fehler, fand ich heraus, dass es eine Streaming API für Daten auf serielle Weise excel Handling (anstatt die Datei vollständig in den Speicher geladen)

ich habe eine xlsx Arbeitsmappe mit einem einzelnen Arbeitsblatt und in mehr Werten in Zellen eingegeben und kam mit dem folgenden Code, um es zu lesen, um zu versuchen:

jedoch
public static void main(String[] args) throws Throwable { 
     SXSSFWorkbook wb = new SXSSFWorkbook(new XSSFWorkbook(new FileInputStream("C:\\test\\tst.xlsx"))); // keep 100 rows in memory, exceeding rows will be flushed to disk 
     SXSSFSheet sheet = (SXSSFSheet) wb.getSheetAt(0); 
     Row row = sheet.getRow(0); 
     //row is always null 
     while(row.iterator().hasNext()){ //-> NullPointerException 
      System.out.println(row.getCell(0).getStringCellValue()); 
     } 

    } 

, trotz der Lage ist, seine Arbeitsblatt zu erhalten richtig, es immer kommt mit leeren (null) Zeilen.

Ich habe recherchiert und einige Beispiele der Streaming-API im Internet gefunden, aber keine von ihnen sind Lesen vorhandenen Dateien, sie sind alle über Generieren von Excel-Dateien.

Ist es tatsächlich möglich, Daten von bestehenden .xlsx Dateien in einem Stream zu lesen?

+0

Verwenden Sie Eclipse IDE dafür? –

+0

Ja, ich bin, warum? –

+0

coz Ich habe eine Lösung, wenn Sie den Heap-Speicherplatz erhöhen möchten. –

Antwort

15

Nach etwas mehr graben, fand ich diese library aus:

Wenn Sie Apache POI in der Vergangenheit in Excel-Dateien zu lesen verwendet haben, haben Sie wahrscheinlich bemerkt, dass es effizient, nicht sehr Speicher ist. Das Einlesen einer ganzen Arbeitsmappe führt zu einer starken Speicherauslastungsspitze, die auf einem Server Verwüstungen verursachen kann.

Es gibt viele gute Gründe dafür, dass Apache das gesamte Arbeitsbuch lesen muss, aber die meisten davon haben damit zu tun, dass die Bibliothek das Lesen und Schreiben mit zufälligen Adressen ermöglicht. Wenn Sie (und nur wenn) nur den Inhalt einer Excel-Datei schnell und effizient lesen möchten, benötigen Sie diese Fähigkeit wahrscheinlich nicht. Leider benötigt der Code in der POI-Bibliothek zum Lesen einer Streaming-Arbeitsmappe nur einen SAX-ähnlichen Parser. Alle benutzerfreundlichen Klassen wie Row und Cell fehlen in dieser API.

Diese Bibliothek dient als Wrapper für diese Streaming-API, wobei die Syntax der Standard-POI-API beibehalten wird. Lesen Sie weiter, um zu sehen, ob es für Sie richtig ist.

InputStream is = new FileInputStream(new File("/path/to/workbook.xlsx")); 
StreamingReader reader = StreamingReader.builder() 
     .rowCacheSize(100) // number of rows to keep in memory (defaults to 10) 
     .bufferSize(4096)  // buffer size to use when reading InputStream to file (defaults to 1024) 
     .sheetIndex(0)  // index of sheet to use (defaults to 0) 
     .sheetName("sheet1") // name of sheet to use (overrides sheetIndex) 
     .read(is);   // InputStream or File for XLSX file (required) 

Es gibt auch SAX Event API, die das Dokument liest und seinen Inhalt durch Ereignisse analysieren.

Wenn Speicherbedarf ein Problem ist, dann für XSSF, können Sie an den zugrunde liegenden XML-Daten erhalten, und diese selbst verarbeiten. Dies ist für fortgeschrittene Entwickler gedacht, die bereit sind, ein wenig Low-Level-Struktur von .xlsx-Dateien zu lernen, und die glücklich sind, XML in Java zu verarbeiten. Es ist relativ einfach zu verwenden, erfordert jedoch ein grundlegendes Verständnis der Dateistruktur. Der Vorteil ist, dass Sie eine XLSX-Datei mit relativ geringem Speicherbedarf lesen können.

+1

Ja, auch ich habe das gleiche Problem und verwendet diese Bibliothek und es funktioniert wie Charme –

+0

aber diese Bibliothek wird nur mit .xlsx-Dateien arbeiten, ich habe eine Geschäftsanforderung, nur .xls-Dateien zu verwenden, und wie du gesagt poi eine Menge Speicher für große Excel-Datei reads. Haben Sie einen Vorschlag für diesen Fall – akhilsk