首页 > 解决方案 > Camel CsvDataFormat 解组 Excel csv 文件的多个问题

问题描述

我需要处理从政府网站获得的 csv 文件。该文件有两种不同的格式问题,Camel CsvDataFormat unmarshal 无法同时处理这些问题。最小测试文件:

Registration No,Trade Name
"A009928","Rotagen "Combo""
"A010343","Vet Direct Abamectin Wormer, Bot + Tape"

使用此代码解组:

CsvDataFormat csv = new CsvDataFormat();
csv.setDelimiter(","); 
csv.setQuoteDisabled(true); 
csv.setUseMaps(false);
from("file://c:/temp?fileName=test.csv&noop=true")
           .unmarshal(csv)
           .process(new Processor() {
                public void process(Exchange exchange) throws Exception {
                     List<List<String>> rows = (List<List<String>>) exchange.getIn().getBody();
                     for (int j = 0; j< rows.size();j++) {
                        List<String> row = rows.get(j);
    
                        for (int i = 0; i< row.size();i++) {
                            log.info("ITEM["+row.get(i)+"]");
                            }
                     
                        
                     }
               }
           
        });


当 setQuoteDisabled(false) 我得到:

java.lang.IllegalStateException:IOException 读取下一条记录:java.io.IOException:(第 2 行)封装的标记和分隔符之间的无效字符

当 setQuoteDisabled(true) 文件被解组,但第 3 行在额外的 ',' 处结束了额外的拆分,这是输出:

13:10| INFO | MainRoute.java 54 | ITEM[Registration No]
13:10| INFO | MainRoute.java 54 | ITEM[Trade Name]
13:10| INFO | MainRoute.java 54 | ITEM["A009928"]
13:10| INFO | MainRoute.java 54 | ITEM["Rotagen "Combo""]
13:10| INFO | MainRoute.java 54 | ITEM["A010343"]
13:10| INFO | MainRoute.java 54 | ITEM["Vet Direct Abamectin Wormer]
13:10| INFO | MainRoute.java 54 | ITEM[ Bot + Tape"]

如何配置 CsvDataFormat 以正确解组两行?

标签: csvapache-camel

解决方案


嗯,这是 CSV 作为“软标准”的问题。行和分隔符或多或少是标准化的,但是当涉及到引号时,它就变得复杂了。

由于您的数据被引用(即每个字段值都在引号中),正确的配置将是

setQuoteDisabled(false)

第二条记录适用于此配置。

"A010343","Vet Direct Abamectin Wormer, Bot + Tape"

因为字段是用引号括起来的,所以数据里面的逗号是没有问题的。

但是,第一条记录在 data 中包含引号

"A009928","Rotagen "Combo""

根据RFC-4180,第 2.7 段此类引号必须使用附加引号进行转义

如果使用双引号括住字段,则出现在字段内的双引号必须通过在其前面加上另一个双引号来进行转义。

"A009928","Rotagen ""Combo"""

您可以尝试在一条记录中手动修复此问题,看看它是否像这样工作。

通常,您有多种选择:

  • 通知数据提供者他的数据不符合 RFC-4180 并要求他修复它
  • 在使用 Camel 读取数据之前先修复数据
  • 自己解析数据,补偿报价问题

推荐阅读