集算报表继承了润乾报表的宏机制来处理动态报表,对于简单的动态报表使用宏实现很方便。对于一些复杂的动态报表,集算报表还提供了脚本数据集来处理动态报表,适合宏无法实现的场景,而润乾报表中要实现复杂动态报表时则须要编写自己定义数据集来完毕。以下通过几个样例来具体比較一下集算报表和润乾报表在处理动态报表时的同样与不同点。

同样点

        集算报表和润乾报表都提供了宏,使用方式差点儿全然一致,且都包括普通宏和动态宏。

        普通宏经常使用于静态内容替换。如在员工表中同一时候仅仅希望查看薪金或奖金。开发两张报表显然是繁冗的,使用普通宏在一张报表来完毕非常easy,例如以下报表:

集算报表与润乾报表处理动态报表时的异同_字段

        预览报表输入參数和宏:

集算报表与润乾报表处理动态报表时的异同_集算报表_02

        当參数arg1值为BONUS。宏macro值为BONUS时,可得到例如以下报表结果:

集算报表与润乾报表处理动态报表时的异同_字段_03

        当參数arg1值为SALARY。宏macro值为SALARY时,可得到例如以下报表结果:

集算报表与润乾报表处理动态报表时的异同_sql_04

        相对普通宏仅仅能替换静态内容,动态宏则能够编写动态表达式。完毕动态内容的替换,从而完毕动态报表制作。比方这种动态报表,针对指定表依据用户选择的字段和条件进行查询,报表中显示选择的字段及其数据。因为字段和条件都是动态的,所以须要先在报表中将SQL拼好再交由数据库进行查询,这时就须要在动态宏中进行拼接。

例如以下报表:

集算报表与润乾报表处理动态报表时的异同_动态报表_05

        当中报表參数和宏设置为:

集算报表与润乾报表处理动态报表时的异同_数据集_06

        输入cols值:订单ID,客户ID,订购日期,发货日期,到货日期,运货费

        输入where值:where 货主地区='华北' and 货主城市 in ('北京','天津','张家口','秦皇岛')

集算报表与润乾报表处理动态报表时的异同_集算报表_07

        其值为:"select"+cols+" from 订单"+where,宏类型为动态宏。

        设置数据集SQL为:${sql}。预览报表能够得到例如以下动态报表结果:

集算报表与润乾报表处理动态报表时的异同_数据集_08

        以上为使用宏(普通宏和动态宏)开发相对简单(仅仅静态内容或通过简单的表达式完毕)的动态报表,而对于复杂的动态报表。往往须要经过复杂计算才干完毕。而这类复杂情况使用宏往往非常难甚至无法完毕,这时集算报表和润乾报表处理的方式则有非常大不同。

不同点

        集算报表提供了脚本数据集的方式能够完毕上述提到的复杂动态报表的开发,因为脚本内置且语法简单。非常easy处理这类报表。

而润乾报表仅仅能通过自己定义数据源在JAVA中完毕,使用的简易性则略逊一筹。以下还是通过样例来看一下。

        由用户针对特定表指定选择列和条件,如用户在订单表中选择列时。订单ID、雇员ID和订购日期是必选列。即使用户没有选择,在查询后仍然显示。

这就须要在拼接SQL的时候事先推断必选列是否在用户的选出列中,假设不在。则在后面加入,同一时候要保证用户选出列的次序。

        通过宏实现的难点在于。因为须要推断每一个必选列是否在用户选择字段的列表中,假设没有则附加。有多少个必选列就要比較几次,在必选列较多的时候很复杂。

        以下是集算报表通过脚本数据集的实现(报表參数与表达式与上例一致):

集算报表与润乾报表处理动态报表时的异同_数据集_09

        上述脚本在A2中将所选字段集合与必选字段集合做并集即获得了全部查询字段,拼接SQL进行查询后为报表返回结果集。过程非常easy。

 

        而润乾报表在这样的情况一般要採用自己定义数据集了,以下是润乾报表通过自己定义数据集的实现(主要代码):

<span style="font-size:14px;">public class QueryData implements IDataSetFactory {
	public DataSet createDataSet(Context ctx, DataSetConfig dsc, boolean isinput) {
		Map map = ctx.getParamMap(false); // 获得当前报表的全部參数对比表
		String cols = "";
		String where = "";
		if (map != null) {
			Iterator it = map.entrySet().iterator();
			cols = map.get("cols").toString(); // 获取參数值
			where = map.get("where").toString(); // 获取參数值
		}

		DataSet ds1 = new DataSet("ds1");
		Connection con = null;
		try {
			con = ctx.getConnectionFactory("demo").getConnection();				Statement stmt = con.createStatement();
			String sql = "select " + cols + " from 订单 " + where;
			ResultSet rs = stmt.executeQuery(sql);
			ResultSetMetaData rsmd = rs.getMetaData();
			int colCount = rsmd.getColumnCount();
			//设置列名
			for (int i = 1; i <= colCount; i++) {
				ds1.addCol(rsmd.getColumnName(i));
			}

			//设置数据集数据
			if (rs != null) {
				while (rs.next()) {
					Row rr = ds1.addRow();
					for (int i = 1; i <= colCount; i++) {
						rr.setData(i, rs.getObject(i));
					}
				}
			}
			rs.close();
			stmt.close();
			con.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return ds1;
	}
}
</span>

       上述自己定义数据集首先获取了报表參数和当前数据源连接。其次依据參数拼接出要运行SQL,而后依据获得的ResultSet为数据集分别设置列名和数据,最后返回创建的数据集。在使用时,将编译后的class(QueryData.class)放到应用的classpath中方才完毕。

 

       通过以上实现过程能够看到,对于复杂的动态报表(如上例),使用脚本数据集实现更为简单,除了其拥有简洁的语法,脚本数据集内置在报表中无需其它程序文件附加,则更为便捷。