我想处理这种结构的 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 */ }
问题是第一行的值可能与 header 名称不同,文件仍在处理中。
最佳答案
安全地引用列
如果您的源代码包含标题记录,您可以通过使用不带参数的 withHeader(String...) 来简化代码并安全地引用列:
CSVFormat.EXCEL.withHeader();
这会导致解析器读取第一条记录并将其值用作列名。然后,调用采用字符串列名参数的 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"));
}
}
}
}
关于java - 如何验证 CSV 文件的第一行是否与标题名称匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65732573/