【问题标题】:How to verify if first line of CSV file matches the header names?如何验证 CSV 文件的第一行是否与标题名称匹配?
【发布时间】:2021-04-20 06:35:30
【问题描述】:

我想处理这种结构的CSV文件:

header1,header2
val1.1, val1.2
val2.1, val2.2

但前提是第一行包含两个标题名称 - 否则抛出异常。

我目前使用Apache Common CSV 的实现是:

Reader reader = new InputStreamReader(new ByteArrayInputStream(file.getContent()));

CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT
            .withHeader("header1", "header2")
            .withSkipHeaderRecord());

for (CSVRecord csvRecord : csvParser) { /* records processing */ }

问题是第一行的值可能与标题名称不同,并且文件仍在处理中。

【问题讨论】:

标签: java csv apache-commons-csv


【解决方案1】:

参考Java Doc of CSVFormat

安全地引用列

如果您的源代码包含标题记录,您可以通过使用不带参数的 withHeader(String...) 来简化代码并安全地引用列:

 CSVFormat.EXCEL.withHeader();

这会导致解析器读取第一条记录并将其值用作列名。然后,调用采用 String 列名参数的 CSVRecord get 方法之一:

 String value = record.get("Col1");

这使您的代码不受 CSV 文件中列顺序更改的影响。


所以你可以按照这个并使用第一行作为标题,然后验证标题CSVParser#getHeaderNames

下面是一个简单的演示:

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

public class UseFirstRowAsHeader {
    public static void main(String[] args) throws IOException {
        String validHeaderCsv = "header1,header2\r\n"
                + "val1.1,val1.2\r\n"
                + "val2.1,val2.2";
        parseWithHeaderValidation(validHeaderCsv);
        String invalidHeaderCsv = "header1,header2,header3\r\n"
                + "val1.1,val1.2\r\n"
                + "val2.1,val2.2";
        parseWithHeaderValidation(invalidHeaderCsv);
    }

    private static void parseWithHeaderValidation(String validHeaderCsv) throws IOException {
        Reader reader = new StringReader(validHeaderCsv);
        List<String> expectedHeaders = new ArrayList<String>();
        expectedHeaders.add("header1");
        expectedHeaders.add("header2");
        try (CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT
                .withHeader().withAllowMissingColumnNames(false)
                .withSkipHeaderRecord())) {
            if (!csvParser.getHeaderNames().equals(expectedHeaders)) {
                throw new IllegalStateException("Not expected headers" + csvParser.getHeaderNames());
            }

            for (CSVRecord csvRecord : csvParser) {
                System.out.println(csvRecord.get("header1") + "," + csvRecord.get("header2"));
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    相关资源
    最近更新 更多