きり丸の技術日記

技術検証したり、資格等をここに残していきます。

SpringBootでCSVアップロードする(MultipartFile)

きり丸アドベントカレンダー2020の19記事目です。


ToDoアプリケーションでは、CSVファイルをアップロードして一括で登録するような機能があると便利です。ですので、ファイルをアップロードする仕組みを作りましょう。

ゴール

  • HTMLからJavaにファイルをアップロードする
  • アップロードしたCSVファイルを読み込んでDBに登録する

環境

  • Java
    • 15
  • org.springframework.boot:spring-boot-starter-web
    • 2.4.0

手順

HTMLでファイルアップロードボタンを作る


HTMLのFormタグのenctypeに「multipart/form-data」を指定するとファイルをアップロードできます。

また、Javaで受け取れるようにinputタグのnameを適当に指定します。

   <form method="post" action="/" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" name="upload_file" value="ファイルをアップロード">
        <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
    </form>

CSVファイルを準備する


事前にCSVファイルを作成します。今回はid、userIdとactionの3項目をもつCSVファイルを作成します。

4,admin,味噌
5,admin,オイスターソース
6,admin,家に帰る

JavaCSVファイルを受け取ってDBに登録する


@RequestParamにHTMLのinputタグで指定していたnameを指定します。アップロードしたファイルはMultipartFileクラスで受け取ります。

文字コードUTF-8で読み込んだ後に、BufferdReaderに変換します。

あとは、CSVファイルなのでカンマで分解してDBに渡せるように加工します。

  @PostMapping(value = "/", params = "upload_file")
  public String uploadFile(@RequestParam("file") MultipartFile uploadFile) {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(uploadFile.getInputStream(), StandardCharsets.UTF_8))){
      String line;
      while ((line = br.readLine()) != null) {
        final String[] split = line.split(",");
        final TodoDto todo = TodoDto.builder().id(Integer.parseInt(split[0])).userId(split[1]).action(split[2]).build();
        todoRepository.insert(todo);
      }
    } catch (IOException e) {
      throw new RuntimeException("ファイルが読み込めません", e);
    }

    return "redirect:/";
  }

ソースコード

アドベントカレンダー19日目。
github.com

終わりに

Controllerを使う場合は、この記事のような処理になります。RestControllerの場合、ファイルアップロードする場合はファイルをBase64でencodeし、受け取ったのちにdecodeします。

Controllerでのファイル操作を忘れていたので、こういう機会で素振りしました。

個人的にはREST APIで実装することが多いのでControllerで実装する機会が少ないのですが、ぜひ実践してみてください。


この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。

参考記事

敬称略

stack overflow:read data from MultipartFile which has csv uploaded from browser stackoverflow.com

類似記事

きり丸アドベントカレンダー2020 adventar.org

きり丸のHerokuページ
https://kirimaru-todoapp.herokuapp.com/

20日目のアドベントカレンダーの記事 https://nainaistar.hatenablog.com/entry/2020/12/20/083000nainaistar.hatenablog.com

f:id:nainaistar:20201109133010p:plain