【发布时间】:2019-05-24 15:23:02
【问题描述】:
我编写了一个简单的测试应用程序,它从数据库中读取记录并将结果放入 csv 文件中。到目前为止它工作正常,但列名,即标题没有放在 csv 文件中。根据文档,它应该放在那里。我也试过不带/带流和拆分,但情况是一样的。
在第 182 行的骆驼单元测试中,标题被明确地放在那里:https://github.com/apache/camel/blob/master/components/camel-csv/src/test/java/org/apache/camel/dataformat/csv/CsvDataFormatTest.java
如何在不遍历标题的情况下解决这个非常简单的问题?我还尝试了不同的设置,但都一样。例如,我已经设置了分隔符,但没有设置标题。也提前感谢您的回复。
我像这样使用 Camel 2.16.1:
final CsvDataFormat csvDataFormat = new CsvDataFormat();
csvDataFormat.setHeaderDisabled(false);
[...]
from("direct:TEST").routeId("TEST")
.setBody(constant("SELECT * FROM MYTABLE"))
.to("jdbc:myDataSource?readSize=100") // max 100 records
// .split(simple("${body}")) // split the list
// .streaming() // not to keep all messages in memory
.marshal(csvDataFormat)
.to("file:extract?fileName=TEST.csv");
[...]
编辑 1
我还尝试从 exchange.in 添加标题。它们在 HashSet 中的名称为“CamelJdbcColumnNames”。我像这样将它添加到 csvDataFormat 中:
final CsvDataFormat csvDataFormat = new CsvDataFormat();
csvDataFormat.setHeaderDisabled(false);
[...]
from("direct:TEST").routeId("TEST")
.setBody(constant("SELECT * FROM MYTABLE"))
.to("jdbc:myDataSource?readSize=100") // max 100 records
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
headerNames = (HashSet)exchange.getIn().getHeader("CamelJdbcColumnNames");
System.out.println("#### Process headernames = " + new ArrayList<String>(headerNames).toString());
csvDataFormat.setHeader(new ArrayList<String>(headerNames));
}
})
.marshal(csvDataFormat)//.tracing()
.to("file:extract?fileName=TEST.csv");
println() 打印列名,但生成的 cvs 文件不打印。
EDIT2 我按照评论 1 中的建议将标题名称添加到正文中,如下所示:
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
Set<String> headerNames = (HashSet)exchange.getIn().getHeader("CamelJdbcColumnNames");
Map<String, String> nameMap = new LinkedHashMap<String, String>();
for (String name: headerNames){
nameMap.put(name, name);
}
List<Map> listWithHeaders = new ArrayList<Map>();
listWithHeaders.add(nameMap);
List<Map> records = exchange.getIn().getBody(List.class);
listWithHeaders.addAll(records);
exchange.getIn().setBody(listWithHeaders, List.class);
System.out.println("#### Process headernames = " + new ArrayList<String>(headerNames).toString());
csvDataFormat.setHeader(new ArrayList<String>(headerNames));
}
})
该提案解决了问题并感谢您,但这意味着 CsvDataFormat 并不是真正可用的。 JDBC 查询之后的交换主体包含来自 HashMaps 的 ArrayList,其中包含表的一条记录。 HashMap 的键是列名,值是值。因此,在 CsvDataFormat 中设置标头输出的配置值应该足以生成标头。您知道更简单的解决方案还是我错过了配置中的某些内容?
【问题讨论】:
标签: csv apache-camel