OpenCSVのCSVReaderとCSVWriterの例
OpenCSVは軽量なJava CSVパーサーです。今日は、CSVパースのためのOpenCSVの例を見てみましょう。
オープンCSV
OpenCSVは、CSV解析のためのほとんどの基本的な機能を提供しています。OpenCSVは、Javaに組み込まれたCSVパーサーがないため、より人気があります。OpenCSVのCSVパーサーの中でも重要なクラスには、次のものがあります。
-
- CSVReader: OpenCSVで最も重要なクラスです。CSVReaderクラスはCSVファイルをパースするために使用されます。CSVデータを行ごとにパースしたり、全データを一度に読み込むことができます。
-
- CSVWriter: CSVWriterクラスは、CSVデータをWriterの実装に書き込むために使用されます。カスタムの区切り記号や引用符を定義することもできます。
-
- CsvToBean: CsvToBeanは、CSVデータをJavaオブジェクトに変換したい場合に使用されます。
- BeanToCsv: BeanToCsvは、JavaのビーンをCSVファイルにエクスポートするために使用されます。
OpenCSVのMaven依存関係
以下のMaven依存関係を使用して、OpenCSVのjarファイルを追加することができます。
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>3.8</version>
</dependency>
例題プログラムを見る前に、デモ用のCSVデータと対応するJava Beanが必要です。以下はサンプルのCSVファイルである、emps.csvです。
1,Pankaj Kumar,20,India
2,David Dan,40,USA
3,Lisa Ray,28,Germany
以下は、CSVデータを保持するための私たちのJava Beanクラスです。
package com.scdev.csv.model;
public class Employee {
private String id;
private String name;
private String age;
private String country;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString() {
return "{" + id + "::" + name + "::" + age + "::" + country + "}";
}
}
CSVのパースとCSVの書き込みの一般的な例を見てみましょう。
CSVリーダー
最初のCSVReaderの例は、CSVファイルの行を一つずつ読み込んで、それを従業員のリストに変換するものです。
package com.scdev.csv.opencsv.parser;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.scdev.csv.model.Employee;
import com.opencsv.CSVReader;
/**
* OpenCSV CSVReader Example, Read line by line
*
* @author scdev
*
*/
public class OpenCSVReaderLineByLineExample {
public static void main(String[] args) throws IOException {
CSVReader reader = new CSVReader(new FileReader("emps.csv"), ',');
List<Employee> emps = new ArrayList<Employee>();
// read line by line
String[] record = null;
while ((record = reader.readNext()) != null) {
Employee emp = new Employee();
emp.setId(record[0]);
emp.setName(record[1]);
emp.setAge(record[2]);
emp.setCountry(record[3]);
emps.add(emp);
}
System.out.println(emps);
reader.close();
}
}
上記のCSVReaderの例は、理解しやすいです。重要なポイントは、メモリリークを避けるためにCSVReaderを閉じることです。また、他の文字を使用している場合に備えて区切り文字を指定することもできます。次のCSVReaderの例は、CSVReaderのreadAll()メソッドを使用して、データを一度にすべて読み取るものです。
package com.scdev.csv.opencsv.parser;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.scdev.csv.model.Employee;
import com.opencsv.CSVReader;
/**
* OpenCSV CSVReader Example, Read all at once
*
* @author scdev
*
*/
public class OpenCSVReaderReadAllExample {
public static void main(String[] args) throws IOException {
CSVReader reader = new CSVReader(new FileReader("emps.csv"), ',');
List<Employee> emps = new ArrayList<Employee>();
List<String[]> records = reader.readAll();
Iterator<String[]> iterator = records.iterator();
while (iterator.hasNext()) {
String[] record = iterator.next();
Employee emp = new Employee();
emp.setId(record[0]);
emp.setName(record[1]);
emp.setAge(record[2]);
emp.setCountry(record[3]);
emps.add(emp);
}
System.out.println(emps);
reader.close();
}
}
CsvToBean の内容を日本語で説明すると、
「CsvToBeanは、CSV形式のデータをJavaオブジェクトに変換するためのライブラリです。」
ほとんどの場合、CSVをJavaオブジェクトに変換したいです。このような場合は、CsvToBeanを使用することができます。以下に、従業員CSVファイルを従業員オブジェクトのリストに変換する方法を示す簡単な例があります。
package com.scdev.csv.opencsv.parser;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import com.scdev.csv.model.Employee;
import com.opencsv.CSVReader;
import com.opencsv.bean.ColumnPositionMappingStrategy;
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
public class OpenCSVParseToBeanExample {
public static void main(String[] args) throws IOException {
CSVReader reader = new CSVReader(new FileReader("emps.csv"), ',');
ColumnPositionMappingStrategy<Employee> beanStrategy = new ColumnPositionMappingStrategy<Employee>();
beanStrategy.setType(Employee.class);
beanStrategy.setColumnMapping(new String[] {"id","name","age","country"});
CsvToBean<Employee> csvToBean = new CsvToBean<Employee>();
List<Employee> emps = csvToBean.parse(beanStrategy, reader);
System.out.println(emps);
}
}
ColumnPositionMappingStrategyは、CSVデータの行インデックスをEmployeeオブジェクトのフィールドにマッピングするために使用されます。時にはCSVファイルにヘッダーデータも含まれます。例えば、以下のようなemps1.csvがあります。
ID,NAME,age, country
1,Pankaj Kumar,20,India
2,David Dan,40,USA
3,Lisa Ray,28,Germany
この場合、MappingStrategyの実装としてHeaderColumnNameMappingStrategyを使用することができます。以下は、HeaderColumnNameMappingStrategyの使用を示すメソッドです。
// returning list of Employee for CSVWriter example demo data
public static List<Employee> parseCSVWithHeader() throws IOException {
CSVReader reader = new CSVReader(new FileReader("emps1.csv"), ',');
HeaderColumnNameMappingStrategy<Employee> beanStrategy = new HeaderColumnNameMappingStrategy<Employee>();
beanStrategy.setType(Employee.class);
CsvToBean<Employee> csvToBean = new CsvToBean<Employee>();
List<Employee> emps = csvToBean.parse(beanStrategy, reader);
System.out.println(emps);
reader.close();
return emps;
}
CSVWriterを日本語で表現すると、「CSVの書き込み者」となります。
CSVWriterの例を見て、JavaオブジェクトをCSVへ書き込む方法を見てみましょう。先程定義したparseCSVWithHeader()を再利用します。
package com.scdev.csv.opencsv.parser;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.scdev.csv.model.Employee;
import com.opencsv.CSVWriter;
public class OpenCSVWriterExample {
public static void main(String[] args) throws IOException {
StringWriter writer = new StringWriter();
//using custom delimiter and quote character
CSVWriter csvWriter = new CSVWriter(writer, '#', '\'');
List<Employee> emps = OpenCSVParseToBeanExample.parseCSVWithHeader();
List<String[]> data = toStringArray(emps);
csvWriter.writeAll(data);
csvWriter.close();
System.out.println(writer);
}
private static List<String[]> toStringArray(List<Employee> emps) {
List<String[]> records = new ArrayList<String[]>();
// adding header record
records.add(new String[] { "ID", "Name", "Age", "Country" });
Iterator<Employee> it = emps.iterator();
while (it.hasNext()) {
Employee emp = it.next();
records.add(new String[] { emp.getId(), emp.getName(), emp.getAge(), emp.getCountry() });
}
return records;
}
}
CSVデータを書く際に、カスタム区切り文字の使用に注意してください。また、CSVの列のフィールドで使用する引用符の文字も指定しています。上記のCSVWriterの例では、次の出力が生成されます。
[{1::Pankaj Kumar::20::India}, {2::David Dan::40::USA}, {3::Lisa Ray::28::Germany}]
'ID'#'Name'#'Age'#'Country'
'1'#'Pankaj Kumar'#'20'#'India'
'2'#'David Dan'#'40'#'USA'
'3'#'Lisa Ray'#'28'#'Germany'
OpenCSVのCSVWriterを使用して、ResultSetを開く。
時々、データベースのテーブルデータをバックアップとしてCSVファイルに出力したいことがあります。その場合は、CSVWriterのwriteAll(ResultSet rs, boolean includeColumnNames)メソッドを使えば簡単に行うことができます。
OpenCSVアノテーション
OpenCSVはアノテーションベースのサポートも提供しています。OpenCSVの一部のアノテーションには、次のものがあります。
- CsvBindByName: for binding between a column name of the CSV input and a field in a bean.
- CsvBindByPosition: for binding between a column number of the CSV input and a field in a bean.
- CsvDate: for time based conversion.
ただし、OpenCSVのアノテーションを使用することは避けたいです。そうすると、コードはOpenCSVと密に結びついてしまいます。OpenCSVのexampleチュートリアルは以上です。参考:OpenCSV公式ページ。