Java+SpringBootで検索結果をCSVダウンロードできる機能を実装できたので備忘録として残しておきます。
で、このCSVボタンを押すと、検索結果全てがCSVファイルとしてダウンロードされるようにします
1 - まずこんな感じで検索ボタンが押された後のレコード情報をhiddenの<form>に入れて保持しておきます。
<form id="csvform" method="post" th:action="@{/asset/csv}" th:object="${csvForm}">
<div th:each="asset:${assets}">
<input type="hidden" name="id" th:value="${asset.id}" />
<input type="hidden" name="categoryId" th:value="${asset.categoryId}" />
<input type="hidden" name="adminName" th:value="${asset.adminName}" />
<input type="hidden" name="assetName" th:value="${asset.assetName}" />
<input type="hidden" name="remarks" th:value="${asset.remarks}" />
</div>
<button type="submit">CSV</button>
</form>
2 - で、CSボタンが押されたらこの情報全てをポスト送信し、コントローラー側で受け取ってCSV形式に整形し、ダウンロードしてくれます。この際に、CSV records
ではなく、List<CSV> records
とすると、エラーが起きてしまうのはなぜだか分からずじまい... とりあえずList<Object>を受け取るにはList<Object>をフィールドにもっとクラスを用意しておかないといけないみたい。
@PostMapping(value = "/csv", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE
+ "; charset=UTF-8; Content-Disposition: attachment")
@ResponseBody
public Object csvDownload(@ModelAttribute("csvForm") CSV records) throws JsonProcessingException {
List<CsvColumn> csvList = new ArrayList<>();
for (int i = 0; i < records.getId().size(); i++) { // レコードの数ぶんだけループ回して
csvList.add(new CsvColumn(records.getId().get(i), records.getCategoryId().get(i), records.getAdminName().get(i), records.getAssetName().get(i), records.getRemarks().get(i)));
}
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(CsvColumn.class).withHeader();
return mapper.writer(schema).writeValueAsString(csvList);
}
@Data
public class CSV {
List<Integer> id;
List<Integer> categoryId;
List<String> adminName;
List<String> assetName;
List<String> remarks;
}
@JsonPropertyOrder({"資産ID", "資産種別", "管理者名", "資産名", "備考"})
@Data
public class CsvColumn {
@JsonProperty("資産ID")
private Integer id;
@JsonProperty("資産種別")
private Integer categoryId;
@JsonProperty("管理者名")
private String adminName;
@JsonProperty("資産名")
private String assetName;
@JsonProperty("備考")
private String remarks;
public CsvColumn () {}
public CsvColumn (Integer id, Integer categoryId, String adminName, String assetName, String remarks) {
this.id = id;
this.categoryId = categoryId;
this.adminName = adminName;
this.assetName = assetName;
this.remarks = remarks;
}