【问题标题】:Stream data to velocity template on the fly即时将数据流式传输到速度模板
【发布时间】:2023-03-06 21:41:01
【问题描述】:

有人可以告诉我,是否可以以某种方式打开 Velocity Excel 模板并在运行中向其中部分传输大量数据?

假设我想从外部资源 ArrayLists 中循环读取数据。每次迭代包含 10 000 个项目的列表。在简单的迭代中,我想将列表推送到 Velocity Excel 模板并通过跳转到下一个迭代来忘记它。在数据处理结束时,我会将 Velocity 上下文和模板与所有数据进行最终合并。

到目前为止,我已经看到了通过 Velocity 引擎通过几个简单步骤生成 Excel 报告的方法:

  • 创建 Velocity 模板
  • 创建 Velocity 上下文
  • 将数据放到上下文中
  • 合并上下文和模板

但我需要多次重复第 3 步。

【问题讨论】:

    标签: java velocity


    【解决方案1】:

    这是我经过测试的解决方案,在我的情况下效果很好。我能够直接从数据库加载大量数据到 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
    }
    

    【讨论】:

      【解决方案2】:

      我看到的默认 Velocity 的唯一选择是实现类似“流式集合”的东西,它永远不会在内存中保存完整的数据,而是在迭代器中一一提供数据。

      然后,您可以将此 Collection 放入 Velocity 上下文中,并在 Velocity 模板中使用它来迭代项目。在内部,Collection 会从您的外部源一个接一个地检索 hasNext()/next() 调用中的项目。

      【讨论】:

        猜你喜欢
        • 2018-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-13
        • 1970-01-01
        • 2020-05-06
        • 1970-01-01
        相关资源
        最近更新 更多