Spring Web MVCのViewでExcelを生成して返す
前回はSpring Web MVCのViewでPDFを生成して返すを試しました。
公式リファレンスによればExcelもできるようなので、同様に試してみました。
Spring Web MVC 公式リファレンス
Spring Web MVCの公式ドキュメントにおいて、Excel Viewについてはこちらに記載されています。
必要なライブラリ
Excelを扱う際、内部ではApache POIを使用します。
そのため、pom.xml
に以下の依存関係を追加します。
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.1</version>
</dependency>
実装例
Spring BootのWeb starterをベースにしました。
Xlsx Viewを定義し、そのViewをController側で使用しています。
PDF Viewの実装例
AbstractXlsxView
を継承し、以下のようにViewを実装しました。
シートを追加し、指定された行・列のセルに行列番号を書き込んでいます。
また、一番左上(0行目0列目)のセルにはmydata
として渡されたテキストデータを入れています。
public class MyExcelView extends AbstractXlsxView {
@Override
protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request,
HttpServletResponse response) throws Exception {
Sheet sheet = workbook.createSheet("MyTestSheet");
Row row = sheet.createRow(0);
Cell cell = row.createCell(3);
cell.setCellValue("0,3");
cell = row.createCell(0);
cell.setCellValue((String)model.get("mydata"));
row = sheet.createRow(11);
cell = row.createCell(0);
cell.setCellValue("11,0");
row = sheet.createRow(1);
cell = row.createCell(1);
cell.setCellValue("1,1");
cell = row.createCell(10);
cell.setCellValue("1,10");
}
}
Controllerの実装例
Controllerは以下のように実装しました。
動的なデータを渡す想定で、mydata
に文字列を入れて渡しています。
@Controller
public class ExcelController {
@RequestMapping("/excel")
public MyExcelView excel(MyExcelView mav) {
mav.addStaticAttribute("mydata", "myvalue");
return mav;
}
}
# 今回もModelAndViewの癖で、変数名をmavにしてしまった
動作確認
実装したものをローカルで実行しhttp://localhost:8080/excel
へアクセスすると、Excelがダウンロードできました。
MacのNumbersで開くと以下のように表示されました。
ControllerやViewで指定したデータが動的に差し込まれ、Excelが生成されていることを確認できました。
サンプル
作成したサンプルのソースコードはGitHubに置いてあります。
まとめ
Spring Web MVCのViewに、Excel Viewを使う方法を試しました。
今までこういったデータはCSVで生成することが多かったのですが、Excelで開き直すたびにデータの型を指定するのが大変だった他、複数のシートを合わせる場合は大変でした。
Excel形式のファイルであればデータの型も指定できますし、複数のシートを作ることもできるので、出力したデータをより手軽にExcelで扱えるようになりそうです。