Apache Commons CSV 教程

厉文栋
2023-12-01

Apache Commons CSV 教程

Apache Commons CSV 库很容易实现创建和读取CSV文件。本文我们通过示例进行详细学习。

maven 依赖

首先增加合适的版本依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.4</version>
</dependency>

读CSV文件

下面示例读取book.csv文件,发起内容如下:

author,title
Dan Simmons,Hyperion
Douglas Adams,The Hitchhiker’s Guide to the Galaxy

下面代码展示如何读取:

Map<String, String> AUTHOR_BOOK_MAP = new HashMap<>() {
    {
        put("Dan Simmons", "Hyperion");
        put("Douglas Adams", "The Hitchhiker's Guide to the Galaxy");
    }
}
String[] HEADERS = { "author", "title"};
 
@Test
public void givenCSVFile_whenRead_thenContentsAsExpected() throws IOException {
    Reader in = new FileReader("book.csv");
    Iterable<CSVRecord> records = CSVFormat.DEFAULT
      .withHeader(HEADERS)
      .withFirstRecordAsHeader()
      .parse(in);
    for (CSVRecord record : records) {
        String author = record.get("author");
        String title = record.get("title");
        assertEquals(AUTHOR_BOOK_MAP.get(author), title);
    }
}

示例代码读csv文件记录,并跳过首行。可以指定不同类型的CSV文件格式CSVFormat,下面示例会涉及。

创建CSV文件

下面看如何创建csv文件:

public void createCSVFile() throws IOException {
    FileWriter out = new FileWriter("book_new.csv");
    try (CSVPrinter printer = new CSVPrinter(out, CSVFormat.DEFAULT
      .withHeader(HEADERS))) {
        AUTHOR_BOOK_MAP.forEach((author, title) -> {
            printer.printRecord(author, title);
        });
    }
}

新文件包括标题行及相应记录。

首行及按列读

有不同的方式读写首行,也有不同方式读写列值,下面依次说明。

按列索引读

这是最基本的读列方式,适合于不知道csv文件的首行场景:

Reader in = new FileReader("book.csv");
Iterable<CSVRecord> records = CSVFormat.DEFAULT.parse(in);
for (CSVRecord record : records) {
    String columnOne = record.get(0);
    String columnTwo = record.get(1);
}

根据预定义的首行读列值

相比于按索引读更直接:

Iterable<CSVRecord> records = CSVFormat.DEFAULT
  .withHeader("author", "title").parse(in);
for (CSVRecord record : records) {
    String author = record.get("author");
    String title = record.get("title");
}

使用首行枚举

通过字符串读取列值容易产生错误。使用枚举代替字符串使代码更规范,更好理解:

enum BookHeaders {
    author, title
}
 
Iterable<CSVRecord> records = CSVFormat.DEFAULT
  .withHeader(BookHeaders.class).parse(in);
for (CSVRecord record : records) {
    String author = record.get(BookHeaders.author);
    String title = record.get(BookHeaders.title);
}

跳过首行

通常csv文件包括首行,因此,大多数情况,跳过首行从第二行开始。下面代码自动检测首行:

Iterable<CSVRecord> records = CSVFormat.DEFAULT
  .withFirstRowAsHeader().parse(in);
for (CSVRecord record : records) {
    String author = record.get("author");
    String title = record.get("title");
}

通过首行创建csv文件

同样我们可以通过首行创建csv文件:

FileWriter out = new FileWriter("book_new.csv");
CSVPrinter printer = CSVFormat.DEFAULT
  .withHeader("author", "title").print(out);

总结

文本通过示例学习了Apache’s Commons CSV 库,更多内容可以查看官方文档

 类似资料: