OpenCSV CSVReader CSVWriter示例

时间:2020-02-23 14:41:36  来源:igfitidea点击:

OpenCSV是轻量级的Java CSV解析器。
今天,我们将研究用于CSV解析的OpenCSV示例。

OpenCSV

OpenCSV提供了CSV解析的大多数基本功能。
OpenCSV之所以受欢迎,是因为Java中没有内置的CSV解析器。
OpenCSV CSV解析器中的一些重要类是:

  • CSVReader:这是OpenCSV中最重要的类。
    CSVReader类用于解析CSV文件。
    我们可以逐行解析CSV数据或者一次读取所有数据。

  • CSVWriter:CSVWriter类用于将CSV数据写入Writer实现。
    您可以定义自定义定界符以及引号。

  • CsvToBean:当您想将CSV数据转换为Java对象时使用CsvToBean。

  • BeanToCsv:BeanToCsv用于将Java bean导出到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,hyman Kumar,20,San Franceco
2,David Dan,40,USA
3,Lisa Ray,28,Germany

下面是用于保存CSV数据的java bean类。

package com.theitroad.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文件行,然后转换为Employee列表。

package com.theitroad.csv.opencsv.parser;

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

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

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

/**
 * OpenCSV CSVReader Example, Read all at once
 * 
 * @author hyman
 *
 */
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转换为java对象。
在这些情况下,我们可以使用CsvToBean。
下面是一个简单的示例,显示了如何将我们的员工CSV文件转换为Employee对象列表。

package com.theitroad.csv.opencsv.parser;

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

import com.theitroad.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,hyman Kumar,20,San Franceco
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

让我们看一下CSVWriter示例,该示例将Java对象写入CSV Writer。
我们将重用上面定义的parseCSVWithHeader()

package com.theitroad.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.theitroad.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::hyman Kumar::20::San Franceco}, {2::David Dan::40::USA}, {3::Lisa Ray::28::Germany}]
'ID'#'Name'#'Age'#'Country'
'1'#'hyman Kumar'#'20'#'San Franceco'
'2'#'David Dan'#'40'#'USA'
'3'#'Lisa Ray'#'28'#'Germany'

OpenCSV CSVWriter结果集

有时我们想将数据库表数据转储为CSV文件作为备份。
我们可以使用CSVWriter的writeAll(ResultSet rs,boolean includeColumnNames)方法轻松做到这一点。

OpenCSV注释

OpenCSV也提供基于注释的支持。
一些OpenCSV注释是;

  • CsvBindByName:用于在CSV输入的列名和bean中的字段之间进行绑定。

  • CsvBindByPosition:用于在CSV输入的列号和bean中的字段之间进行绑定。

  • CsvDate:用于基于时间的转换。