Java OpenCSV

您所在的位置:网站首页 java写excel与写csv Java OpenCSV

Java OpenCSV

2024-06-18 15:56| 来源: 网络整理| 查看: 265

在 Opencsv 教程中,我们展示了如何与 Opencsv 库一起使用,该库用于在 Java 中读写 CSV 文件。 我们提供了一些代码示例,可在 Java 中使用 CSV。 该教程的源代码也可以从作者的 Github 存储库中获得。

CSV(逗号分隔值)格式是在电子表格和数据库中使用的非常流行的导入和导出格式。

CSV 文件中的每一行都是一个数据记录。 每个记录由一个或多个字段组成,用逗号分隔。 尽管 CSV 格式是一种非常简单的格式,但还是有许多差异,例如不同的定界符,换行或引号字符。

Opencsv 库

Opencsv 是一个非常简单的 Java CSV 解析器库。 它的开发是由于缺乏商业友好许可证。

com.opencsv opencsv 4.1

这是 Opencsv 的 Maven 依赖关系。

OpenCSV 读取数据

以下示例从 CSV 文件读取数字。

$ tree . ├── nbactions.xml ├── pom.xml └── src ├── main │ ├── java │ │ └── com │ │ └── zetcode │ │ └── OpenCSVReadEx.java │ └── resources │ └── numbers.csv └── test └── java

这是项目结构。

numbers.csv

3,5,6,2,1,7,8 4,5,7,3,2,8,9

numbers.csv文件中有两个数据记录。

OpenCSVReadEx.java

package com.zetcode; import com.opencsv.CSVReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; public class OpenCSVReadEx { public static void main(String[] args) throws IOException { String fileName = "src/main/resources/numbers.csv"; try (FileInputStream fis = new FileInputStream(fileName); InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8); CSVReader reader = new CSVReader(isr)) { String[] nextLine; while ((nextLine = reader.readNext()) != null) { for (String e : nextLine) { System.out.format("%s ", e); } } } } }

该示例从numbers.csv文件中读取数字并将其打印到控制台。

String fileName = "src/main/resources/numbers.csv";

该文件位于src/main/resources目录中。

try (FileInputStream fis = new FileInputStream(fileName); InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8); CSVReader reader = new CSVReader(isr)) {

CSVReader是用于读取 CSV 文件的类。

while ((nextLine = reader.readNext()) != null) { for (String e: nextLine) { System.out.format("%s ", e); } }

我们遍历读取器并将值打印到终端。 readNext()方法从缓冲区读取下一行,并转换为字符串数组。

3 5 6 2 1 7 8 4 5 7 3 2 8 9

这是程序的输出。

使用不同的分隔符的 OpenCSV 读取

尽管有 CSV 文件的名称,但也可以用逗号以外的分隔符分隔 CSV 文件。 下面的示例显示如何读取由竖线分隔的数字。 字符。

此示例使用 Gradle 工具构建。

$ tree . ├── build.gradle ├── settings.gradle └── src ├── main │ ├── java │ │ └── com │ │ └── zetcode │ │ └── OpenCSVReadEx2.java │ └── resources │ └── numbers.csv └── test ├── java └── resources

我们展示了项目结构。

settings.gradle

rootProject.name = 'OpenCSVReadEx2'

这是 Gradle 设置文件。

build.gradle

apply plugin: 'application' archivesBaseName = "readnumbers2" version = '1.0' mainClassName = "com.zetcode.OpenCSVReadEx2" sourceCompatibility = '1.8' compileJava.options.encoding = 'UTF-8' repositories { mavenCentral() } dependencies { compile group: 'com.opencsv', name: 'opencsv', version: '4.1' }

这是 Gradle 构建文件。

numbers.csv

1|2|3|4|5 6|7|3|9|8 9|1|1|0|2

我们有三行数字,中间用|分隔。 字符。

OpenCSVReadEx2.java

package com.zetcode; import com.opencsv.CSVParser; import com.opencsv.CSVParserBuilder; import com.opencsv.CSVReader; import com.opencsv.CSVReaderBuilder; import java.io.BufferedReader; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; public class OpenCSVReadEx2 { public static void main(String[] args) throws IOException { String fileName = "src/main/resources/numbers.csv"; Path myPath = Paths.get(fileName); CSVParser parser = new CSVParserBuilder().withSeparator('|').build(); try (BufferedReader br = Files.newBufferedReader(myPath, StandardCharsets.UTF_8); CSVReader reader = new CSVReaderBuilder(br).withCSVParser(parser) .build()) { List rows = reader.readAll(); for (String[] row : rows) { for (String e : row) { System.out.format("%s ", e); } System.out.println(); } } } }

该示例从numbers.csv文件中读取值,并将其打印到控制台。

CSVParser parser = new CSVParserBuilder().withSeparator('|').build();

创建具有特定解析器字符的CSVParser。

try (BufferedReader br = Files.newBufferedReader(myPath, StandardCharsets.UTF_8); CSVReader reader = new CSVReaderBuilder(br).withCSVParser(parser) .build()) {

用CSVReaderBuilder创建一个CSVReader。

List rows = reader.readAll();

我们使用readAll()方法将所有元素读入列表中。 此方法不应用于大文件。

$ gradle build $ gradle run :compileJava UP-TO-DATE :processResources UP-TO-DATE :classes UP-TO-DATE :run 1 2 3 4 5 6 7 3 9 8 9 1 1 0 2

我们构建并运行该示例。

OpenCSV 写入数据

CSVWriter类用于将数据写入 CSV 文件。

OpenCSVWriteEx.java

package com.zetcode; import com.opencsv.CSVWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; public class OpenCSVWriteEx { public static void main(String[] args) throws IOException { String[] entries = { "book", "coin", "pencil", "cup" }; String fileName = "src/main/resources/items.csv"; try (FileOutputStream fos = new FileOutputStream(fileName); OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8); CSVWriter writer = new CSVWriter(osw)) { writer.writeNext(entries); } } }

该示例将数据从数组写入items.csv文件。 该文件将写入项目根目录。 writeNext()方法将元素数组写入文件。

在下一个代码示例中,我们将所有数据一次性写入。

OpenCSVWriteEx2.java

package com.zetcode; import com.opencsv.CSVWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; public class OpenCSVWriteEx2 { public static void main(String[] args) throws IOException { String[] items1 = {"book", "coin", "pencil"}; String[] items2 = {"pen", "chair", "lamp"}; String[] items3 = {"ball", "bowl", "spectacles"}; List entries = new ArrayList(); entries.add(items1); entries.add(items2); entries.add(items3); String fileName = "src/main/resources/items.csv"; try (FileOutputStream fos = new FileOutputStream(fileName); OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8); CSVWriter writer = new CSVWriter(osw)) { writer.writeAll(entries); } } }

该示例使用writeAll()方法将数组列表写入items.csv文件。

将 SQL 数据转换为 CSV 文件

以下示例从数据库表中检索数据并将其写入 CSV 文件。 我们使用 MySQL 数据库。

cars_mysql.sql

-- SQL for the Cars table CREATE TABLE Cars(Id BIGINT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(150), Price INTEGER); INSERT INTO Cars(Name, Price) VALUES('Audi', 52642); INSERT INTO Cars(Name, Price) VALUES('Mercedes', 57127); INSERT INTO Cars(Name, Price) VALUES('Skoda', 9000); INSERT INTO Cars(Name, Price) VALUES('Volvo', 29000); INSERT INTO Cars(Name, Price) VALUES('Bentley', 350000); INSERT INTO Cars(Name, Price) VALUES('Citroen', 21000); INSERT INTO Cars(Name, Price) VALUES('Hummer', 41400); INSERT INTO Cars(Name, Price) VALUES('Volkswagen', 21600);

这是我们从中检索数据的Cars表。

pom.xml

4.0.0 com.zetcode OpenCSVDatabaseEx 1.0-SNAPSHOT jar UTF-8 1.8 1.8 com.opencsv opencsv 4.1 mysql mysql-connector-java 5.1.45

Maven 构建文件包含 Opencsv 和 MySQL 驱动程序的依赖项。

OpenCSVDatabaseEx.java

package com.zetcode; import com.opencsv.CSVWriter; import java.io.FileWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; public class OpenCSVDatabaseEx { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/testdb?useSsl=false"; String user = "testuser"; String password = "test623"; String fileName = "src/main/resources/cars.csv"; Path myPath = Paths.get(fileName); try (Connection con = DriverManager.getConnection(url, user, password); PreparedStatement pst = con.prepareStatement("SELECT * FROM Cars"); ResultSet rs = pst.executeQuery()) { try (CSVWriter writer = new CSVWriter(Files.newBufferedWriter(myPath, StandardCharsets.UTF_8), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.NO_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END)) { writer.writeAll(rs, true); } } catch (SQLException | IOException ex) { Logger.getLogger(OpenCSVDatabaseEx.class.getName()).log( Level.SEVERE, ex.getMessage(), ex); } } }

在示例中,我们连接到 MySQL 数据库并从Cars表中检索所有行。 数据被写入cars.csv文件。

try (Connection con = DriverManager.getConnection(url, user, password); PreparedStatement pst = con.prepareStatement("SELECT * FROM Cars"); ResultSet rs = pst.executeQuery()) {

我们使用驱动程序管理器连接到数据库表,并执行SELECT * FROM Cars语句。

try (CSVWriter writer = new CSVWriter(Files.newBufferedWriter(myPath, StandardCharsets.UTF_8), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.NO_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END)) {

我们创建一个CSVWriter,它带有默认的分隔符,没有引号,没有转义符和默认行尾。

writer.writeAll(rs, true);

writeAll()方法将java.sql.ResultSet作为参数。 第二个参数指定是否应包含字段头。

$ cat cars.csv ID,NAME,PRICE 1,Audi,52642 2,Mercedes,57127 3,Skoda,9000 4,Volvo,29000 5,Bentley,350000 6,Citroen,21000 7,Hummer,41400 8,Volkswagen,21600 9,Toyota,26700

代码示例将生成此文件。

Opencsv 映射到 JavaBeans

CsvToBean用于将 CSV 数据映射到 JavaBeans。

按列名映射

使用HeaderColumnNameMappingStrategy,我们可以使用 CSV 文件第一行中的列名将 CSV 数据映射到 Java 对象

$ tree . ├── nbactions.xml ├── pom.xml └── src ├── main │ ├── java │ │ └── com │ │ └── zetcode │ │ ├── bean │ │ │ └── Car.java │ │ └── OpenCSVReadBeansEx.java │ └── resources │ └── cars.csv └── test └── java

This is the project structure.

cars.csv

ID,NAME,PRICE 1,Audi,52642 2,Mercedes,57127 3,Skoda,9000 4,Volvo,29000 5,Bentley,350000 6,Citroen,21000 7,Hummer,41400 8,Volkswagen,21600 9,Toyota,26700

这是cars.csv文件。 第一条记录包含列名。

Car.java

package com.zetcode.bean; import com.opencsv.bean.CsvBindByName; public class Car { @CsvBindByName private int id; @CsvBindByName private String name; @CsvBindByName private int price; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Car{id=").append(id).append(", name=") .append(name).append(", price=").append(price).append("}"); return builder.toString(); } }

Car是 JavaBean。 它包含@CsvBindByName注解,用于将 bean 属性映射到 CSV 列。

OpenCSVReadBeansEx.java

package com.zetcode; import com.opencsv.bean.CsvToBean; import com.opencsv.bean.CsvToBeanBuilder; import com.opencsv.bean.HeaderColumnNameMappingStrategy; import com.zetcode.bean.Car; import java.io.BufferedReader; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; public class OpenCSVReadBeansEx { public static void main(String[] args) throws IOException { String fileName = "src/main/resources/cars.csv"; Path myPath = Paths.get(fileName); try (BufferedReader br = Files.newBufferedReader(myPath, StandardCharsets.UTF_8)) { HeaderColumnNameMappingStrategy strategy = new HeaderColumnNameMappingStrategy(); strategy.setType(Car.class); CsvToBean csvToBean = new CsvToBeanBuilder(br) .withType(Car.class) .withMappingStrategy(strategy) .withIgnoreLeadingWhiteSpace(true) .build(); List cars = csvToBean.parse(); cars.forEach(System.out::println); } } }

该示例从cars.csv文件中读取数据,并将它们映射到Car对象。 它使用HeaderColumnNameMappingStrategy。

HeaderColumnNameMappingStrategy strategy = new HeaderColumnNameMappingStrategy(); strategy.setType(Car.class);

HeaderColumnNameMappingStrategy使用 CSV 文件第一行中的列名将数据映射到对象。 列顺序无关紧要。

CsvToBean csvToBean = new CsvToBeanBuilder(br) .withType(Car.class) .withMappingStrategy(strategy) .withIgnoreLeadingWhiteSpace(true) .build();

用CsvToBeanBuilder创建一个CsvToBean。 我们指定类型和映射策略。

List cars = csvToBean.parse();

使用CsvToBean's parse()方法,我们将 CSV 数据解析到列表中。

cars.forEach(System.out::println);

我们遍历 bean 列表并将它们打印到控制台。

Car{id=1, name=Audi, price=52642} Car{id=2, name=Mercedes, price=57127} Car{id=3, name=Skoda, price=9000} Car{id=4, name=Volvo, price=29000} Car{id=5, name=Bentley, price=350000} Car{id=6, name=Citroen, price=21000} Car{id=7, name=Hummer, price=41400} Car{id=8, name=Volkswagen, price=21600} Car{id=9, name=Toyota, price=26700}

这是示例的输出。

按列位置进行映射

ColumnPositionMappingStrategy按列的位置映射。

cars.csv

1,Audi,52642 2,Mercedes,57127 3,Skoda,9000 4,Volvo,29000 5,Bentley,350000 6,Citroen,21000 7,Hummer,41400 8,Volkswagen,21600 9,Toyota,26700

这是cars.csv文件。

Car.java

package com.zetcode.bean; import com.opencsv.bean.CsvBindByPosition; public class Car { @CsvBindByPosition(position = 0) private int id; @CsvBindByPosition(position = 1) private String name; @CsvBindByPosition(position = 2) private int price; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Car{id=").append(id).append(", name=") .append(name).append(", price=").append(price).append("}"); return builder.toString(); } }

@CsvBindByPosition指定 CSV 输入的列号和 bean 中的字段之间的绑定。

OpenCSVReadBeansEx2.java

package com.zetcode; import com.opencsv.bean.ColumnPositionMappingStrategy; import com.opencsv.bean.CsvToBean; import com.opencsv.bean.CsvToBeanBuilder; import com.zetcode.bean.Car; import java.io.BufferedReader; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; public class OpenCSVReadBeansEx2 { public static void main(String[] args) throws IOException { String fileName = "src/main/resources/cars.csv"; Path myPath = Paths.get(fileName); try (BufferedReader br = Files.newBufferedReader(myPath, StandardCharsets.UTF_8)) { ColumnPositionMappingStrategy strategy = new ColumnPositionMappingStrategy(); strategy.setType(Car.class); String[] fields = {"id", "name", "price"}; strategy.setColumnMapping(fields); CsvToBean csvToBean = new CsvToBeanBuilder(br) .withType(Car.class) .withMappingStrategy(strategy) .withIgnoreLeadingWhiteSpace(true) .build(); List cars = csvToBean.parse(); cars.forEach(System.out::println); } } }

该示例从cars.csv文件中读取数据,并将它们映射到Car对象。 它使用ColumnPositionMappingStrategy。

ColumnPositionMappingStrategy strategy = new ColumnPositionMappingStrategy(); strategy.setType(Car.class); String[] fields = {"id", "name", "price"}; strategy.setColumnMapping(fields);

我们创建一个ColumnPositionMappingStrategy。 使用setColumnMapping(),我们设置要映射的列名。

Opencsv 使用StatefulBeanToCsv编写 JavaBeans

在下一个示例中,我们使用StatefulBeanToCsv将 JavaBeans 写入 CSV。

Car.java

package com.zetcode.bean; public class Car { private int id; private String name; private int price; public Car() { } public Car(int id, String name, int price) { this.id = id; this.name = name; this.price = price; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Car{id=").append(id).append(", name=") .append(name).append(", price=").append(price).append("}"); return builder.toString(); } }

这是一个Car bean。

OpenCSVWriteBeansEx.java

package com.zetcode; import com.opencsv.CSVWriter; import com.opencsv.bean.StatefulBeanToCsv; import com.opencsv.bean.StatefulBeanToCsvBuilder; import com.opencsv.exceptions.CsvDataTypeMismatchException; import com.opencsv.exceptions.CsvRequiredFieldEmptyException; import com.zetcode.bean.Car; import java.io.BufferedWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; public class OpenCSVWriteBeansEx { public static void main(String[] args) { String fileName = "src/main/resources/cars.csv"; Path myPath = Paths.get(fileName); List cars = new ArrayList(); cars.add(new Car(1, "Audi", 52642)); cars.add(new Car(2, "Mercedes", 57127)); cars.add(new Car(3, "Skoda", 9000)); cars.add(new Car(4, "Volvo", 29000)); try (BufferedWriter writer = Files.newBufferedWriter(myPath, StandardCharsets.UTF_8)) { StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer) .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER) .build(); beanToCsv.write(cars); } catch (CsvDataTypeMismatchException | CsvRequiredFieldEmptyException | IOException ex) { Logger.getLogger(OpenCSVWriteBeansEx.class.getName()).log( Level.SEVERE, ex.getMessage(), ex); } } }

该示例创建一个汽车对象列表,并将其写入 CSV 文件。

List cars = new ArrayList(); cars.add(new Car(1, "Audi", 52642)); cars.add(new Car(2, "Mercedes", 57127)); cars.add(new Car(3, "Skoda", 9000)); cars.add(new Car(4, "Volvo", 29000));

我们创建汽车对象列表。

StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer) .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER) .build();

用StatefulBeanToCsvBuilder创建一个StatefulBeanToCsv。

beanToCsv.write(cars);

Bean 被写入文件。

在本教程中,我们使用了 Opencsv 库。 我们已经从 CSV 文件读取数据,将数据写入 CSV 文件,从数据库表中导出数据到 CSV 文件,以及将 CSV 数据映射到 bean。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3