2015-11-18 20 views
6

Ho bisogno di leggere file di Excel di grandi dimensioni e di importare i loro dati nella mia applicazione.Apache POI Streaming (SXSSF) per la lettura

Da POI occupa una grande quantità di memoria riservata al lavoro, spesso gettando OutOfMemory errori, ho scoperto che esiste una Streaming API per la gestione di dati di Excel in modo seriale (piuttosto che caricare completamente i file in memoria)

ho creato una cartella di lavoro xlsx, con un unico foglio di lavoro, e inserì diversi valori in celle e si avvicinò con il seguente codice per tentare di leggerlo:

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()); 
     } 

    } 

Tuttavia, pur essendo in grado di ottenere i suoi fogli di lavoro correttamente, sempre viene fornito con righe vuote (null).

Ho ricercato e trovato diversi esempi dell'API Streaming in Internet, ma nessuno di essi è relativo a che legge i file esistenti, si tratta di generare file Excel.

È effettivamente possibile leggere i dati dai file esistenti .xlsx in uno streaming?

+0

Si sta utilizzando IDE Eclipse per questo? –

+0

Sì, lo sono, perché? –

+0

coz Ho una soluzione se vuoi aumentare lo spazio dell'heap. –

risposta

15

Dopo aver scavato un po 'di più, ho scoperto questo library:

Se hai utilizzato Apache POI in passato per leggere nei file di Excel, probabilmente avete notato che non è molto efficiente della memoria. La lettura di un'intera cartella di lavoro causerà un grave picco di utilizzo della memoria, che può causare il caos su un server.

Ci sono molti buoni motivi per cui Apache deve leggere l'intera cartella di lavoro, ma la maggior parte di essi ha a che fare con il fatto che la libreria consente di leggere e scrivere con indirizzi casuali. Se (e solo se) vuoi solo leggere il contenuto di un file Excel in modo veloce e in memoria, probabilmente non hai bisogno di questa capacità. Sfortunatamente, l'unica cosa nella libreria POI per leggere una cartella di lavoro in streaming richiede che il tuo codice utilizzi un parser simile a SAX. Tutte le classi amiche come Row e Cell mancano da quell'API.

Questa libreria funge da wrapper attorno all'API di streaming pur mantenendo la sintassi dell'API POI standard. Continua a leggere per vedere se è giusto per te.

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) 

C'è anche SAX Event API, che legge il documento e analizzare il suo contenuto attraverso eventi.

Se l'impronta di memoria è un problema, per XSSF è possibile ottenere i dati XML sottostanti ed elaborarli autonomamente. Questo è inteso per gli sviluppatori intermedi che desiderano imparare un po 'di struttura di basso livello dei file .xlsx e che sono felici di elaborare XML in java. È relativamente semplice da usare, ma richiede una conoscenza di base della struttura del file. Il vantaggio offerto è che è possibile leggere un file XLSX con un ingombro di memoria relativamente ridotto.

+1

Sì, anche io ho affrontato lo stesso problema e ho usato questa libreria e funziona come il fascino –

+0

ma questa libreria funzionerà solo con i file .xlsx, ho un obbligo aziendale di usare solo file .xls, e come hai detto poi prendere un sacco di memoria per file excel di grandi dimensioni. Si ha qualche suggerimento per questo caso – akhilsk

Problemi correlati