2012-06-27 119 views
15

我可以用apache poi創建一個excel文件。不過,我希望用戶能夠將其作爲「真正的」excel文件下載。我想達到的效果是有一個允許用戶下載文件的彈出框。這類似於使用創建一個excel文件供用戶使用Apache POI下載

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

有一個重要的例外:我必須允許用戶下載適當的excel文件。我在某處讀了上面的代碼,只是對客戶端說服務器發送了一個excel文件

回答

32

在普通的servlet而不是JSP文件中執行這項工作。 JSP文件是用來動態生成HTML代碼的,它使用字符編寫器代替二進制輸出流,因此只會破壞POI生成的Excel文件,這本質上是一個二進制流。

所以,基本上所有你需要在servlet的doGet()方法做的是以下幾點:

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

現在,下載它,由它的URL,而不是JSP文件中調用Servlet。

+0

將WritableWorkbook是一部分jexcel api對不對?這應該工作,即使即時使用poi權利? – user571099

+0

@ user571099這裏的工作簿是一個'HSSFWorkbook',而不是'WritableWorkbook'。 –

+0

這正是我所期待的!我認爲這可以與Jersey RESTful Web服務類似地完成? – Brian

20

儘管使用servlet而不是jsp編寫二進制附件更爲常見,但是從jsp編寫二進制附件當然是可以的。這樣做的好處是您無需擔心配置web.xml或重新加載應用程序。這可能是一個重要的考慮因素,具體取決於您的Web服務器環境。

這是一個jsp示例,它使用poi將二進制附件發送到瀏覽器。

<%@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(); 

%> 

最重要的訣竅是要確保只有一個與您的所有進口和之前的「<%」開頭的代碼其他指令線。否則,jsp可能會輸出一些最初的新行並損壞您的輸出。

另外,我建議你總是設置內容的長度。如果未設置,某些瀏覽器將無法正常工作。這就是爲什麼我首先將電子表格輸出到字節數組,所以我可以在實際發送數據之前設置長度。

+0

謝謝你的回答,但我可以問你,你在哪裏定義xls文件的路徑?我的意思是,jsp如何知道,從哪裏選擇xls文件?它可以使用由java程序創建的pdf嗎? –

0

,如果你想下載唐,T使用HSSF工作簿它會更慢,消耗更多的空間使用apche的POI 3.17β-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(); 

對於使用PDF的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(); 
相關問題