apache camel split csv文件

时间:2015-01-07 14:49:59

标签: apache apache-camel

我们要求将大型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>

1 个答案:

答案 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;
    }

这种方法的缺点可能是性能,因为你重新聚合而不是直接写入目标文件,但它确实实现了你想要的。

希望有所帮助。