2012-03-19 25 views
6

Necesito escribir un conjunto de resultados de más de 65000 filas en el archivo xlsx. Así que estoy tratando de usar Apache POI 3.7. Pero obtengo el error de OutOfMemoryError: espacio de pila de Java. ¿Cómo resuelvo este problema además de aumentar la memoria JVM que no parece resolver el problema? Por favor ayuda.Apache POI 3.7 OutOfMemoryError: espacio de pila de Java al escribir en un gran número de filas en archivos xlsx

simple código de ejemplo:

public static void main(String[] args) throws IOException { 
     Workbook wb = new XSSFWorkbook(); 
     CreationHelper createHelper = wb.getCreationHelper(); 
     Sheet sheet = wb.createSheet("new sheet"); 

     // Create a row and put some cells in it. Rows are 0 based. 
     for (int i=0;i<65000;i++){ 
      Row row = sheet.createRow((int) i); 
     // Create a cell and put a value in it. 
     Cell cell = row.createCell(0); 
     cell.setCellValue(1); 

     // Or do it on one line. 
     row.createCell(1).setCellValue(1.2); 
     row.createCell(2).setCellValue(
       createHelper.createRichTextString("This is a string")); 
     row.createCell(3).setCellValue(true); 
     } 


     // Write the output to a file 
     FileOutputStream fileOut = new FileOutputStream("test1.xls"); 
     fileOut.flush(); 
     wb.write(fileOut); 
     fileOut.close(); 
    } 
+0

Me pregunto si se puede eludir este problema escribiendo en un archivo CSV e importando a Excel 2007? –

Respuesta

10

Es posible que desee echa un vistazo a lo que el proyecto POI hizo recientemente con el SXSSF API. También hay una sección en el How-To.
Para el código de ejemplo que proporcionó, este sería el ajuste perfecto, ya que solo crea datos y luego se olvida de ellos después de la creación. Con la extensión SXSSF puede comenzar a escribir los datos en el archivo de inmediato. Esto mantiene la huella de memoria baja.

Tenga en cuenta que esta característica no está presente en Apache POI 3.7 pero se agregó en Apache POI 3.8 beta 3.
Versión final 3.8 actualmente se está votando. Entonces, si tiene que usar una versión final, no debería pasar demasiado tiempo antes de que se lance.

+0

He descargado 3.8 ('poi-bin-3.8-20120326.tar.gz') y realicé pruebas. 100K filas sin ningún problema y uso de memoria de 200MB, que parece ser constante. Anteriormente, con XSSF, necesitaba 1GB para 10K filas. HSSF necesitaba 5 veces menos memoria, pero todavía era mucho, 1.5G para 65K. Turismo, hiciste mi día! Ahora estoy usando el mismo código de 'usermodel', solo cambié la clase de libro de trabajo a' org.apache.poi.xssf.streaming.SXSSFWorkbook'. – Jarekczek

0

Tengo el mismo problema, esto no es una solución pero funciona, creo diferentes archivos de Excel y luego los fusiono manualmente, sé que esta no es una buena solución, pero como era urgente para mí no tuve otra opción.

Puede hacer esto de dos maneras diferentes:

1.- Crear un nuevo archivo una vez yoi han alcanzado las 3000 filas:

XSSFWorkbook wb = new XSSFWorkbook(); 
fileOut = new FileOutputStream("file1.xlsx"); 
fileOut = new FileOutputStream("file2.xlsx");... 

puede agregar a este en una declaración para crearlos Dinámicamente, una vez que haya alcanzado los primeros 3000 registros guarde el archivo y continúe escribiendo en el próximo.

2.- Delimitar los registros conjunto de resultados o de origen para obtener menos de 3000 registros, y ejecutar de nuevo el programa entero, pero con una serie de consultas diferente cada vez:

between recNum = 1 and recNum <=100 

la siguiente ejecución será:

between recNum > 100 and recNum <= 200 

Esto es solo un ejemplo, espero que esto pueda serle útil.

Cuestiones relacionadas