Pregunta

Quiero que mis usuarios de la aplicación web para descargar algunos datos como un archivo de Excel.

Tengo la siguiente función para enviar un flujo de entrada en el objeto respuesta.

public static void sendFile(InputStream is, HttpServletResponse response) throws IOException {
        BufferedInputStream in = null;
        try {
            int count;
            byte[] buffer = new byte[BUFFER_SIZE];
            in = new BufferedInputStream(is);
            ServletOutputStream out = response.getOutputStream();
            while(-1 != (count = in.read(buffer)))
                out.write(buffer, 0, count);
            out.flush();            
        }   catch (IOException ioe) { 
            System.err.println("IOException in Download::sendFile"); 
            ioe.printStackTrace();
        } finally {
            if (in != null) {
                try { in.close(); 
                } catch (IOException ioe) { ioe.printStackTrace(); }
            }   
        }
    }

Me gustaría transformar mi objeto HSSFWorkbook a un flujo de entrada y pasarlo al método anterior.

public InputStream generateApplicationsExcel() {
    HSSFWorkbook wb = new HSSFWorkbook();
    // Populate the excel object
    return null; // TODO. return the wb as InputStream 
}

http://poi.apache.org/ apidocs / org / apache / poi / HSSF / UserModel / HSSFWorkbook.html

¿Fue útil?

Solución

El problema con su pregunta es que usted está mezclando OutputStreams y InputStreams. Un InputStream es algo que se lee de un OutputStream y es algo que se escribe en.

Esta es la forma en que escribo un objeto de punto de interés al flujo de salida.

// this part is important to let the browser know what you're sending
response.setContentType("application/vnd.ms-excel");
// the next two lines make the report a downloadable file;
// leave this out if you want IE to show the file in the browser window
String fileName = "Blah_Report.xls";
response.setHeader("Content-Disposition", "attachment; filename=" + fileName); 

// get the workbook from wherever
HSSFWorkbook wb = getWorkbook();
OutputStream out = response.getOutputStream();
try {
   wb.write(out);
}       
catch (IOException ioe) { 
  // if this happens there is probably no way to report the error to the user
  if (!response.isCommited()) {
    response.setContentType("text/html");
    // show response text now
  }
}

Si desea volver a utilizar el código existente que tendría que almacenar los datos de puntos de interés en algún lugar y luego convertir eso en un flujo de entrada. Eso sería hacer fácilmente escribiéndola a un ByteArrayOutputStream, entonces la lectura de los bytes utilizando un ByteArrayInputStream, pero yo no lo recomendaría. Su método existente sería más útil como una aplicación genérica de tuberías, donde se puede canalizar los datos de un InputStream y OutputStream a, pero no lo necesitará para escribir objetos de puntos de interés.

Otros consejos

se puede crear un InputStream de un objeto.

public InputStream generateApplicationsExcel() {
    HSSFWorkbook wb = new HSSFWorkbook();
    // Populate a InputStream from the excel object
    return new ByteArrayInputStream(excelFile.getBytes());
}

Creo que entiendo lo que estás tratando de hacer (quizás estoy quedarse corto, sin embargo)

que realmente no necesita que gran parte de código - revisar el método de escritura -

HSSFWorkbook wb = new HSSFWorkBook();
//populate

ServletOutputStream out = response.getOutputStream();
try {
   wb.write(out);
   out.flush();
}       
catch (IOException ioe) { 
   //whatever
}
out.close();

Por lo que yo recuerdo cuando trabajaba w / PDI que es lo que hice. Si está dentro de un marco Web puede que tenga que finaggle de modo que el marco no trata de hacer algo con el que ServletOutputStream después de que haya cerrado la misma. Si se intenta, obtendrá un lanzamiento de excepción que indica que el flujo de salida está cerrado ya.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top