2012-07-05 3 views
10

Ich verwende XSSF von apache-POI, um die XLSX-Datei zu lesen. Ich erhalte einen Fehler java.lang.OutOfMemoryError: Java heap space. Später, erhöhte die Größe des Heap mit -Xmx1024m für die Java-Klasse immer noch den gleichen Fehler wiederholt.Wie lese ich XLSX-Datei der Größe> 40MB

Code:

String filename = "D:\\filename.xlsx"; 
FileInputStream fis = null; 
try { 
    fis = new FileInputStream(filename); 
    XSSFWorkbook workbook = new XSSFWorkbook(fis); 

In dem obigen Codesegment, stoppt die Ausführung an XSSFWorkbook und führt den angegebenen Fehler. Kann jemand einen besseren Ansatz zum Lesen großer XLSX-Dateien vorschlagen?

+0

Sie es von IDE wie Eclipse ausführen? Wie hast du Speicheroptionen festgelegt? Ich denke, dass deine Einstellungen nicht richtig beeinflusst wurden. –

+0

Ja, ich benutze Eclipse IDE und habe die folgenden Änderungen vorgenommen ... 1) In eclipse.ini habe ich die -Xmx256M nach -Xmx-1024M bearbeitet 2) Im IDE Fenster-> Preferences-> Installierte JRE-> hinzugefügt - Xms256M -Xmx1024M in Standard-VM-Argumenten. Ich denke, es könnte sich in Eclipse IDE – Avinash

Antwort

14

Mit POI können Sie Excel-Dateien in Streaming-Form lesen. Die API ist so ziemlich ein Wrapper um SAX. Stellen Sie sicher, dass Sie das OPC-Paket auf die richtige Weise öffnen, indem Sie den Konstruktor verwenden, der einen String akzeptiert. Sonst könnte der Speicher nicht mehr ausreichen.

OPCPackage pkg = OPCPackage.open(file.getPath()); 
XSSFReader reader = new XSSFReader(pkg); 

Nun Leser ermöglicht es Ihnen, InputStreams für die verschiedenen Teile zu bekommen. Wenn Sie die XML-Analyse selbst durchführen möchten (mit SAX oder StAX), können Sie diese verwenden. Aber es erfordert, dass man mit dem Format vertraut ist.

Eine einfachere Option ist die Verwendung XSSFSheetXMLHandler. Hier ist ein Beispiel, das das erste Blatt liest:

StylesTable styles = reader.getStylesTable(); 
ReadOnlySharedStringsTable sharedStrings = new ReadOnlySharedStringsTable(pkg); 
ContentHandler handler = new XSSFSheetXMLHandler(styles, sharedStrings, mySheetContentsHandler, true); 

XMLReader parser = XMLReaderFactory.createXMLReader(); 
parser.setContentHandler(handler); 
parser.parse(new InputSource(reader.getSheetsData().next())); 

Wo mySheetsContentHandler eine eigene Implementierung von XSSFSheetXMLHandler.SheetContentsHandler sein sollte. Diese Klasse wird mit Zeilen und Zellen gefüttert.

Beachten Sie jedoch, dass dies mäßig Speicher verbrauchen kann, wenn Ihre Tabelle gemeinsam genutzte Zeichenfolgen ist riesig (was passiert, wenn Sie keine doppelten Zeichenfolgen in Ihren großen Blättern haben). Wenn Speicher immer noch ein Problem ist, empfehle ich die Verwendung der Raw-XML-Streams (ebenfalls von XSSFReader bereitgestellt).

+0

Erstaunliche Antwort, vielen Dank! –

+0

Vielleicht könnten Sie mir bei der Lösung dieses Problems helfen: http://stackoverflow.com/questions/31939669/how-to-interrupt-po-i-streaming-reader-after-reading-the-first-line –