java - para - Transmisión de un libro de trabajo de POI al flujo de salida del servlet
hssfworkbook java (5)
Construyo un libro de trabajo de PDI muy grande, en mi servidor web. Mantener todo el libro en la memoria, no escalará para múltiples solicitudes concurrentes. ¿Hay alguna manera de que pueda escribir progresivamente el libro de trabajo en el flujo de salida del servlet? Eso debería reducir el tiempo de respuesta, así como hacer que la memoria del proceso sea eficiente.
¿Intentó con el método de escritura directamente en HttpServletResponse.getOutputStream ()?
Por favor, eche un vistazo al siguiente ejemplo:
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
...
OutputStream out = response.getOutputStream();
wb.write(out);
out.close();
Desafortunadamente, eso es imposible cuando no hay medios de datos secuenciales. Yo sugeriría buscar otro formato, por ejemplo, CSV o XML. Ambos se pueden escribir de forma secuencial. Si proviene de una base de datos, incluso se puede hacer más eficiente, ya que una base de datos decente tiene funciones integradas para exportar de manera eficiente a esos formatos. Solo tienes que transmitir los bytes de uno a otro lado.
La situación ha mejorado considerablemente desde que se escribieron el resto de las respuestas: el streaming ahora es parte de Apache Poi.
Consulte la clase SXSSFWorkbook y la documentación aquí . Utiliza una ventana de transmisión sobre la hoja, vaciando las filas antiguas fuera de la ventana a archivos temporales.
Esto se basa en el enfoque de BigGridDemo
utilizado en la respuesta de hlg , pero ahora forma parte de la distribución oficial.
Aquí está el ejemplo de la documentación:
public static void main(String[] args) throws Throwable {
// keep 100 rows in memory, exceeding rows will be flushed to disk
SXSSFWorkbook wb = new SXSSFWorkbook(100);
Sheet sh = wb.createSheet();
for(int rownum = 0; rownum < 1000; rownum++){
Row row = sh.createRow(rownum);
for(int cellnum = 0; cellnum < 10; cellnum++){
Cell cell = row.createCell(cellnum);
String address = new CellReference(cell).formatAsString();
cell.setCellValue(address);
}
}
// Rows with rownum < 900 are flushed and not accessible
for(int rownum = 0; rownum < 900; rownum++){
Assert.assertNull(sh.getRow(rownum));
}
// ther last 100 rows are still in memory
for(int rownum = 900; rownum < 1000; rownum++){
Assert.assertNotNull(sh.getRow(rownum));
}
FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx");
wb.write(out);
out.close();
// dispose of temporary files backing this workbook on disk
wb.dispose();
}
Si está a punto de generar Excel 2007 (xslx), puede adaptar el enfoque de BigGridDemo.java como se describe aquí: http://web.archive.org/web/20110821054135/http://www.realdevelopers.com/blog/code/excel
La solución es permitir que POI genere un contenedor xslx solo como plantilla y transmita los datos reales de la hoja de cálculo como XML a una secuencia de salida zip. La racionalización de la generación XML depende de usted.
Si usa JExcel It tiene código de ejemplo para leer el código de flujo hacia y desde un Servlet. http://jexcelapi.sourceforge.net/resources/faq/
El único inconveniente de esta API parece que solo admite hasta Excel 2003 inclusive.
Uso de POI: ¿No puede crear el archivo y servir los bytes del archivo a la secuencia de salida del servlet?