きり丸アドベントカレンダー2020の20記事目です。
前回の記事でCSVのアップロード処理を書きました。逆に、CSVのダウンロード処理もできるとうれしいです。
ですので、今回の記事ではCSVダウンロードします。
ゴール
- CSVファイルをダウンロードする
環境
- Java
- 15
- org.springframework.boot:spring-boot-starter-web
- 2.4.0
- (org.springframework.boot:spring-boot-starter-security)
- 2.4.0(重要ではないですが、検証ソースで使っているので…)
- (Lombok)
手順
HTMLでファイルダウンロードボタンを作る
今回は、actionのURLがそのままファイル名となるように作っているので、ログインしている情報からuserIdを取得します。
ログインユーザーは、kirimaruとadminを用意しているので、実際のactionのURLは「/kirimaru.csv」か「admin.csv」になることを想定しています。
<form method="get" th:action="|/${#authentication.principal.username}.csv|"> <input type="submit" name="download_file" value="ファイルをダウンロード"> <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" /> </form>>
CSVファイル用のDTOを用意する
@JsonProperty
で出力したいCSVファイルのカラム名を指定します。
@JsonPropertyOrder
を付けることで、確実にcsvファイルの出力される順番が保証されるので、書くべきでしょう。
@Value @AllArgsConstructor @JsonPropertyOrder({"ID", "UserId", "Action"}) public class TodoCsv { @JsonProperty("ID") private long id; @JsonProperty("UserId") private String userId; @JsonProperty("Action") private String action; }
DBから取得した値を元にCSVファイルをダウンロードする
@GetMapping
のvalueがそのままファイル名となります。producesに文字コード等を設定します。
今回の処理で大事なのは次の処理です。他の項目はアドベントカレンダーとしては必要ですが、この記事だけを見に来た人にとっては蛇足になります。
CsvMapper mapper = new CsvMapper(); CsvSchema schema = mapper.schemaFor(TodoCsv.class).withHeader(); return mapper.writer(schema).writeValueAsString(csvs);
ファイル名:IndexController.java
@GetMapping(value = "/*.csv", params = "download_file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8; Content-Disposition: attachment" ) @ResponseBody public Object index() throws JsonProcessingException { // User名取得 SecurityContext securityContext = (SecurityContext) session.getAttribute("SPRING_SECURITY_CONTEXT"); Authentication authentication = securityContext.getAuthentication(); AuthTargetUser principal = (AuthTargetUser) authentication.getPrincipal(); String username = principal.getUsername(); // DBから取得 List<TodoDto> todos = todoRepository.findList(username); // CSVファイル用のDTOに詰め直す List<TodoCsv> csvs = todos.stream().map( e -> new TodoCsv(e.getId(), e.getUserId(), e.getAction()) ).collect(Collectors.toList()); // ファイルをダウンロードさせる CsvMapper mapper = new CsvMapper(); CsvSchema schema = mapper.schemaFor(TodoCsv.class).withHeader(); return mapper.writer(schema).writeValueAsString(csvs); }}
ソースコード
アドベントカレンダー20日目。
github.com
終わりに
アップロードと比べてダウンロードが非常に面倒でした。まさかCSVファイル用に別のライブラリを入れる必要があったとは…。
正直、「参考記事をやってみた」以上の情報が無いので、もっと詳しいことは参考記事の先を見ていただけると分かります。追加情報としては、2020年でも動くよ―程度ですね。
普段触っていない機能は理解が難しいです。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。
参考記事
敬称略
yo1000:Spring MVC で CSV をダウンロードさせる qiita.com
類似記事
きり丸アドベントカレンダー2020 adventar.org
きり丸のHerokuページ
https://kirimaru-todoapp.herokuapp.com/
21日目のアドベントカレンダーの記事 nainaistar.hatenablog.com