Domanda

Sto cercando di scrivere in un (formato .xls MS Excel 2003) Excel File programatically utilizzando Java. I file di output di Excel possono contenere ~ 200.000 righe che ho intenzione di dividere più di numero di fogli (64K righe per foglio, a causa del limite di Excel).

Ho provato con le API apache POI ma sembra essere uno spreco di memoria a causa del modello oggetto API. Sono costretto a aggiungere cellule / fogli per l'oggetto di lavoro in memoria e solo una volta è aggiunta tutti i dati, posso scrivere la cartella di lavoro in un file! Ecco un esempio di come l'apache raccomanda scrivo files excel usando il loro API:

Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("new sheet");

//Create a row and put some cells in it
Row row = sheet.createRow((short)0);

// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Chiaramente, la scrittura ~ filari di 20K (con alcune 10-20 colonne in ogni riga) mi dà il temuto "java.lang.OutOfMemoryError: spazio heap Java".

Ho cercato di aumentare heap iniziale JVM e la dimensione massima heap utilizzando Xms e parametri Xmx come Xms512m e Xmx1024. Ancora non posso scrivere più di 150k righe al file.

Sto cercando un modo per lo streaming di un file Excel invece di costruire l'intero file in memoria prima di scrivere sul disco che si spera risparmiare un sacco di utilizzo della memoria. Qualsiasi API o soluzioni alternative sarebbe apprezzato, ma sono limitati all'uso di Java. Grazie! :)

È stato utile?

Soluzione

Tutte le API Java esistenti cercano di costruire l'intero documento in RAM in una sola volta. Prova a scrivere un file XML che è conforme al nuovo formato di file XSLX invece. Per iniziare, vi suggerisco di costruire un piccolo file nella forma desiderata in Excel e salvarlo. Poi aprire ed esaminare la struttura e sostituire le parti che si desidera.

buon articolo sul formato generale.

Altri suggerimenti

Prova ad utilizzare SXSSF cartella di lavoro, questo è grande cosa per grandi documenti xls, il documento di accumulo e non mangiare RAM a tutti, becase utilizzando nio

ho dovuto dividere i file in diversi file excel al fine di superare l'eccezione spazio di heap. Ho pensato che circa 5k righe con 22 colonne era su di esso, così ho fatto la mia logica in modo che ogni riga 5k avrei finito il file, avviare un nuovo e proprio far di conto i file di conseguenza.

Nei casi in cui ho avuto 20k + righe da scritte avrei 4+ file diversi che rappresentano i dati.

Date un'occhiata alla HSSF serializzatore dal progetto cocoon .

  

Il serializzatore HSSF cattura eventi SAX e crea un foglio di calcolo in formato XLS utilizzato da Microsoft Excel

C'è anche JExcelApi, ma i suoi usi più memoria. penso che si dovrebbe creare .csv file e aprirlo in Excel. esso consente di passare un sacco di dati, ma non sarà in grado di fare qualsiasi "Excel magico".

Si consiglia di utilizzare il formato CSV. In questo modo non si è limitato dalla memoria più --well, forse solo durante la precompilazione i dati per CSV, ma questo può essere fatto in modo efficiente, così, ad esempio l'esecuzione di query sottoinsiemi di righe da DB utilizzando, ad esempio LIMIT/OFFSET e subito scriverlo su file invece di tirare l'intero contenuto della tabella DB nella memoria di Java prima di scrivere qualsiasi linea. La limitazione di Excel delle quantità righe in un "foglio" salirà a circa un milione.

Detto questo, se i dati sono in realtà proviene da un DB, quindi altamente riconsiderare se Java è lo strumento giusto per questo. La maggior parte dei decenti DB sono una funzione di esportazione-to-CSV che può fare questo compito indubbiamente molto più efficiente. In caso di, ad esempio MySQL, è possibile utilizzare il LOAD DATA INFILE comando per questo.

Abbiamo sviluppato una libreria Java per questo scopo e attualmente è disponibile come progetto open source https: // GitHub com / jbaliuka / x4j-analitica. L'usiamo per il reporting operativo. Generiamo enormi file di Excel, ~ 200.000 dovrebbe funzionare senza problemi, Excel riesce ad aprire tali file troppo. Il nostro codice utilizza POI caricare il modello, ma il contenuto generato viene trasmesso direttamente al file senza XML o modello oggetto strato in memoria.

E 'questo problema di memoria accadere quando si inseriscono dati nella cella, o quando si eseguono i dati di calcolo / generazione?

Se avete intenzione di caricare file in un Excel che consistono di formato del modello statico predefinito, quindi meglio di salvare un modello e riutilizzare il tempo multiplo. Normalmente i casi modello accadono quando si sta per generare report giornaliero di vendita o ecc ...

Altrimenti, ogni volta che è necessario creare nuova riga, confine, colonna ecc da zero.

Finora, Apache POI è l'unica scelta che ho trovato.

"Chiaramente, la scrittura ~ righe 20k (con alcuni 10-20 colonne per ogni riga) mi dà la temuta "java.lang.OutOfMemoryError:"." Spazio heap Java

"Enterprise IT"

Cosa si può fare è-eseguire l'inserimento dei dati batch. Creare una tabella queuetask, ogni volta dopo generare 1 pagina, riposo per secondi, quindi continuare seconda parte. Se siete preoccupazione circa i cambiamenti di dati dinamici durante il vostro compito di coda, è possibile prima ottiene la chiave primaria in Excel (nascondendo e bloccare la colonna dalla vista utente). Prima esecuzione verrà inserire la chiave primaria, quindi secondo run coda in poi leggerà da blocco note e fare la parte di operazione da parte.

Abbiamo fatto qualcosa di molto simile, stessa quantità di dati, e abbiamo dovuto passare a JExcelApi perché POI è così pesante sulle risorse. Prova JExcelApi, non ve ne pentirete quando si deve manipolare i grandi Excel-files!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top