OpenCSV CSVReader CSVWriter 예


OpenCSV는 경량 자바 CSV 파서입니다. 오늘은 CSV 파싱을 위한 OpenCSV 예제를 살펴보겠습니다.

OpenCSV

  1. CSVReader: 이것은 OpenCSV에서 가장 중요한 클래스입니다. CSVReader 클래스는 CSV 파일을 구문 분석하는 데 사용됩니다. CSV 데이터를 한 줄씩 파싱하거나 한 번에 모든 데이터를 읽을 수 있습니다.
  2. CSVWriter: CSVWriter 클래스는 CSV 데이터를 Writer 구현에 쓰는 데 사용됩니다. 따옴표뿐만 아니라 맞춤 구분 기호를 정의할 수 있습니다.
  3. CsvToBean: CsvToBean은 CSV 데이터를 Java 개체로 변환하려는 경우에 사용됩니다.
  4. BeanToCsv: BeanToCsv는 자바 빈을 CSV 파일로 내보내는 데 사용됩니다.

OpenCSV Maven 종속성

아래 maven 종속성을 사용하여 OpenCSV jar를 추가할 수 있습니다.

<dependency>
	<groupId>com.opencsv</groupId>
	<artifactId>opencsv</artifactId>
	<version>3.8</version>
</dependency>

예제 프로그램을 살펴보기 전에 데모 CSV 데이터와 해당 자바 빈이 필요합니다. 다음은 샘플 CSV 파일 emps.csv입니다.

1,Pankaj Kumar,20,India
2,David Dan,40,USA
3,Lisa Ray,28,Germany

아래는 CSV 데이터를 보유하는 자바 빈 클래스입니다.

package com.journaldev.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 쓰기의 몇 가지 일반적인 예를 살펴보겠습니다.

CSVReader

첫 번째 CSVReader 예제는 CSV 파일 행을 하나씩 읽은 다음 Employee 목록으로 변환하는 것입니다.

package com.journaldev.csv.opencsv.parser;

import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.journaldev.csv.model.Employee;
import com.opencsv.CSVReader;

/**
 * OpenCSV CSVReader Example, Read line by line
 * 
 * @author pankaj
 *
 */
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.journaldev.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.journaldev.csv.model.Employee;
import com.opencsv.CSVReader;

/**
 * OpenCSV CSVReader Example, Read all at once
 * 
 * @author pankaj
 *
 */
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

대부분의 경우 CSV를 자바 개체로 변환하려고 합니다. 이러한 경우 CsvToBean을 사용할 수 있습니다. 다음은 직원 CSV 파일을 직원 개체 목록으로 변환하는 방법을 보여주는 간단한 예입니다.

package com.journaldev.csv.opencsv.parser;

import java.io.FileReader;
import java.io.IOException;
import java.util.List;

import com.journaldev.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 데이터 행 인덱스를 직원 개체 필드에 매핑하는 데 사용됩니다. 때때로 CSV 파일에도 헤더 데이터가 있습니다. 예를 들어 아래와 같이 emps1.csv가 있을 수 있습니다.

ID,NAME,age, country
1,Pankaj Kumar,20,India
2,David Dan,40,USA
3,Lisa Ray,28,Germany

이 경우 HeaderColumnNameMappingStrategy를 MappingStrategy 구현으로 사용할 수 있습니다. 다음은 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 Writer에 자바 개체를 쓰는 CSVWriter 예제를 살펴보겠습니다. 위에서 정의한 parseCSVWithHeader()를 재사용합니다.

package com.journaldev.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.journaldev.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 결과 집합

때때로 데이터베이스 테이블 데이터를 CSV 파일에 백업으로 덤프하려고 합니다. CSVWriter writeAll(ResultSet rs, boolean includeColumnNames) 메서드를 사용하면 쉽게 할 수 있습니다.

OpenCSV 주석

OpenCSV는 주석 기반 지원도 제공합니다. 일부 OpenCSV 주석은 다음과 같습니다.

  • CsvBindByName: CSV 입력의 열 이름과 빈의 필드 간 바인딩용.
  • CsvBindByPosition: CSV 입력의 열 번호와 빈의 필드 사이를 바인딩합니다.
  • CsvDate: 시간 기반 변환용.

그러나 저는 OpenCSV 주석을 사용하고 싶지 않습니다. 그러면 내 코드가 OpenCSV와 밀접하게 결합되기 때문입니다. 이것이 OpenCSV 예제 튜토리얼의 전부입니다. 참조: OpenCSV 공식 페이지