带页合计的固定行数分页分组报表
需求说明:
润乾报表提供了多种灵活的报表分页方式,如按纸分页,按行分页等,另外还可以行后分页可支持表达式,让报表分页更加灵活和便于控制。
客户要求实现的报表要求如下:
1. 报表需要按固定行(7行)分页,每页底部添加页合计。
2.报表为分组报表,按”产品类别”分组,每组后需要添加组合计。
实现难点:
1. 不能通过设置”按行分页”实现,该方式不能根据分页在每页下方生成”页合计”。
2. 不能确定数据集中记录的序号,故难以判断何时进行分页,何时生成”页合计”。
问题解决及需求实现:
1. 给数据集中的记录添加序号,这样可以根据添加的序号进行分页分组。
2. 通过”行后分页”的方式实现分页,在 “页合计”行设置行后分页。
具体实现如下:
1. 用自定义数据集方式为原有的数据集结果添加序号列
原来数据集ds1:SELECT 产品.产品ID,产品.产品名称,产品.单价,产品.库存量,产品.类别ID FROM 产品 WHERE 产品.类别ID is not null ORDER BY 产品.类别ID ASC,产品.产品ID ASC。
得到的结果如下:
用自定义数据集构建数据集ds2,读取ds1的结果,并为其添加序号列。
生成的数据集结果如下:
自定义数据集类MyDataSet部分实现代码如下:
public class MyDataSet implements IDataSetFactory{
public DataSet createDataSet(Context ctx, DataSetConfig dsc, boolean retrieve){
……
//读取同一报表中已算出的数据集
DataSet ds1 = ctx.getDataSet(“ds1″);
//构造一个数据集
DataSet ds2 = new DataSet(“ds2″);
ds2.addCol(“seq”);//添加序号列
//添加ds1中的列名值ds2
for(int j=1;j<=ds1.getColCount();j++){
ds2.addCol(ds1.getColName(j));
}
//根据ds1的行数添加行至ds2,并按递增顺序添加序号
for( int i = 0; i < ds1.getRowCount(); i++ ) {
Row row = ds2.addRow();
row.setData(1, new Integer(i));
for(int k=1;k<=ds1.getColCount();k++){
row.setData(k+1, ds1.getData(i+1, k));
}
}
return ds2;
}
}
注意:对查询结果增加序号列的操作也可以通过在数据集sql中实现,但是不同的数据库类型实现的方式有所不同,比如oracle就可以借助rownum来增加序号列。
2. 报表模板设计:
A1:=ds2.Group(类别ID,false), 针对类别进行分组。
B1:=ds2.count(),统计该类别的记录条数,该单元格不可视。
C1:=B1+C1[-1],统计累计记录条数,该单元格不可视。
第一行的行类型为分组表头,组头级别为1.
第二行的行类型也为分组表头,组头级别为2.该行单元格的左主格为A1。
A3:=ds2.Group(int((seq-C1[-1])/5),false),首先seq-C1[-1]可以得到组内序号,其中C1[-1]是上一个类别分组中累计的记录数。ds2.Group(int((seq-C1[-1])/5),false)根据组内序号除以5的取整结果进行当前(类别)组内的页分组。
B3: =ds2.Select(产品ID),产品列表。
E3:=ds2.count(),左主格为A3。统计每个分页分组里面的记录数
A4:页合计,设置行后分页表达式:if(E3<5,false,true),如果当前的组的记录数小于5的话就不分页,否则行后分页。也就是当每个类别分组的最后一个页分组的记录数不足5的话在下方显示组合计。
实现效果:
每页重复打印分组表头,每页添加页合计,每组添加组合计。