Domanda

Voglio che i miei utenti di applicazioni Web per scaricare alcuni dati come file Excel.

Ho la prossima funzione per inviare un flusso di input nell'oggetto risposta.

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(); }
            }   
        }
    }

Vorrei trasformare il mio oggetto HSSFWorkbook ad un flusso di input e passarlo al metodo precedente.

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 / PDI / HSSF / usermodel / HSSFWorkbook.html

È stato utile?

Soluzione

Il problema con la tua domanda è che si stia mescolando OutputStreams e InputStreams. Un InputStream è qualcosa che si legge da e un OutputStream è qualcosa che si scrive a.

Questo è come io scrivo un oggetto POI nel flusso di output.

// 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
  }
}

Se si voleva riutilizzare il codice esistente che avrebbe dovuto memorizzare i dati POI da qualche parte poi trasformarla in un flusso di input. Sarebbe essere facilmente effettuata scrivendo a un ByteArrayOutputStream, poi leggendo quei byte utilizzando un ByteArrayInputStream, ma io non lo consiglio. Il tuo metodo esistente sarebbe più utile come un'implementazione generica del tubo, in cui è possibile pipe i dati da un InputStream e OutputStream a, ma non è necessario per la scrittura di oggetti POI.

Altri suggerimenti

è possibile creare un InputStream da un oggetto.

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

Credo di capire quello che stai cercando di fare (forse sto undershooting, però)

non si ha realmente bisogno che molto codice - controllare il metodo di scrittura -

HSSFWorkbook wb = new HSSFWorkBook();
//populate

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

Per quanto mi ricordo quando ho lavorato w / POI che quello che ho fatto. Se sei all'interno di un framework web potrebbe essere necessario finaggle in modo che il quadro non cerca di fare qualcosa con il che ServletOutputStream dopo aver chiuso esso. Se si cerca, si otterrà un lancio un'eccezione che indica che il flusso di uscita è chiusa già.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top