我们要求将大型CSV拆分为较小的多个CSV文件。 第一行主CSV文件包含我在所有生成的CSV文件中需要的列标题。
如何实现它?
我可以使用Apache Camel Splitter路由分割文件,如下所示......
<split id="LineItemSplitter" streaming="true"
parallelProcessing="true" timeout="0">
<tokenize token="\n" group="5000" />
<to id="LineItemOutbox"
uri="file:/target?fileName=${file:name.noext}-${date:now:yyyyMMddHHmmssSSSSS}.csv?fileExist=Append" />
</split>
</route>
答案 0 :(得分:1)
一种可能的方法是使用聚合器模式并在策略类中添加列标题。
例如见下文:
<aggregate strategyRef="messageAggregatorStrategy">
<correlationExpression>
<constant>true</constant>
</correlationExpression>
<completionTimeout>
<simple>10000</simple>
</completionTimeout>
<completionSize>
<simple>500</simple>
</completionSize>
<to id="LineItemOutbox"
uri="file:/target?fileName=${file:name.noext}-${date:now:yyyyMMddHHmmssSSSSS}.csv?fileExist=Append" />
</aggregate>
然后你的策略bean:
<bean id="messageAggregatorStrategy" class="com.youorg.MessageAggregator" />
然后在您的策略中,您可以设置列标题:
public class MessageAggregator implements AggregationStrategy
{
private static final Logger logger = Logger.getLogger(MessageAggregator.class);
private String COLUMN_HEADERS = "a,b,c";
@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange)
{
Exchange exchangeToReturn;
StringBuffer csvBuffer;
String csv = newExchange.getIn().getBody(String.class);
if (oldExchange == null)
{
csvBuffer = new StringBuffer();
csvBuffer.append(COLUMN_HEADERS).append("\r\n");
csvBuffer.append(csv);
newExchange.getIn().setBody(csvBuffer);
exchangeToReturn = newExchange;
}
else
{
csvBuffer = (StringBuffer) oldExchange.getIn().getBody(StringBuffer.class);
// update the existing message with the added body
csvBuffer.append("\r\n");
csvBuffer.append(csv);
oldExchange.getIn().setBody(csvBuffer);
// and return it
exchangeToReturn = oldExchange;
}
return exchangeToReturn;
}
这种方法的缺点可能是性能,因为你重新聚合而不是直接写入目标文件,但它确实实现了你想要的。
希望有所帮助。