Super CSVでBeanのリストを和名ヘッダーをつけてCSV出力 を以前書いて、入力のときに同じことができないかをやってみました。
結論としてはできます! これで落ち着いてCSV生活がおくれるというものです。
補足
2020年6月時点ですが、supercsvは新しいメンテナーを探している状況です。
最初に作った人が、時間もとれなくなり、モチベーションも下がったとのことです。
詳細はこちら。
このissueをみるに、立候補している人が最近出たようですが、どうなるか微妙です。
Javaのライフサイクルも変わったので、これから新しいプロジェクトに使うには躊躇うところです。
(結構使い勝手がよく、日本ではマッチするケースが多い気がするだけに、悩みどころです)
代替のライブラリとしては、univocity_parsers を見つけました。
サンプルコードもたくさん提供されています。
参考リンク
前提
Beanは次のようなものとします。getter,setterは省略しています。
読み取りの場合、setterは必須です。
class User {
/**
* ユーザID
*/
private String id;
/**
* ユーザ名
*/
private String name;
/**
* 削除フラグ
*/
private boolean deleted;
/* 中略 */
}
また、和名からカラム名へ変換するメソッドを事前に用意します。
// サンプルなので、guavaつかってそれっぽいのを作成
// 実際には設定ファイルなどから生成をするのを想定
Map<String,String> converter = ImmutableMap.Builder()
.put("ユーザID", "id")
.put("ユーザ名", "name")
.put("削除フラグ", "deleted")
.build();
public String[] toPropertyHeader(String[] header, Map<String,String> converter) {
/* converterをつかって、和名をカラム名に変化したarrayを生成 */
}
サンプルコード
次のようなCSVをとりこむとします。
ユーザID,ユーザ名,削除フラグ
001,ユーザその1,false
002,ユーザ2,true
File file = new File("user.csv");
try(ICsvBeanReader beanReader = new CsvMapReader(new FileReader(file), CsvPreference.EXCEL_PREFERENCE)) {
String[] header = beanReader .getHeader(true); // CSVの和名ヘッダーを取得
String[] propertyHeader = toPropertyHeader(header, converter); //和名ヘッダーをカラム名ヘッダーに変換
User user;
while((user= beanReader .read(User.class, propertyHeader)) != null) {
Logger.info("user {}", user);
}
} catch (Exception e) {
Logger.error("reading is failed.", e);
}
ポイントなのは、getHeaderで取得したのを変換するところです。
readerは、ヘッダー内のカラムの順番で値を持っているので、実際に渡されたヘッダー内の順番を保持する必要があります。こうした場合、ヘッダーの中の順番をかえても、結果的には名前でマッピングされているので、正しくとりこめます。
まとめ
Beanでやりました、Mapでもどうようのことができます。公式サイトをよく読んでみたら、
This relies on the fact that the column names in the header of the CSV file
customerNo,firstName,lastName,birthDate,mailingAddress,married,numberOfKids,favouriteQuote,email,loyaltyPoints
match up exactly with the bean's field names, and the bean has the appropriate setters defined for each field.
If your header doesn't match (or there is no header), then you can simply define your own name mapping array.
とあるので、もとのヘッダーがカラム名になってなかったら、自分で用意できるよということですね。もっとはやく気がつけば...