WorkbookをHTTPレスポンスとしてダウンロードさせる。
Apache POIを使用してWorkbookオブジェクトを作成したと仮定する。
以下は作成済みのWorkbookオブジェクトをダウンロードするメソッドの例だ。
メソッドの例
Apache POIで主に使用するWorkbookオブジェクトはHSSFWorkbook、XSSFWorkbookは2種類ある。
HSSFWorkbookはExcel 97~2003(.xls)を処理する為のクラスで、古い。
XSSFWorkbookはExcel 2007以上(.xlsx) を処理する為のクラス。
HSSFWorkbookはサポートする機能も少ないし、スタイルもその数が制限されている。
色々不便だが、ここではHSSFWorkbookを例とする。
protected void exportXsl(HSSFWorkbook wb, String fileName, HttpServletResponse response) {
// HTTPレスポンスヘッダーを設定する。
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName);
// ワークブックオブジェクトをレスポンスに書き込む。outとresponseOutputStreamはtry with resourceで対応する。
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
OutputStream responseOutputStream = response.getOutputStream()) {
wb.write(out);
responseOutputStream.write(out.toByteArray());
responseOutputStream.flush(); // Flush the response output stream
} catch (IOException e) {
// 例外処理
} finally {
try {
wb.close();
} catch (IOException e) {
// 例外処理
}
}
}
このメソッドがvoidになっている理由はreturn "" や他の戻り値を返すコードを exportXsl メソッドに追加すると、2回レスポンスを送信しようとしてエラーが発生する可能性があるため。
exportXsl メソッド内で response.getOutputStream() を使って、ファイルをクライアントに送信している。この時点でレスポンスが確定し、ファイルが送られるのだ。
パラメーター説明
①HSSFWorkbook wb:作成済みのWorkbook (仮定: HSSFWorkbook)
②String fileName:ファイル名
③HttpServletResponse response:クライアントからダウンロードリクエストが来たら、それに対してHTTPレスポンスを送信するため
try with resource?
外部リソースを使った後に自動的にリソース閉じる仕組みのこと。
try()の括弧の中にリソースを宣言する方法。
try (ResourceType resource = new ResourceType()) {
// リソースを使った処理
} catch (ExceptionType e) {
// 例外処理
}
try with resourceをしないと?
リソースを手動で閉じる必要がある。
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("file.txt"));
...
} catch (IOException e) {
// 例外処理
} finally {
if (br != null) {
try {
br.close(); // 明示的にリソースを閉じる
} catch (IOException e) {
// 閉じる際の例外処理
}
}
}
閉じるって?
プログラムが使ったリソース(ファイル、ネットワーク接続、データベース接続など)を使い終わった後に解放する必要がある。無駄にメモリやシステム資源を消費することを防ぐ。
例ではoutとresponseOutputStreamはtry with resourceで対応していて、パラメーターのwbはfinallyブロックを使い、リソースのclose()メソッドを明示的に呼び出してリソースを解放している。
closeとflushの違いは?
flushとは、バッファに溜まっているデータを強制的に出力先に送る操作。バッファとは、データを一時的に保持するメモリ領域。なんで使うかというとI/O操作の効率を上げるため。小さなデータを一度に一つずつ書き込むのではなく、一定量のデータをバッファに溜めてから一度に書き出す。
通常、閉じる際に自動的にflushが行われる。なので、flushが必要な場面はリアルタイムにデータを反映させたい場合やすべてのデータを確実に送信したい場合。
結論:コードの理解
wb.write(out);
responseOutputStream.write(out.toByteArray());
responseOutputStream.flush();
- wb.write(out): HSSFWorkbookの内容をByteArrayOutputStream(out)に書き込んで,outはメモリ内のバッファにデータを保持します。
- responseOutputStream.write(out.toByteArray()): outに溜まったデータをHttpServletResponseの出力ストリーム(responseOutputStream)に書き込んでいる。
- responseOutputStream.flush(): responseOutputStreamに溜まったバッファのデータをクライアントに強制的に送っている。
( ・。。・ )🖐
間違っている内容がありましたら、教えて頂ければ喜びます。