一、什么是CSV
逗号分隔值 (CSV) 文件只是一个普通的纯文本文件,将数据存储在一列一列中,然后用分隔符(如制表符\t,分号等,通常是逗号“,”) 将其拆分,是不同系统之间传输数据的一种常见方式。
OpenCSV 是 Java 的 CSV 解析库。OpenCSV 支持您想要执行的所有基本 CSV 类型操作。Java 7 目前是 OpenCSV 的最低支持版本。Java 语言不提供任何本身支持来有效处理 CSV 文件,因此我们使用 OpenCSV 处理 Java 中的 CSV 文件。下面是一个CSV文件的例子:
1,US,United States
2,MY,Malaysia
3,AU,Australia
二、如何在项目中添加 OpenCSV?
- 对于 maven 项目,您可以在 pom 中包含 OpenCSV maven 依赖项.xml文件。
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.3</version>
</dependency>
- 于 Gradle 项目,可以包括 OpenCSV 依赖项。
compile group: 'com.opencsv', name: 'opencsv', version: '5.3'
- 您可以下载OpenCSV Jar 并包括在项目类路径中。
三、OpenCSV的常用类
- CSVReader – 此类提供将 CSV 文件读取为字符串数组列表的操作。
- CSVWriter – 此类允许将数据写入 CSV 文件。
- CsvToBean – 当您想要把 CSV 文件内容填充到 java bean 时,将使用此类。
- BeanToCsv – 此类有助于将数据从 java 应用程序导出到 CSV 文件。
四、读取 CSV 文件
要读取 CSV 文件,您需要 CSVReader 类。以下是我们将要读取的示例 CSV 文件。
name, rollno, department, result, cgpa
amar, 42, cse, pass, 8.6
rohini, 21, ece, fail, 3.2
aman, 23, cse, pass, 8.9
rahul, 45, ee, fail, 4.6
pratik, 65, cse, pass, 7.2
raunak, 23, me, pass, 9.1
suvam, 68, me, pass, 8.2
我们可以通过两种方式读取 csv 文件:
- 按行读取数据 :让我们看看如何进行行读取 CSV 文件。为了一行一行地读取数据,首先我们必须通过传递CSV文件的CSVReader 对象来构造和初始化CSVReader对象。之后,我们必须调用 CSVReader 对象的 readNext()方法,以按行读取数据,如下代码所示。
// Java code to illustrate reading a
// CSV file line by line
public static void readDataLineByLine(String file)
{
try {
// Create an object of filereader
// class with CSV file as a parameter.
FileReader filereader = new FileReader(file);
// create csvReader object passing
// file reader as a parameter
CSVReader csvReader = new CSVReader(filereader);
String[] nextRecord;
// we are going to read data line by line
while ((nextRecord = csvReader.readNext()) != null) {
for (String cell : nextRecord) {
System.out.print(cell + "\t");
}
System.out.println();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
- 一次读取所有数据:我们使用 readNext() 方法一个一个的读取 CSV 记录。CSVReader 还提供一种称为 readAll() 的方法,用于一次将所有记录读取到列表中。
List allData = csvReader.readAll();
默认情况下,当我们读取 csv 文件时,不会忽略标头。当我们需要跳过列表中的第一个元素时,我们可以在创建 CSVReader 时指定开始行。
CSVReader csvReader = new CSVReaderBuilder(reader).withSkipLines(1).build();
代码:
// Java code to illustrate reading a
// all data at once
public static void readAllDataAtOnce(String file)
{
try {
// Create an object of file reader
// class with CSV file as a parameter.
FileReader filereader = new FileReader(file);
// create csvReader object and skip first Line
CSVReader csvReader = new CSVReaderBuilder(filereader)
.withSkipLines(1)
.build();
List<String[]> allData = csvReader.readAll();
// print Data
for (String[] row : allData) {
for (String cell : row) {
System.out.print(cell + "\t");
}
System.out.println();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
使用不同的分隔符读取 CSV 文件
CSV 文件可以用逗号以外的分隔符分隔,例如分号、冒号等。下面的示例演示如何读取 CSV 文件的数据,该文件用分号字符分隔。
分号分隔 CSV 文件示例:
name;rollno;department;result;cgpa
amar;42;cse;pass;8.6
rohini;21;ece;fail;3.2
aman;23;cse;pass;8.9
rahul;45;ee;fail;4.6
pratik;65;cse;pass;7.2
raunak;23;me;pass;9.1
suvam;68;me;pass;8.2
对于自定义分隔符,将创建具有特定解析器字符的第一个 CSVParser。
CSVParser parser = new CSVParserBuilder().withSeparator(';').build();
然后,我们将使用CSVParser()方法创建CSVReader对象,并提供了与CSVParser方法的参数的解析器对象。最后调用生成方法生成对象。
CSVReader csvReader = new CSVReaderBuilder(filereader).withCSVParser(parser).build();
代码:
// Java code to illustrate
// Reading CSV File with different separator
public static void readDataFromCustomSeperator(String file)
{
try {
// Create an object of file reader class with CSV file as a parameter.
FileReader filereader = new FileReader(file);
// create csvParser object with
// custom seperator semi-colon
CSVParser parser = new CSVParserBuilder().withSeparator(';').build();
// create csvReader object with parameter
// filereader and parser
CSVReader csvReader = new CSVReaderBuilder(filereader)
.withCSVParser(parser)
.build();
// Read all data at once
List<String[]> allData = csvReader.readAll();
// Print Data.
for (String[] row : allData) {
for (String cell : row) {
System.out.print(cell + "\t");
}
System.out.println();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
示例 – 读取两个 csv 文件result.csv 和 results_semicolon_Seperator.csv
result.csv具有默认分隔符','results_semicolon_Seperator.csv使用的是分隔符';''代替','。
代码:
// Java program to illustrate reading
// two CSV files
// with different seperators
import java.io.FileReader;
import java.util.List;
import com.opencsv.*;
public class ReadCSVData {
private static final String CSV_FILE_PATH
= "D:\\EclipseWorkSpace\\CSVOperations\\results.csv";
private static final String CSV_FILE_CUSTOM_SEPERATOR
= "D:\\EclipseWorkSpace\\CSVOperations\\results_semicolon_Seperator.csv";
public static void main(String[] args)
{
System.out.println("Read Data Line by Line With Header \n");
readDataLineByLine(CSV_FILE_PATH);
System.out.println("_______________________________________________");
System.out.println("Read All Data at Once and Hide the Header also \n");
readAllDataAtOnce(CSV_FILE_PATH);
System.out.println("_______________________________________________");
System.out.println("Custom Seperator here semi-colon\n");
readDataFromCustomSeperator(CSV_FILE_CUSTOM_SEPERATOR);
System.out.println("_______________________________________________");
}
public static void readDataLineByLine(String file)
{
try {
// Create an object of filereader class
// with CSV file as a parameter.
FileReader filereader = new FileReader(file);
// create csvReader object passing
// filereader as parameter
CSVReader csvReader = new CSVReader(filereader);
String[] nextRecord;
// we are going to read data line by line
while ((nextRecord = csvReader.readNext()) != null) {
for (String cell : nextRecord) {
System.out.print(cell + "\t");
}
System.out.println();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void readAllDataAtOnce(String file)
{
try {
// Create an object of filereader class
// with CSV file as a parameter.
FileReader filereader = new FileReader(file);
// create csvReader object
// and skip first Line
CSVReader csvReader = new CSVReaderBuilder(filereader)
.withSkipLines(1)
.build();
List<String[]> allData = csvReader.readAll();
// print Data
for (String[] row : allData) {
for (String cell : row) {
System.out.print(cell + "\t");
}
System.out.println();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void readDataFromCustomSeperator(String file)
{
try {
// Create object of filereader
// class with csv file as parameter.
FileReader filereader = new FileReader(file);
// create csvParser object with
// custom seperator semi-colon
CSVParser parser = new CSVParserBuilder().withSeparator(';').build();
// create csvReader object with
// parameter filereader and parser
CSVReader csvReader = new CSVReaderBuilder(filereader)
.withCSVParser(parser)
.build();
// Read all data at once
List<String[]> allData = csvReader.readAll();
// print Data
for (String[] row : allData) {
for (String cell : row) {
System.out.print(cell + "\t");
}
System.out.println();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
输出:
_______________________________________________
Read Data Line by Line With Header
name rollno department result cgpa
amar 42 cse pass 8.6
rohini 21 ece fail 3.2
aman 23 cse pass 8.9
rahul 45 ee fail 4.6
pratik 65 cse pass 7.2
raunak 23 me pass 9.1
suvam 68 me pass 8.2
_______________________________________________
Read All Data at Once and Hide the Header also
amar 42 cse pass 8.6
rohini 21 ece fail 3.2
aman 23 cse pass 8.9
rahul 45 ee fail 4.6
pratik 65 cse pass 7.2
raunak 23 me pass 9.1
suvam 68 me pass 8.2
_______________________________________________
Custom Seperator here semi-colon
name rollno department result cgpa
amar 42 cse pass 8.6
rohini 21 ece fail 3.2
aman 23 cse pass 8.9
rahul 45 ee fail 4.6
pratik 65 cse pass 7.2
raunak 23 me pass 9.1
suvam 68 me pass 8.2
_______________________________________________
五、写入 CSV 文件
写入 CSV 文件就像读取一样简单。通过将 FileWriter 对象作为参数传递,然后开始使用 CSVWrite 类的方法将数据写入 CSV 文件,创建 CSVWriter 实例。写入数据后,我们需要通过调用 CSVWriter 类的 close() 方法来关闭 CSVWriter 连接。
代码:
public static void writeDataLineByLine(String filePath)
{
// first create file object for file placed at location
// specified by filepath
File file = new File(filePath);
try {
// create FileWriter object with file as parameter
FileWriter outputfile = new FileWriter(file);
// create CSVWriter object filewriter object as parameter
CSVWriter writer = new CSVWriter(outputfile);
// adding header to csv
String[] header = { "Name", "Class", "Marks" };
writer.writeNext(header);
// add data to csv
String[] data1 = { "Aman", "10", "620" };
writer.writeNext(data1);
String[] data2 = { "Suraj", "10", "630" };
writer.writeNext(data2);
// closing writer connection
writer.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
输出:结果.csv以下数据的文件
"Name", "Class", "Marks"
"Aman", "10", "620"
"Suraj", "10", "630"
代码:
public static void writeDataAtOnce(String filePath)
{
// first create file object for file placed at location
// specified by filepath
File file = new File(filePath);
try {
// create FileWriter object with file as parameter
FileWriter outputfile = new FileWriter(file);
// create CSVWriter object filewriter object as parameter
CSVWriter writer = new CSVWriter(outputfile);
// create a List which contains String array
List<String[]> data = new ArrayList<String[]>();
data.add(new String[] { "Name", "Class", "Marks" });
data.add(new String[] { "Aman", "10", "620" });
data.add(new String[] { "Suraj", "10", "630" });
writer.writeAll(data);
// closing writer connection
writer.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
输出:
"Name", "Class", "Marks"
"Aman", "10", "620"
"Suraj", "10", "630"
使用不同的分隔符写 CSV 文件
默认情况下,CSV 的分隔符将是逗号"," 。如果要将另一个字符作为分隔符,以便它可以作为参数传递给 CSVWriter 类。
Syntax :
CSVWriter(Writer writer, char separator, char quotechar,
char escapechar, String lineEnd)
Description : Constructs CSVWriter with supplied separator,
quote char, escape char and line ending.
代码:
public static void writeDataForCustomSeperatorCSV(String filePath)
{
// first create file object for file placed at location
// specified by filepath
File file = new File(filePath);
try {
// create FileWriter object with file as parameter
FileWriter outputfile = new FileWriter(file);
// create CSVWriter with '|' as separator
CSVWriter writer = new CSVWriter(outputfile, '|',
CSVWriter.NO_QUOTE_CHARACTER,
CSVWriter.DEFAULT_ESCAPE_CHARACTER,
CSVWriter.DEFAULT_LINE_END);
// create a List which contains String array
List<String[]> data = new ArrayList<String[]>();
data.add(new String[] { "Name", "Class", "Marks" });
data.add(new String[] { "Aman", "10", "620" });
data.add(new String[] { "Suraj", "10", "630" });
writer.writeAll(data);
// closing writer connection
writer.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
输出:result.csv文件的数据如下
Name|Class|Marks
Aman|10|620
Suraj|10|630
示例:
让我们创建 一个java 程序,该程序生成分号分隔的 csv 文件,并包含作为Input提供的数据。
Input:
Enter no of rows
9
Enter Data
Name Class Marks
Aman 10 543
Amar 10 541
Sanjeet 10 555
Luv 10 580
Ranjeet 10 512
Rabi 10 540
Dev 10 333
Sunny 10 198
代码:
// Java program to illustrate
// for Writing Data in CSV file
import java.io.*;
import java.util.*;
import com.opencsv.CSVWriter;
public class ResultGenerator {
private static final String CSV_FILE_PATH
= "./result.csv";
public static void main(String[] args)
{
addDataToCSV(CSV_FILE_PATH);
}
public static void addDataToCSV(String output)
{
// first create file object for file placed at location
// specified by filepath
File file = new File(output);
Scanner sc = new Scanner(System.in);
try {
// create FileWriter object with file as parameter
FileWriter outputfile = new FileWriter(file);
// create CSVWriter with ';' as separator
CSVWriter writer = new CSVWriter(outputfile, ';',
CSVWriter.NO_QUOTE_CHARACTER,
CSVWriter.DEFAULT_ESCAPE_CHARACTER,
CSVWriter.DEFAULT_LINE_END);
// create a List which contains Data
List<String[]> data = new ArrayList<String[]>();
System.out.println("Enter no of rows");
int noOfRow = Integer.parseInt(sc.nextLine());
System.out.println("Enter Data");
for (int i = 0; i < noOfRow; i++) {
String row = sc.nextLine();
String[] rowdata = row.split(" ");
data.add(rowdata);
}
writer.writeAll(data);
// closing writer connection
writer.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出:下面是result.csv文件的数据
Name;Class;Marks
Aman;10;543
Amar;10;541
Sanjeet;10;555
Luv;10;580
Ranjeet;10;512
Rabi;10;540
Dev;10;333
Sunny;10;198
第六、踩坑[奸笑]
代码执行到CSVReader csvReader = new CSVReader(filereader);的时候就报错:
java.lang.ClassNotFoundException: org.apache.commons.lang3.ObjectUtils
报错很清楚,就是缺少了ObjectUtils这个类。您可以如下操作:
在gradle依赖中加上下面这个依赖,重新编译就可以了。
- 对于 maven 项目,您可以添加依赖项。
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
- 对于 Gradle 项目,可以包括下面这个依赖,重新编译就可以了。
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.11'
- 您也可以下载 Jar 并包括在项目类路径中。
https://commons.apache.org/proper/commons-lang/download_lang.cgi
完事收工[奸笑]