2012-06-27 26 views
15

Soy capaz de crear un archivo de Excel usando apache poi. Sin embargo, quiero que los usuarios puedan descargar esto como un archivo de Excel "verdadero". el efecto que quiero lograr sería tener una ventana emergente que permita al usuario descargar el archivo. esto es similar al uso deCrear un archivo de Excel para que los usuarios descarguen usando Apache POI

<%@ page contentType="application/vnd.ms-excel" pageEncoding="ISO-8859-1"%> 
<%response.setHeader("Content-Disposition", "attachment;filename=myfile.xls"); %> 

con una excepción crítica: debo permitir que el usuario descargue un archivo de Excel adecuado. He leído en alguna parte el código anterior simplemente le dice al cliente que el servidor está enviando un archivo de Excel

Respuesta

32

Haga el trabajo en un servlet normal en lugar de un archivo JSP. Un archivo JSP está destinado a generar dinámicamente código HTML y está utilizando un escritor de caracteres para eso en lugar de una secuencia de salida binaria y, por lo tanto, solo corrompería su archivo de Excel generado por PI que, en esencia, es una secuencia binaria.

Así que, básicamente, todo lo que tiene que hacer en el método del servlet doGet() es la siguiente:

response.setContentType("application/vnd.ms-excel"); 
response.setHeader("Content-Disposition", "attachment; filename=filename.xls"); 
HSSFWorkbook workbook = new HSSFWorkbook(); 
// ... 
// Now populate workbook the usual way. 
// ... 
workbook.write(response.getOutputStream()); // Write workbook to response. 
workbook.close(); 

Ahora, para descargarlo, invocar el servlet por su URL en lugar del archivo JSP.

+0

writableworkbook es parte de la api jexcel ¿verdad? esto debería funcionar incluso si estoy usando poi ¿verdad? – user571099

+0

@ user571099 el libro de trabajo es un 'HSSFWorkbook' aquí, no un' WritableWorkbook'. –

+0

¡Esto era exactamente lo que estaba buscando! Supongo que esto se puede hacer de manera similar con el servicio web RESTful de Jersey. – Brian

20

Si bien es cierto que es más común escribir un archivo adjunto binario utilizando un servlet en lugar de un jsp, sin duda es posible escribir un archivo adjunto binario de un jsp. Y la ventaja de hacerlo es que no necesita preocuparse por configurar web.xml o volver a cargar su aplicación. Esa puede ser una consideración importante, dependiendo del entorno de su servidor web.

Aquí hay un jsp de ejemplo que usa poi para enviar un archivo adjunto binario a un navegador.

<%@page import="org.apache.poi.hssf.usermodel.*" %><%@page import="java.io.*" %><% 

// create a small spreadsheet 
HSSFWorkbook wb = new HSSFWorkbook(); 
HSSFSheet sheet = wb.createSheet(); 
HSSFRow row = sheet.createRow(0); 
HSSFCell cell = row.createCell(0); 
cell.setCellValue("Some text"); 

// write it as an excel attachment 
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream(); 
wb.write(outByteStream); 
byte [] outArray = outByteStream.toByteArray(); 
response.setContentType("application/ms-excel"); 
response.setContentLength(outArray.length); 
response.setHeader("Expires:", "0"); // eliminates browser caching 
response.setHeader("Content-Disposition", "attachment; filename=testxls.xls"); 
OutputStream outStream = response.getOutputStream(); 
outStream.write(outArray); 
outStream.flush(); 

%> 

El truco importante es asegurarse de que sólo hay una línea con todas sus importaciones y otras directivas anteriores a la "<%" que comienza su código. De lo contrario, jsp puede generar algunas nuevas líneas iniciales y dañar su resultado.

Además, le sugiero que siempre configure la longitud del contenido. Algunos navegadores no funcionarán correctamente si no está configurado. Es por eso que primero envío mi hoja de cálculo a una matriz de bytes, por lo que podría establecer la longitud antes de enviar los datos.

+0

Gracias por la respuesta, pero ¿puedo preguntarle dónde define la ruta al archivo xls? Quiero decir, ¿cómo sabe jsp, dónde elegir ese archivo xls? ¿Podría funcionar con el pdf, que fue creado por el programa de Java antes? –

0

si desea descargar Don, t utilizar HSSF libro lo hará más lento y consume más espacio utilice apche POI 3.17 beta-1

SXSSFWorkbook workbook = new SXSSFWorkbook(100); 
workbook.setCompressTempFiles(true); 
Sheet sh = workbook.createSheet(); 
//write your data on sheet 

//below code will download file in browser default download folder 
response.setContentType("application/vnd.ms-excel"); 
      response.setHeader("Content-Disposition", "attachment; filename="+filename+".xlsx"); 
      workbook.write(response.getOutputStream()); 
      workbook.close(); 
      workbook.dispose(); 

Para Pdf Uso itext

 Document document = new Document(); 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
      PdfWriter.getInstance(document, baos); 
      document.open(); 
//write your code 

document.add("content"); 
      document.close(); 
      response.setHeader("Expires", "0"); 
      response.setHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0"); 
      response.setHeader("Pragma", "public"); 
      response.setContentType("application/pdf"); 
      response.addHeader("Content-Disposition", "attachment; filename="+filename+".pdf"); 
      response.setContentLength(baos.size()); 
      OutputStream os = response.getOutputStream(); 
      baos.writeTo(os); 
      os.flush(); 
      os.close(); 
Cuestiones relacionadas