LoginSignup
0
0

More than 1 year has passed since last update.

Spring Boot + Excel Upload + CSV出力

Last updated at Posted at 2021-09-12

PostmanでエクセルをPOSTし、Spring側でCSV出力

末尾の参考サイトのソースをもとに、PostmanでExcelをPOSTし、受信側(spring boot)でCSVライブラリの「OrangeSignal CSV」を利用してCSV出力した。
CSVのヘッダに日本語の列名を指定するところで物凄くつまったので、サンプルソースを記載する。

@Service
public class ExcelService {
  @Autowired TutorialRepository repository;
  public void save(MultipartFile file) {
    try {
      List<Tutorial> tutorials = ExcelHelper.excelToTutorials(file.getInputStream());
      repository.saveAll(tutorials);
      // 区切り文字と囲み文字、エスケープ文字を指定して CSV 形式設定情報を構築
      CsvConfig cfg = new CsvConfig(',', '"', '"');
      List<TutorialCSVData> tutorialCSVList =
          tutorials.stream().map(TutorialCSVData::toCSVDataFromPOJO).collect(Collectors.toList());
      File fileout = new File("Tutorial.csv");
      Csv.save(
          tutorialCSVList,
          fileout,
          cfg,
          new CsvEntityListHandler<TutorialCSVData>(TutorialCSVData.class));
    } catch (Exception e) {
      throw new RuntimeException("fail to store excel data: " + e.getMessage());
    }
  }
  public ByteArrayInputStream load() {
    List<Tutorial> tutorials = repository.findAll();

    ByteArrayInputStream in = ExcelHelper.tutorialsToExcel(tutorials);
    return in;
  }
  public List<Tutorial> getAllTutorials() {
    return repository.findAll();
  }
}

「OrangeSignal CSV」では、CSV出力にPOJOクラスが利用できる。
POJOクラスでは、@CsvEntity アノテーションと @CsvColumn アノテーションをつける。
@CsvColumn(name = "番号")とすると、CSVのヘッダ列の名前に"番号"を指定できる。
この指定をしない場合、CSVのヘッダ列の名前は、POJOクラスのフィールド名(この例では"id")となる。

参考元ソースには、データベースに格納する「Tutorial」Entityがあるが、
CSVに日本語項目を出力したかったので、別途「TutorialCSVData 」を作成し、TutorialからTutorialCSVDataに変換している。

OrangeSignal CSVサイトのユーザーガイドにある「ColumnNameMappingBeanListHandler」を使って、
項目列とPOJOオブジェクトフィールド(の変数名)を対応付けていたが、CSVの列が100以上の場合はしんどい。
100項目の定義をしたくないので、なんとかならないか調べたところ、@CsvEntityを使っている場合は、
「CsvEntityListHandler」を使えばよいということがわかった。
ここはユーザーガイドにも説明があるので、私の理解力がなかったようです。(ちょっと試してうまくいかなかったのであきらめてた)
将来、同じように困る人用にサンプルを載せておきます。

ちなみに公式のユーザーガイドにあるColumnNameMappingBeanListHandler#addColumnメソッドは誤記で、正しくはcolumnメソッドでした。詳細はJavadoc参照。

package com.bezkoder.spring.files.excel.model;

import com.orangesignal.csv.annotation.CsvColumn;
import com.orangesignal.csv.annotation.CsvEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@CsvEntity
public class TutorialCSVData {
  @CsvColumn(name = "番号")
  public String id;

  @CsvColumn(name = "タイトル")
  public String title;

  @CsvColumn(name = "詳細")
  public String description;

  @CsvColumn(name = "補足")
  public String published;

  public static TutorialCSVData toCSVDataFromPOJO(Tutorial tutorial) {
    return new TutorialCSVData(
        Long.toString(tutorial.getId()),
        tutorial.getTitle(),
        tutorial.getDescription(),
        String.valueOf(tutorial.isPublished()));
  }
}

CsvConfigクラスで””で囲ったり、改行コード(WIN, Mac, Linux)を指定できる。

CSV出力結果

Tutorial.csv
"番号","タイトル","詳細","補足"
"1","Spring Boot Tut#1","Tut#1 Description","false"
"2","Spring Boot Tut#2","Tut#2 Description","true"
"3","MySQL Database Tut#3","Tut#3 Description","true"
"4","Hibernate Tut#4","Tut#4 Description","false"
"5","Spring Cloud Tut#5","Tut#5 Description","true"
"6","Microservice Tut#6","Tut#6 Description","false"
"7","MongoDB Database Tut#7","Tut#7 Description","true"
"8","Spring Data JPA Tut#8","Tut#8 Description","true"

補足情報

「OrangeSignal CSV」利用のためのpom.xmlの設定です。

pom.xml
<dependency>
  <groupId>com.orangesignal</groupId>
  <artifactId>orangesignal-csv</artifactId>
  <version>2.2.1</version>
</dependency>

公式のクイックスタートではバージョンが「2.2.2-SNAPSHOT」となってますが、 Intellij環境ではmavenのエラーになり、読み込まれませんでした。

参考:
Spring Boot: Upload/Import Excel file data into MySQL Database
https://www.bezkoder.com/spring-boot-upload-excel-file-database/

ソースを動かす場合、エクセルのシート名は
ExcelHelperクラスのSHEETで「Tutorials」に定義されているので注意。(POSTするエクセルのシート名に変更)

OrangeSignal CSV
http://orangesignal.github.io/orangesignal-csv/index.html
https://github.com/orangesignal/orangesignal-csv/issues/29

おわり。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0