2008-12-18 45 views
8

我希望我的Web應用程序用戶將一些數據作爲Excel文件下載。如何從HSSFWorkbook對象獲得輸入流

我有下一個函數在響應對象中發送輸入流。

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

我想將我的HSSFWorkbook對象轉換爲輸入流並將其傳遞給前一個方法。

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

回答

10

你的問題的問題是你正在混合OutputStreams和InputStreams。 InputStream是您讀取的內容,OutputStream是您寫入的內容。

這是我如何寫POI對象到輸出流。

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

如果您想重新使用您現有的代碼,您必須將POI數據存儲在某處,然後將THAT轉換爲輸入流。這很容易通過將它寫入ByteArrayOutputStream,然後使用ByteArrayInputStream讀取這些字節,但我不會推薦它。你現有的方法作爲一個通用的管道實現會更有用,你可以將數據從一個InputStream管道輸出到OutputStream,但是你不需要它來編寫POI對象。例如:

+0

+1。但我如何獲得HSSFWorkbook的文件大小?我想添加一個標題`Content-Length' – MyTitle 2012-09-19 04:48:46

0

我想我明白你正在試圖做的(也許我下衝,雖然)

你並不真的需要那麼多的代碼是什麼 - 檢查出的寫入方法 -

HSSFWorkbook wb = new HSSFWorkBook(); 
//populate 

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

據我記得,當我工作瓦特/ POI這就是我做的。如果你在一個web框架中,你可能不得不爲此付出代價,以便框架在關閉它之後不會嘗試使用那個ServletOutputStream做些什麼。如果它嘗試,你會得到一個異常拋出,告訴你輸出流已經關閉。