ふりぶろぐ
Web Engineer's Blog
Java

【Java】Super CSV & Super CSV Annotationの使い方!【ライブラリ】

Java
環境
  • Java 11
  • Play framework 2.6
  • Super CSV 2.4.0
  • Super CSV Annotation 2.2

JavaでCSVを扱うライブラリはいくつかあると思いますが、今回はSuper CSVを使ってみました。

共通処理として実装しておくと使い回しができて便利でした。

ちなみに今回、私はPlay Framework 2.6で使用しました。
メインで使っているフレームワークがPlay Frameworkなんですよね。

以前使用したことがあったのですが、そのときはSpring Bootでした。

どちらも同じJavaなので基本的に使い方は同じです。

実際に使ってみる!

今回はサンプルとして店舗情報のCSVを取り込む想定。
こんなCSVを取り込んでみます。

sample.csv

店舗ID,店舗名,電話番号
1,A店,0000000001
2,B店,0000000002
3,C店,0000000003

店舗ID店舗名電話番号
1A店0000000001
2B店0000000002
3C店0000000003

ライブラリのインポート

Super CSVを使えるようにするためにbuild.sbtに追記します。

バージョンは最新ものもにしたほうが良いと思います。

super-csv-annotationも必要になるのでここで追加します。

libraryDependencies += "net.sf.supercsv" % "super-csv" % "2.4.0"
libraryDependencies += "com.github.mygreen" % "super-csv-annotation" % "2.2"

DTOを用意する

CSVから変換するDTOを作成します。

import com.github.mygreen.supercsv.annotation.CsvBean;
import com.github.mygreen.supercsv.annotation.CsvColumn;

/**
 * 店舗DTO
 */
@CsvBean(header = true)
public class SampleShopDto {
    /**
     * 店舗ID
     */
    @CsvColumn(number = 1, label = "店舗ID")
    public String id;

    /**
     * 店舗名
     */
    @CsvColumn(number = 2, label = "店舗名")
    public String name;

    /**
     * 電話番号
     */
    @CsvColumn(number = 3, label = "電話番号")
    public String tel;

    public SampleShopDto() {
    }
}

変換処理

共通処理として作ってみました。
第三引数を切り替えることでTSVも変換できます。

CSVとTSVを両方使う場面も多いと思うのでありがたい!

一応、書き出し処理も作っておいたので残しておきます。

/**
 * CSVファイルを読み込む
 * @param path ファイルパス
 * @param clazz Beanクラス
 * @param csvPreference CSV(STANDARD_PREFERENCE) or TSV(TAB_PREFERENCE)
 * @return List
 */
public static <T> List<T> readCsv(String path, Class<T> clazz, CsvPreference csvPreference) {
    try (
            CsvAnnotationBeanReader<T> csvReader = new CsvAnnotationBeanReader<>(
                    clazz,
                    Files.newBufferedReader(new File(path).toPath(), Charset.defaultCharset()),
                    csvPreference
            )
    ) {
        return csvReader.readAll();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

/**
 * CSVファイルを書き出す
 * @param path 保存先
 * @param clazz Beanクラス
 * @param csvPreference CSV(STANDARD_PREFERENCE) or TSV(TAB_PREFERENCE)
 * @param list データ
 */
public static <T> void writeCsv(String path, Class<T> clazz, CsvPreference csvPreference, List<T> list) {
    try (
            CsvAnnotationBeanWriter<T> csvWriter = new CsvAnnotationBeanWriter<>(
                    clazz,
                    Files.newBufferedWriter(new File(path).toPath(), Charset.defaultCharset()),
                    csvPreference
            )
    ) {
        csvWriter.writeAll(list);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

読み込み

あとはこんな感じでメソッドを呼んであげるだけ!

final String PATH = "XXXXXXXXX";
List<SampleShopDto> sampleShopDtoList = readCsv(PATH + "sample.csv", SampleShopDto.class, CsvPreference.STANDARD_PREFERENCE);
sampleShopDtoList.forEach(sampleShopDto -> {
    System.out.println(sampleShopDto.id + " ," + sampleShopDto.name + ", " + sampleShopDto.tel);
});

PATHは自分がCSVを配置したディレクトリを指定してください。
ちなみにディレクトリはパーミッション変更しておかないとCSVを読み込めないはず。

結果

1 ,A店, 0000000001
2 ,B店, 0000000002
3 ,C店, 0000000003

書き出し

書き出しはこんな感じ。

final String PATH = "XXXXXXXXX";
SampleShopDto sampleShopDto = new SampleShopDto();
sampleShopDto.id = "4";
sampleShopDto.name = "D店";
sampleShopDto.tel = "0000000004";
List<SampleShopDto> sampleShopDtoList = Collections.singletonList(sampleShopDto);
writeCsv(PATH + "sample2.csv", SampleShopDto.class, CsvPreference.STANDARD_PREFERENCE, sampleShopDtoList);

読み込みの処理を逆にしただけですね。

sample2.csv

店舗ID,店舗名,電話番号
4,D店,0000000004

店舗ID店舗名電話番号
4D店0000000004

まとめ

Super CSVを使ってCSVを処理してみました。

難しい部分はすべてライブラリがやってくれるので簡単ですね。

自分で実装するよりもシンプルに実装できるので保守もしやすくなると思います。

独自で処理を作成するよりも簡単なので是非使ってみてください!

ABOUT ME
りーふ
たまにブログを書いてるWebエンジニア。 サーバーサイドメインでインフラとフロントエンドもたまにやります。 Javaが得意。 Play Frameworkが好き。 本業は迷惑をかけない程度に手を抜くスタイル。 意識高い系は苦手。