OpenCSV教程:Java中CSVReader与CSVWriter使用指南及实例

OpenCSV的CSVReader和CSVWriter示例(第1部分,共2部分)

OpenCSV 是一个轻量级的 Java CSV 解析器。今天我们将研究一下 OpenCSV 的 CSV 解析示例。

OpenCSV开源库

OpenCSV提供了大部分CSV解析的基本功能。OpenCSV更受欢迎,因为在Java中没有内置的CSV解析器。OpenCSV CSV解析器的一些重要类包括:

  • CSVReader:这是OpenCSV中最重要的类。CSVReader类用于解析CSV文件。我们可以逐行解析CSV数据,也可以一次性读取所有数据。
  • CSVWriter:CSVWriter类用于将CSV数据写入Writer实现。您可以自定义分隔符和引号。
  • CsvToBean:当您想将CSV数据转换为Java对象时使用CsvToBean。
  • 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,张三,20,中国
2,李四,40,美国
3,王五,28,德国

以下是我们的Java bean类,用于保存CSV数据。

package com.Olivia.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(CSV阅读器)

我们第一个CSVReader的示例是逐行读取CSV文件,然后将其转换为员工列表。

package com.Olivia.csv.opencsv.parser;

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

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

/**
 * OpenCSV CSVReader 示例,逐行读取
 * 
 * @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>();

		// 逐行读取
		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.Olivia.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.Olivia.csv.model.Employee;
import com.opencsv.CSVReader;

/**
 * OpenCSV CSVReader 示例,一次性读取所有数据
 * 
 * @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();

	}

}

将CSV转换为Java Bean

这是文章《OpenCSV的CSVReader和CSVWriter示例》的第2部分(共2部分)。

我们大多数时候希望将CSV转换为Java对象。在这些情况下,我们可以使用CsvToBean。下面是一个简单的示例,展示如何将我们的员工CSV文件转换为员工对象列表。

package com.Olivia.csv.opencsv.parser;

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

import com.Olivia.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使用的方法。

// 为CSVWriter示例演示数据返回Employee列表
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文件。我们将重用上述定义的parseCSVWithHeader()函数。

package com.Olivia.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.Olivia.csv.model.Employee;
import com.opencsv.CSVWriter;

public class OpenCSVWriterExample {

	public static void main(String[] args) throws IOException {
		StringWriter writer = new StringWriter();
		
		// 使用自定义分隔符和引号字符
		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[]>();

		// 添加标题记录
		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: 用于将CSV输入的列名与bean中的字段绑定。
  • CsvBindByPosition: 用于将CSV输入的列号与bean中的字段绑定。
  • CsvDate: 用于基于时间的转换。

然而,我不想使用OpenCSV的注解,因为那样我的代码会与OpenCSV紧密耦合。这就是有关OpenCSV示例教程的全部内容。参考:OpenCSV官方页面。

bannerAds