3

どういうわけかVelocityExcelテンプレートを開いて、その場で部分的に大量のデータをストリーミングできる場合は、誰かに知らせてもらえますか?

データを含む外部リソースArrayListsからループで読み取りたいとしましょう。反復ごとに10000アイテムの1つのリスト。簡単なイテレーションでは、リストをVelocity Excelテンプレートにプッシュし、次のイテレーションにジャンプしてそれを忘れたいと思います。データ処理の最後に、Velocityコンテキストとテンプレートをすべてのデータと最終的にマージします。

これまで、いくつかの簡単な手順でVelocityエンジンによってExcelレポートを生成する方法を見てきました。

  • Velocityテンプレートを作成する
  • Velocityコンテキストを作成する
  • データをコンテキストに置く
  • コンテキストとテンプレートをマージする

しかし、私は3番目のステップを数回繰り返す必要があります。

4

2 に答える 2

4

これが私の場合にうまく機能する私のテスト済みソリューションです。データベースから直接ロードされた大量のデータをExcelシートに生成することができます。

Connection conn = getDs().getConnection();
// such a configuration of prepared statement is mandatory for large amount of data
PreparedStatement ps = conn.prepareStatement(MY_QUERY, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);

// load huge amount of data per 50000 items
ps.setFetchSize(50000);
ResultSet rs = ps.executeQuery();

// calculate count of returned data earlier
final CountWrapper countWrapper = new CountWrapper(countCalculatedEarlier);
CustomResultSetIterator<MyObject> rowsIter = new CustomResultSetIterator<MyObject>(rs, new org.apache.commons.dbutils.BasicRowProcessor(), MyObject.class) {

    private Long iterCount = 0L;

    @Override
    public boolean hasNext() {
        // you can't call isLast method on defined as forward only cursor of result set, hence there is a homegrown calculation whether last item is reached or not
        return iterCount < countWrapper.getCount().longValue();
    };

    @Override
    public MyObject next() {
        iterCount++;
        return super.next();
    };
};

VelocityContext context = new VelocityContext();
// place an interator here instead of collection object
context.put("rows", rowsIter);

Template t = ve.getTemplate(template);
File file = new File(parthToFile);
FileWriter fw = new FileWriter(file);
// generate on the fly in my case 1 000 000 rows in Excel, watch out such an Excel may have 1GB size
t.merge(context, fw);

// The CustomResultSetIterator is a:

public class CustomResultSetIterator<E> implements Iterator<E> {
  //...implement all interface's methods
}
于 2012-09-10T08:15:56.827 に答える
2

デフォルトのVelocityで私が見る唯一のオプションは、「ストリーミングコレクション」のようなものを実装することです。これは、完全なデータをメモリに保持することはなく、イテレータにデータを1つずつ提供します。

次に、このコレクションをVelocityコンテキストに配置し、Velocityテンプレートで使用してアイテムを反復処理します。内部的には、コレクションはhasNext()/ next()呼び出しのアイテムを外部ソースから次々に取得します。

于 2012-08-27T21:25:47.750 に答える