12

Web アプリケーションのユーザーに、一部のデータを Excel ファイルとしてダウンロードしてもらいたいと考えています。

応答オブジェクトで入力ストリームを送信する次の関数があります。

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

4

4 に答える 4

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データをどこかに保存してから、それを入力ストリームに変換する必要があります。これは、ByteArrayOutputStreamに書き込んでから、ByteArrayInputStreamを使用してそれらのバイトを読み取ることで簡単に実行できますが、お勧めしません。既存のメソッドは、InputStreamからOutputStreamにデータをパイプできる一般的なパイプ実装としてより便利ですが、POIオブジェクトの書き込みには必要ありません。

于 2008-12-18T21:08:41.467 に答える
0

私はあなたがやろうとしていることを理解していると思います(しかし、私は過小評価しているかもしれません)

それほど多くのコードは必要ありません - write メソッドをチェックしてください -

HSSFWorkbook wb = new HSSFWorkBook();
//populate

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

私がPOIで働いていたときのことを覚えている限り、それが私がしたことです。Web フレームワーク内にいる場合は、それを閉じた後にフレームワークがその ServletOutputStream で何かをしようとしないように、それをいじる必要があるかもしれません。試行すると、出力ストリームが既に閉じられていることを示す例外がスローされます。

于 2008-12-18T20:31:05.257 に答える