2

我倾向于使用CSVRecord,因为它可以用来映射标题并获取相应的值。我的应用程序经常使用 CSVRecord 类。但是,我无法实例化 CSVRecord。我不想修改源/创建一个新类,因为它已经提供了一个返回 CSVRecord 的解析器。我有一个需要转换为 CSVRecord 类型的字符串列表(标题以及值)。有没有直接的方法可以在不进行格式化然后解析的情况下完成此操作?像下面这样一个:

private CSVRecord format(List<String> header, List<String> values)
{
    CSVFormat csvFormat = CSVFormat.DEFAULT.withRecordSeparator(System.lineSeparator())
            .withQuoteMode(QuoteMode.ALL);
    CSVRecord csvRecord = null;
    final StringWriter out = new StringWriter();
    try (CSVPrinter csvPrinter = new CSVPrinter(out, csvFormat);)
    {
        csvPrinter.printRecord(values);
        String value = out.toString().trim();
        for (CSVRecord r : CSVParser.parse(value, csvFormat.withHeader(header.toArray(new String[header.size()]))))
            csvRecord = r;
    }
    catch (IOException e)
    {
        logger.error("Unable to format the Iterable to CSVRecord. Header: [{}]; Values: [{}]", e,
                String.join(", ", header), String.join(", ", values));
    }
    return csvRecord;
}

private void testMethod() throws Exception
{
    List<String> header = Arrays.asList("header1", "header2", "header3");
    List<String> record = Arrays.asList("val1", "val2", "val3");
    CSVRecord csvRecord = format(header, record);
    logger.info("{}", csvRecord.get("header2"));
}
4

2 回答 2

3

您可以将列表作为字符串直接传递到 CSVParser 而不是创建编写器。

CSVRecord csvr = CSVParser.parse(
values.stream().collect(Collectors.joining(","))
,csvFormat.withHeader(header.toArray(new String[header.size()])))
.getRecords().get(0);
于 2017-08-03T20:57:20.040 回答
1

BeanIO 和 SimpleFlatMapper 在解决这个问题方面做得更好。BeanIO 使用 Map 数据结构和配置文件来声明 CSV 文件的结构,因此非常强大。SimpleFlatMapper 默认将 POJO 属性作为标题名称,并输出属性值为列值。

BeanIO

http://beanio.org/2.1/docs/reference/index.html#CSVStreamFormat

SimpleFlatMapper

http://simpleflatmapper.org/

CsvParser
   .mapTo(MyObject.class)
   .stream(reader)
   .forEach(System.out::println);
于 2017-08-03T20:27:15.563 回答