- 公式ドキュメント
- Beanクラスの作成
- CSVファイルの書き込み
- CSVファイルの読み込み
- org.supercsv.prefs.CsvPreferenceの設定
- CSVファイルのうち一部のカラムを除外して読み書きしたい
- 書式を指定するアノテーション
公式ドキュメント
Beanクラスの作成
クラスには@CsvBean
アノテーションを付与する。
各フィールドには@CsvColumn
アノテーションを付与する。
その他作成するBeanクラスは以下のルールを満たしている必要がある。
import com.github.mygreen.supercsv.annotation.CsvBean; import com.github.mygreen.supercsv.annotation.CsvColumn; import lombok.Data; @Data @CsvBean public class Member { /** 名前 */ @CsvColumn(number = 1) private String name; /** 住所 */ @CsvColumn(number = 2) private String address; /** 年齢 */ @CsvColumn(number = 3) private int age; }
@CsvBeanの属性について
header
読み書きするCSVファイルにヘッダ行が存在する前提で処理をするかどうか。
trueを設定した場合、読み込み時は1行目をヘッダ行として扱い、書き込み時は1行目にヘッダ行を出力するようになる。
validateHeader
ヘッダー行の読み込み時に、値の検証を行うかどうか。
trueの場合、ヘッダー行の値が定義されている値と同じかどうか検証を行う。
検証の結果ヘッダーの値が不正な場合、com.github.mygreen.supercsv.exception.SuperCsvNoMatchHeaderException
がスローされる。
headerMapper
カラムに対するヘッダーラベルを取得方法を指定する。
デフォルトではカラムのラベル情報をヘッダーとする。
com.github.mygreen.supercsv.builder.HeaderMapper
の実装クラスを指定する。
validators
レコードに対する値の検証を行うクラスを指定する。
カラム間の相関チェックやBean Validationを使用する際に設定する。
com.github.mygreen.supercsv.validation.CsvValidator<?>
の実装クラスを指定する。
複数指定可能であり、指定した順にチェックが実行される。
listeners
ライフサイクルコールバック用のリスナークラスを指定するためのアノテーションを指定する。
@CsvColumnの属性について
number
CSVファイルから読み書きする際の列番号を指定する。
デフォルト値が設定されていて必須項目ではないように見えるが、列番号の重複は許可されていないので重複しないように値を設定する必要がある。
番号は1から設定する。
label
ヘッダに表示するカラム名を設定する。
未設定の場合はフィールド名が使用される。
builder
OSSがサポートしていないクラスにマッピングさせたい場合に使用する。
com.github.mygreen.supercsv.builder.ProcessorBuilder
を実装したクラスを指定する。
CSVファイルの書き込み
com.github.mygreen.supercsv.io.CsvAnnotationBeanWriter
クラスを使用してファイル書き込みを行う。
コンストラクタには、マッピングに使用するBeanクラス、Writer、CSV出力に係る各種設定を行うorg.supercsv.prefs.CsvPreference
を指定する。
1行ずつ書き込む
1行ずつ書き込みを行う場合はwrite()
メソッドを使用する。
このメソッドを使用する場合で、ヘッダ行を書き込みたい場合は、別途writeHeader()
メソッドを呼び出す必要がある。
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.List; import org.supercsv.prefs.CsvPreference; import com.github.mygreen.supercsv.io.CsvAnnotationBeanWriter; public class SampleCsvWriter { public void write() { try (FileWriter writer = new FileWriter("member.csv"); BufferedWriter bw = new BufferedWriter(writer); CsvAnnotationBeanWriter<Member> csvWriter = new CsvAnnotationBeanWriter<>( Member.class, bw, CsvPreference.STANDARD_PREFERENCE);) { Member member = new Member(); member.setName("太郎"); member.setAddress("愛知県名古屋市"); member.setAge(30); csvWriter.writeHeader(); csvWriter.write(member); csvWriter.flush(); } catch (IOException e) { } } }
上記の実装で出力されるCSVファイルは以下の通り
name,address,age 太郎,愛知県名古屋市,30
改行を含むデータを設定しても出力することができる
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.List; import org.supercsv.prefs.CsvPreference; import com.github.mygreen.supercsv.io.CsvAnnotationBeanWriter; public class SampleCsvWriter { public void write() { try (FileWriter writer = new FileWriter("member.csv"); BufferedWriter bw = new BufferedWriter(writer); CsvAnnotationBeanWriter<Member> csvWriter = new CsvAnnotationBeanWriter<>( Member.class, bw, CsvPreference.STANDARD_PREFERENCE);) { Member member = new Member(); member.setName("太郎\\n山田"); member.setAddress("愛知県名古屋市"); member.setAge(30); csvWriter.writeHeader(); csvWriter.write(member); csvWriter.flush(); } catch (IOException e) { } } }
上記の実装で出力されるCSVファイルは以下の通り
name,address,age "太郎 山田",愛知県名古屋市,30
複数行まとめて書き込む
複数行まとめて書き込みを行う場合はwriteAll()
メソッドを使用する。
@CsvBeanでheader属性にtrueが設定されている場合、ヘッダ行は自動で出力される。
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.List; import org.supercsv.prefs.CsvPreference; import com.github.mygreen.supercsv.io.CsvAnnotationBeanWriter; public class SampleCsvWriter { public void write() { try (FileWriter writer = new FileWriter("member.csv"); BufferedWriter bw = new BufferedWriter(writer); CsvAnnotationBeanWriter<Member> csvWriter = new CsvAnnotationBeanWriter<>( Member.class, bw, CsvPreference.STANDARD_PREFERENCE);) { Member member = new Member(); member.setName("太郎\\n山田"); member.setAddress("愛知県名古屋市"); member.setAge(30); Member member2 = new Member(); member2.setName("花子"); member2.setAddress("愛知県長久手市"); member2.setAge(45); List<Member> list = List.of(member, member2); csvWriter.writeAll(list); csvWriter.flush(); } catch (IOException e) { } } }
上記の実装で出力されるCSVファイルは以下の通り
name,address,age "太郎 山田",愛知県名古屋市,30 花子,愛知県長久手市,45
CSVファイルの読み込み
com.github.mygreen.supercsv.io.CsvAnnotationBeanReader.CsvAnnotationBeanReader
クラスを使用してファイル書き込みを行う。
コンストラクタには、マッピングに使用するBeanクラス、Reader、CSV入力に係る各種設定を行うorg.supercsv.prefs.CsvPreference
を指定する。
1行ずつ読み込む
1行ずつ読み込みを行う場合はread()
メソッドを使用する。
読み込み対象のCSVは以下の通り
"name","address","age" "太郎 山田","愛知県名古屋市","30" "花子","愛知県長久手市","45"
データ行の読み込みの前にヘッダ行を読み込まないと例外(com.github.mygreen.supercsv.exception.SuperCsvBindingException
)が発生する。
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.List; import org.supercsv.prefs.CsvPreference; import org.supercsv.quote.AlwaysQuoteMode; import com.github.mygreen.supercsv.io.CsvAnnotationBeanReader; public class SampleCsvReader { public void read() { CsvPreference preference = new CsvPreference.Builder('"', ',', "\\n") .useQuoteMode(new AlwaysQuoteMode()) .build(); try (FileReader reader = new FileReader("member.csv"); BufferedReader br = new BufferedReader(reader); CsvAnnotationBeanReader<Member> csvReader = new CsvAnnotationBeanReader<>( Member.class, br, preference);) { // ヘッダ行の読み込み String[] header = csvReader.getHeader(true); // データ行の読み込み Member member; while ((member = csvReader.read()) != null) { System.out.println(member); } } catch (IOException e) { } } }
Streamで読み込む
Streamで読み込みを行う場合はlines()
メソッドを使用する。
読み込み対象のCSVは以下の通り
"name","address","age" "太郎 山田","愛知県名古屋市","30" "花子","愛知県長久手市","45"
データ行の読み込みの前にヘッダ行を読み込まないと例外(com.github.mygreen.supercsv.exception.SuperCsvBindingException
)が発生する。
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.List; import org.supercsv.prefs.CsvPreference; import org.supercsv.quote.AlwaysQuoteMode; import com.github.mygreen.supercsv.io.CsvAnnotationBeanReader; public class SampleCsvReader { public void read() { CsvPreference preference = new CsvPreference.Builder('"', ',', "\\n") .useQuoteMode(new AlwaysQuoteMode()) .build(); try (FileReader reader = new FileReader("member.csv"); BufferedReader br = new BufferedReader(reader); CsvAnnotationBeanReader<Member> csvReader = new CsvAnnotationBeanReader<>( Member.class, br, preference);) { // ヘッダー行の読み込み String headers[] = csvReader.getHeader(true); // データ行の読み込み csvReader.lines().forEach((member) -> { System.out.println(member); }); } catch (IOException e) { } } }
全行まとめて読み込む
複数行まとめて書き込みを行う場合はreadAll()
メソッドを使用する。
@CsvBeanでheader属性にtrueが設定されている場合、1行目はヘッダとみなされる。
読み込み対象のCSVは以下の通り
"name","address","age" "太郎山田","愛知県名古屋市","30" "花子","愛知県長久手市","45"
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.List; import org.supercsv.prefs.CsvPreference; import org.supercsv.quote.AlwaysQuoteMode; import com.github.mygreen.supercsv.io.CsvAnnotationBeanReader; public class SampleCsvReader { public void read() { CsvPreference preference = new CsvPreference.Builder('"', ',', "\\n") .useQuoteMode(new AlwaysQuoteMode()) .build(); try (FileReader reader = new FileReader("member.csv"); BufferedReader br = new BufferedReader(reader); CsvAnnotationBeanReader<Member> csvReader = new CsvAnnotationBeanReader<>( Member.class, br, preference);) { List<Member> list = csvReader.readAll(); for (Member m : list) { System.out.println(m); } } catch (IOException e) { } } }
org.supercsv.prefs.CsvPreferenceの設定
quoteChar
データ内に区切り文字や改行コードがあった時にデータを囲う文字を指定する。
delimiterCharと異なる値を設定する。
delimiterChar
カラムの区切り文字を設定する。
quoteCharと異なる値を設定する。
endOfLineSymbols
改行コードを設定する。
surroundingSpacesNeedQuotes
セルの先頭または末尾にあるスペースが引用符で囲まれていない場合、無視するかどうか(CSVの読み込みと書き込みの両方に適用可能)。
trueを設定した場合、無視する。
デフォルト:false
ignoreEmptyLines
空行(すなわち、行末記号のみを含む)を無視するかどうか。
trueを設定した場合、無視する。
デフォルト:true
encoder
カスタムCsvEncoderを使用して、書き込む際にCSVをエスケープする。org.supercsv.encoder.CsvEncoder
の実装クラスを指定する。
quoteMode
独自のQuoteModeを書き込み時に適用する(カラムに特殊文字が含まれておらず、クォートが適用されない場合のみ適用される)。
独自のQuoteModeを用意して設定するか、 定義済みのものを使用する。
- AlwaysQuoteMode
AlwaysQuoteModeを使用する場合、常に引用符で囲む設定が適用される - ColumnQuoteMode
ColumnQuoteModeを使用する場合、特殊文字のエスケープに必要な場合、または特定の列が常に引用符で囲むべきな場合に引用符で囲む。
org.supercsv.quote.QuoteMode
の実装クラスを指定する。
commentMatcher
コメントをスキップする機能を有効にする。
独自のCommentMatcherを用意して設定するか、 定義済みのものを使用する。
- CommentStartsWith
指定したStringで始まる行にマッチするCommentMatcher
指定した文字列で始まる行をコメントとみなす - CommentMatches
指定された正規表現に合致する行にマッチする CommentMatcher
指定された正規表現に合致する行をコメントとみなす
org.supercsv.comment.CommentMatcher
を実装したクラスを指定する。
maxLinesPerRow
例外が発生する前に行がまたがることができる最大行数 (CSVを読み込み時のみ適用可能)。
このオプションは、引用符が対応しないCSVに遭遇したときに、CSVリーダが高速に失敗することを可能とする。
通常の動作では、対応する引用符が見つかるまで読み込みを続けるが、これはファイル全体を読み込むことになる可能性があり、利用可能なメモリをすべて使い果たすかもしれない。
0または負の値を指定すると、無効となる。 デフォルト: 0
quoteChar, delimiterChar, endOfLineSymbolsについて設定されたものが予め4種類定数で用意されているので、ニーズが合えばそれを使用しても良い。
定数名 | quoteChar | delimiterChar | endOfLineSymbols |
---|---|---|---|
STANDARD_PREFERENCE | " | , | \r\n |
EXCEL_PREFERENCE | " | , | \n |
EXCEL_NORTH_EUROPE_PREFERENCE | " | ; | \n |
TAB_PREFERENCE | " | \t | \n |
以下にCsvPreferenceの設定を定数を使用せずにした場合の実装サンプルを示す。
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.List; import org.supercsv.prefs.CsvPreference; import org.supercsv.quote.AlwaysQuoteMode; import com.github.mygreen.supercsv.io.CsvAnnotationBeanWriter; public class SampleCsvWriter { public void write() { CsvPreference preference = new CsvPreference.Builder('"', ',', "\\n") .useQuoteMode(new AlwaysQuoteMode()) .build(); try (FileWriter writer = new FileWriter("member.csv"); BufferedWriter bw = new BufferedWriter(writer); CsvAnnotationBeanWriter<Member> csvWriter = new CsvAnnotationBeanWriter<>( Member.class, bw, preference);) { Member member = new Member(); member.setName("太郎\\n山田"); member.setAddress("愛知県名古屋市"); member.setAge(30); Member member2 = new Member(); member2.setName("花子"); member2.setAddress("愛知県長久手市"); member2.setAge(45); List<Member> list = List.of(member, member2); csvWriter.writeAll(list); csvWriter.flush(); } catch (IOException e) { } } }
上記の実装で出力されるCSVファイルは以下の通り
"name","address","age" "太郎 山田","愛知県名古屋市","30" "花子","愛知県長久手市","45"
CSVファイルのうち一部のカラムを除外して読み書きしたい
Beanクラスに@CsvPartial
アノテーションを付与することで実現可能。
import com.github.mygreen.supercsv.annotation.CsvBean; import com.github.mygreen.supercsv.annotation.CsvColumn; import com.github.mygreen.supercsv.annotation.CsvPartial; import lombok.Data; @Data @CsvBean(header = true) @CsvPartial(columnSize = 5, headers = { @CsvPartial.Header(number = 3, label = "電話番号"), @CsvPartial.Header(number = 5, label = "生年月日") }) public class SampleCsv { // 読み書きしないフィールドは宣言しない @CsvColumn(number = 1, label = "ID") private int id; @CsvColumn(number = 2, label = "氏名") private String name; @CsvColumn(number = 4, label = "メールアドレス") private String email; }
@CsvPartialの属性
columnSize
実際のCSVファイルのカラム数を指定する。 フィールドの@CsvColumnのnumber属性の値よりも大きい値を設定する。
headers
Beanに定義されていないカラムのヘッダー情報を設定する。 ヘッダ情報には以下の2つが設定可能
- カラム番号
- ヘッダのラベル
ファイルの読み書きを実装する
読み込み対象のCSVは以下の通り
"ID","氏名","電話番号","メールアドレス","生年月日" "1","山田","09012345678","sample@co.jp","19991212"
ファイルの読み書きの実装方法は、除外カラムの有無にかかわらず同一である。
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import org.supercsv.prefs.CsvPreference; import org.supercsv.quote.AlwaysQuoteMode; import com.github.mygreen.supercsv.io.CsvAnnotationBeanReader; import com.github.mygreen.supercsv.io.CsvAnnotationBeanWriter; public class SampleCsvOperation { void partial() { CsvPreference preference = new CsvPreference.Builder('"', ',', "\\n") .useQuoteMode(new AlwaysQuoteMode()) .build(); // 一部カラムを除外したファイル読み込み try (FileReader reader = new FileReader("partial_test.csv"); BufferedReader br = new BufferedReader(reader); CsvAnnotationBeanReader<SampleCsv> csvReader = new CsvAnnotationBeanReader<>( SampleCsv.class, br, preference);) { // ヘッダー行の読み込み String headers[] = csvReader.getHeader(true); // データ行の読み込み csvReader.lines().forEach((member) -> { System.out.println(member); }); } catch (IOException e) { } // 一部カラムを除外したファイル書き込み try (FileWriter writer = new FileWriter("partial_test_write.csv"); BufferedWriter bw = new BufferedWriter(writer); CsvAnnotationBeanWriter<SampleCsv> csvWriter = new CsvAnnotationBeanWriter<>( SampleCsv.class, bw, preference);) { SampleCsv csv = new SampleCsv(); csv.setId(2); csv.setName("ほげ"); csv.setEmail("hoho@co.jp"); csvWriter.writeHeader(); csvWriter.write(csv); csvWriter.flush(); } catch (IOException e) { } } }
上記の実装で出力されるCSVファイルは以下の通り
"ID","氏名","電話番号","メールアドレス","生年月日" "2","ほげ",,"hoho@co.jp",
書式を指定するアノテーション
@CsvBooleanFormat
クラスタイプが「boolean/Boolean」のマッピング規則を定義する際に使用する。
属性には以下のものがある。
- readForTrue 読み込むときにtrueと判定する文字列の配列
- readForFalse 読み込むときにfalseと判定する文字列の配列
- ignoreCase 読み込むときに大文字・小文字を無視するかどうか
- failToFalse 読み込むときに「readForTrue」「readForFalse」にない値をfalseとして読み込むかどうか
- message パースに失敗した時のメッセージ
- writeAsTrue 書き込むときにtrueを表現する値
- writeAsFalse 書き込むときにfalseを表現する値
@Data @CsvBean(header = true) public class Member { /** フラグ */ @CsvColumn(number = 4) @CsvBooleanFormat(readForTrue = { "○", "有効", "レ" }, readForFalse = { "×", "無効", "-", "" }, writeAsTrue = "○", writeAsFalse = "×", ignoreCase = true, failToFalse = true, message = "パースに失敗した!") private boolean flag; }
@CsvNumberFormat
数値型に対する書式を指定する際に使用する。
- byte/short/int/long/float/double のプリミティブ型とそのラッパークラス
- java.math.BigDecimal / java.math.BigInteger の数値クラス
プリミティブ型に対して読み込む際に、CSVのカラムの値が空の場合、それぞれのプリミティブ型の初期値が設定される。
属性には以下のものがある。
- pattern
数値の書式を指定する
指定しない場合、クラスごとの標準の書式を使用する - lenient
読み込み時に数値の解析を曖昧に行うか
trueの場合、曖昧な解析を行う(デフォルト:false) - currency
通貨コードを指定する
java.util.Currencyで解釈可能なコードを指定
pattern指定時のみ有効 - locale
ロケールを指定する
省略した場合、システム標準の値を使用する - rounding
丸め方の方法を指定する
java.math.RoundingModeの値を設定する - precision
丸めの精度を指定する
pattern未指定時のみ有効
主に小数の場合に有効桁数を揃える際に使用する - message
パースに失敗した時のメッセージ
@CsvDateTimeFormat
日時型に対する書式を指定する際に使用する。
アノテーションを付与していないときや属性 pattern を指定しないときは、クラスタイプごとに決まった標準の書式が適用される。
標準の書式はここを参照。
属性には以下のものがある。
- pattern
日時の書式を指定する
指定しない場合、クラスごとの標準の書式を使用する - lenient
読み込み時に日時の解析を曖昧に行うか
trueの場合、曖昧な解析を行う(デフォルト:false) - timezone
タイムゾーンを指定する
省略した場合、システム標準の値を使用する - locale
ロケールを指定する
省略した場合、システム標準の値を使用する - message
パースに失敗した時のメッセージ
@Data @CsvBean(header = true) public class Member { /** 日時 */ @CsvColumn(number = 5) @CsvDateTimeFormat(pattern = "uuuu/MM/dd HH:mm:ss") private LocalDateTime datetime; }
@CsvEnumFormat
Enumの変換規則の設定を行う際に使用する。
アノテーション @CsvEnumFormat を付与しなくてもマッピングは可能。
マッピングには、カラムの値とEnumの要素の値(Enum#name())が使用される。
属性には以下のものがある。
- ignoreCase
読み込むときに大文字・小文字を無視するかどうか - selector
Enum#name()の値とは別の値でマッピングさせたい場合に、マッピングに使用するメソッド名を指定する
メソッドは引数なしの文字列型を返すものが指定可能 - message
パースに失敗した時のメッセージ
selectorを指定したマッピングの書き方
public enum RoleType { Normal("一般権限"), Admin("管理者権限"); private String localeName; private RoleType(String localeName) { this.localeName = localeName; } public String localeName() { return this.localeName; } }
Beanクラス
@Data @CsvBean(header = true) public class Member { /** Enum */ @CsvColumn(number = 6) @CsvEnumFormat(ignoreCase = true, selector = "localeName") private RoleType role; }