2010-03-23 75 views
17

Estoy utilizando POI en mi aplicación web J2EE para generar un libro de trabajo. Sin embargo, encuentro que el POI toma alrededor de 3 minutos para crear un libro de trabajo con 25K filas (con alrededor de 15 columnas cada una). ¿Es este un problema de rendimiento de POI, o está justificado tomar tanto tiempo? ¿Existen otras API conocidas por un mejor rendimiento?Rendimiento POI

+0

@Gugusse, aceptaron respuestas son un indicador para aquellos que lean la pregunta lo que el _asker_ considera la respuesta correcta a su/su problema real. Esa es una información muy importante. Dicho esto, ¿hay alguna razón por la que no comentó la necesidad de que el solicitante proporcione un fragmento de código mínimo que muestre el comportamiento descrito? –

+0

@Gugussee, él solo está adivinando. La razón real podría ser cualquier cosa, que la muestra del código mostraría inmediatamente. ¿Sería razonable sugerirle que mejore su metapolicía? –

+0

@ Thorbjørn Ravn Andersen: ¿Sería razonable sugerirle que mejore su meta-meta-policing? ;) – Gugussee

Respuesta

12

Me sorprendería mucho que los POI se demoren tanto en generar ese archivo. Acabo de generar una hoja con 30000 filas x 10 celdas en aproximadamente 18s (sin formato, para ser justos). La causa podría ser uno de los siguientes:

  • registro de puntos de interés podría ser activado, tal como se describe here
  • está ejecutando desde la memoria de intercambio
  • su VM de almacenamiento dinámico disponible podría ser muy baja
+0

¿Contar con caracteres internacionales hará que el procesamiento sea más lento? Y otra pregunta, ¿cómo puede el aumento de la memoria de VM mejorar el rendimiento? –

+0

No creo que los caracteres internacionales hagan que este tipo de procesamiento sea más lento: se trata principalmente de la cantidad de datos. En cuanto al montón disponible de VM, dado que la cantidad necesaria de memoria se acerca al montón disponible, el recolector de basura debe activarse más a menudo: en casos extremos, la mayor parte del tiempo de CPU se gasta en recolección de basura. Esta es una situación específica: no es probable que se vea significativamente afectado por ella. –

+3

en mi experiencia POI es un poco lento y si POI necesita una carga de memoria s *** o necesita iniciarse sesión, entonces definitivamente ** es ** un problema de POI. Generamos informes usando POI y tan pronto como generamos más de unas pocas hojas de cálculo se vuelve muy lento. Además, 30000 filas x 10 celdas es realmente una cantidad trivialmente pequeña de datos para una CPU que hace miles de millones de ciclos por segundo. Entonces, sí, POI es una API bastante lenta. – Gugussee

1

También utilizamos POI en nuestra aplicación web y no tenemos ningún problema de rendimiento, aunque nuestros documentos generados son mucho más pequeños que los suyos. Primero verificaría si el POI es el verdadero problema aquí. Intente generar esos documentos sin la sobrecarga J2EE (Unit-Test) y mida el rendimiento. También podría controlar la carga y el uso de la memoria en su servidor J2EE para ver si los problemas provienen de algunas configuraciones del sistema que no son óptimas.

3

Si ninguna de las otras respuestas funciona, vea si el JExcel de Andy Khan será mejor. Descubrí que es muy superior al POI para tratar con Excel en Java.

1

He comparado el POI de Apache con la biblioteca JExcel. Parece que se trata de JExcel hasta 4 veces más rápido que Apache POI, pero el consumo de memoria parece ser más o menos lo mismo:

@Test 
public void createJExcelWorkbook() throws Exception { 
     WritableWorkbook workbook = Workbook.createWorkbook(new File("jexcel_workbook.xls")); 
     WritableSheet sheet = workbook.createSheet("sheet", 0); 
     for (int i=0; i < 65535; i++) { 
      for (int j=0; j < 10; j++) { 
       Label label = new Label(j, i, "some text " + i + " " + j); 
       sheet.addCell(label); 
      } 
     } 
     workbook.write(); 
     workbook.close(); 
} 

@Test 
public void createPoiWorkbook() throws Exception { 
    Workbook wb = new HSSFWorkbook(); 
    Sheet sheet = wb.createSheet("sheet"); 
    for (int i=0; i < 65535; i++) { 
     Row row = sheet.createRow(i); 
     for (int j=0; j < 10; j++) { 
      Cell cell = row.createCell(j); 
      cell.setCellValue("some text " + i + " " + j); 
     } 
    } 
    FileOutputStream fileOut = new FileOutputStream("poi_workbook.xls"); 
    wb.write(fileOut); 
    fileOut.close(); 
} 

Lo he probado con JExcel versión 2.6.12 y Apache POI versión 3.7. Debe descargar las últimas versiones de la biblioteca usted mismo y ejecutar las pruebas simples anteriores para obtener números más precisos.

<dependency org="org.apache.poi" name="poi" rev="3.7"/> 
<dependency org="net.sourceforge.jexcelapi" name="jxl" rev="2.6.12"/> 

Nota: hay un límite en Apache POI de 65535 filas por hoja.

+4

El límite de fila es una limitación de formato de archivo .xls de Excel, no una de POI. Si usa el formato de archivo .xlsx (utilizando XSSF desde Apache POI), puede crear más filas – Gagravarr

9

El rendimiento de la escritura de archivos de gran tamaño con POI puede reducirse considerablemente si utiliza la API de POI 'de transmisión' en lugar de la API estándar de transmisión. De hecho, por defecto, POI mantendrá todos sus datos en la memoria antes de escribirlos de una vez al final. La huella de memoria de esto puede ser ridículamente grande para archivos grandes. En lugar de usar la API de transmisión, puede controlar cómo se usa la memoria y los datos se escriben en el disco de forma progresiva.

Con el fin de crear un libro de streaming, usar algo como:

SXSSFWorkbook book = new SXSSFWorkbook(); 
    book.setCompressTempFiles(true); 

    SXSSFSheet sheet = (SXSSFSheet) book.createSheet(); 
    sheet.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk 
    // ... 
Cuestiones relacionadas