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官方页面。