2012-06-27 17 views
15

apache poiを使用してExcelファイルを作成できます。しかし、私はユーザーがこれを「真の」Excelファイルとしてダウンロードできるようにしたい。私が達成したい効果は、ユーザーがファイルをダウンロードできるようにするポップアップボックスを持つことです。Apache POIを使用してダウンロードするユーザー用のExcelファイルを作成する

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

重要な例外が1つあります。ユーザーが適切なExcelファイルをダウンロードできるようにする必要があります。私は上記のコードを読んだだけで、クライアントがサーバーにExcelファイルを送信しているというメッセージを表示します。

答えて

32

JSPファイルではなく通常のサーブレットでジョブを実行します。 JSPファイルはHTMLコードを動的に生成するためのもので、バイナリ出力ストリームではなく文字ライタを使用しているため、バイナリストリームであるPOI生成のExcelファイルのみが破損します。

それで、あなたはサーブレットの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ファイルでサーブレットを呼び出します。

+0

writableworkbookはの一部でありますjexcel APIの権利ですか?これはpoiを使っていてもうまくいくはずです。 – user571099

+0

@ user571099ワークブックはここでは 'HSSFWorkbook'であり、' WritableWorkbook'ではありません。 –

+0

これはまさに私が探していたものでした!これはJersey RESTful Webサービスと同様に行うことができると思いますか? – Brian

20

jspではなくサーブレットを使用してバイナリの添付ファイルを書き込む方が一般的ですが、jspからバイナリの添付ファイルを書き込むことは可能です。そうすることの利点は、web.xmlの設定やアプリケーションの再読み込みを心配する必要がないことです。これは、Webサーバー環境に応じて、重要な考慮事項になります。

poiを使用してバイナリアタッチメントをブラウザに送信するjspの例を以下に示します。

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

%> 

重要なトリックは、すべての輸入品とあなたのコードを開始します「<%」に先立って他のディレクティブを持つ唯一の1行があることを確認することです。そうしないと、jspがいくつかの新しい改行を出力し、出力を破損する可能性があります。

また、コンテンツの長さを常に設定することをおすすめします。一部のブラウザは、設定されていないと正しく動作しません。そのため、最初にスプレッドシートをバイト配列に出力するので、実際にデータを送信する前に長さを設定することができます。

+0

ありがとうございますが、xlsファイルへのパスをどこで定義したらいいですか?私は、jspがどのように知っているのか、xlsファイルをどこから選ぶのか、ということですか?以前はJavaプログラムで作成されたpdfでも使えますか? –

0

あなたはドンをダウンロードしたい場合は、tはHSSFを使用するには、それが遅くなり、より多くのスペースを消費apcheを使用するワークブックPDFファイルを使用するiTextのために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(); 

をPOI

 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(); 
関連する問題