在利用birt报表制作table表格时,我们经常会遇到所要制作的表格列数不固定的情况,比如第一列是科目名,后面的列是各个学生的情况(当然实际中一般都是第一列为学生,后面每列是科目,这里只是举个例子),而birt的视图界面在建立table表时,会要求我们输入列数,这样就无法满足我们的需求了(如下图所示):
JS脚本方式动态添加table列
大致思路与第3篇动态添加chart折线图表折线数一样,都是采用存储过程数据集+JS脚本+Java函数实现的。
首先建立一个含有1列的table
添加个名字,之后JS脚本中会用来锁定该table
然后点击next,绑定数据集
这里的数据集我是调用存储过程来创建的,当然也可以直接用SQL语句查。大致数据集查出来的结果如下,每一列代表一个学生,最后面还有一列是课程名,这里需要给学生排序,方便后面与调用Java函数所得的学生名字顺序对应(这里讲下,其实这里的只是伪动态增加,因为在绑定数据集时,birt就已经固定了数据集所查出的列数,比如第一次查有20个学生,第二次查有30个学生,那么birt只会认为数据集只有20个学生的列,由此会导致数据缺失,所以这里采用了一个伪动态做法,就是事先规定了学生列的最大数,比如学生总数不大于50,那就设置一共会查出50列学生,实际查出20个学生的话,就用SQL补上30列的空白列,这样birt就不会出现数据集数据丢失的问题了,所以下图中会有一大堆的0值列):
运行看下效果,大致如下,现在只有一列科目列
然后我们需要编写一个Java函数来获取到底有几个学生(因为birt一个图表一般还能绑定一个数据集,所以用调用Java函数的方式来获取其他的数据),用来确定table实际需要增加几列。这里我采用的是MyBatis来查询数据,整个web项目的框架是spring MVC + MyBatis + Birt,框架的整合在上几篇中也有详细讲过,这里不再赘述。实际的文件内容与第3篇chart动态添加折线中的一样,可以参考那一片中的,简单来讲就是getAllDept.java中有一个方法A,获取Birt传过来的参数,并用这些参数结合MyBatis来查询所有学生的名字,组装成数组,返给Birt,然后Birt根据学生名字数组来绑定数据集中的1,2,3….学生成绩列,并将列名改为实际的学生名(1,2,3…改为名字)。
上面所讲的Birt调用Java函数,并传参,然后接收返回数组,利用返回数组新建table列,并绑定数据集列,修改显示列名的操作都会放在JS脚本中。
首先鼠标左键报表灰色的部分,然后点击,下方的Script按钮,选择上方Script:下拉框的beforeFactory,说明都放在注释里了。
importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
importPackage(Packages.org.eclipse.birt.chart.model.component.impl);
importPackage(Packages.org.eclipse.birt.chart.model.type.impl);
importPackage(Packages.org.eclipse.birt.chart.model.attribute);
importPackage(Packages.org.eclipse.birt.chart.model.attribute.impl);
//这就是上图中调用的Java函数所在的包名
importPackage(Packages.com.springMVC.controller);
//调用Java函数并传参,并接收返回数据
var deptStr=getAllDept.getAllDeptById(params["projectId"].value,params["userId"].value,params["level"].value,params["sDept"].value,params["sLevel"].value,params["sPost"].value).split("#");
//deptTitleTable
elementFactory = reportContext.getDesignHandle().getElementFactory();
//获取新建的table名
mytable = reportContext.getDesignHandle().findElement("deptTable");
myheader = mytable.getHeader().get(0);//获得表格头
mydetail = mytable.getDetail().get(0);//获得明细行
var mycolumn
var colorArr="red,orange,green"//测试用的,可以无视
var colors = colorArr.split(","); //测试用的,可以无视
for(var i=0;i<deptStr.length;i++){
mytable.insertColumn(i+1,1);//循环插入新列,每次加在最后一列的后面
mycolumn = mytable.getColumns().get(i+1);
mycolumn.setProperty("width", "3cm");
mycolumn.setProperty("backgroundColor", "white"); //背景色
mycolumn.setProperty("color", "black"); //字体颜色
dcell = mydetail.getCells().get(i+1);//取得明细行单元格
//设置样式
dcell.setProperty("borderBottomColor","#000000");
dcell.setProperty("borderBottomStyle","solid");
dcell.setProperty("borderBottomWidth","1px");
dcell.setProperty("borderLeftColor","#000000");
dcell.setProperty("borderLeftStyle","solid");
dcell.setProperty("borderLeftWidth","1px");
dcell.setProperty("borderRightColor","#000000");
dcell.setProperty("borderRightStyle","solid");
dcell.setProperty("borderRightWidth","1px");
dcell.setProperty("borderTopColor","#000000");
dcell.setProperty("borderTopStyle","solid");
dcell.setProperty("borderTopWidth","1px");
myDataItem2 = elementFactory.newDataItem("deptTitle"); //上面建立的数据集名称
myDataItem2.setResultSetColumn(i+1); //数据集中所想要展示在该table列中的列名(即1,2,3...)
dcell.getContent().add(myDataItem2);
hcell = myheader.getCells( ).get(i+1);
//设置样式
hcell.setProperty("borderBottomColor","#000000");
hcell.setProperty("borderBottomStyle","solid");
hcell.setProperty("borderBottomWidth","1px");
hcell.setProperty("borderLeftColor","#000000");
hcell.setProperty("borderLeftStyle","solid");
hcell.setProperty("borderLeftWidth","1px");
hcell.setProperty("borderRightColor","#000000");
hcell.setProperty("borderRightStyle","solid");
hcell.setProperty("borderRightWidth","1px");
hcell.setProperty("borderTopColor","#000000");
hcell.setProperty("borderTopStyle","solid");
hcell.setProperty("borderTopWidth","1px");
myLabel = elementFactory.newLabel(i+1);
myLabel.setText(deptStr[i]); //用Java返回的学生名数组来替换1,2,3 的显示
hcell.getContent().add(myLabel);
}
完成以后运行测试下
搞定,然后格式CSS什么的就按照需要进行调整吧,可以对照Birt提供的API手册进行修改。位置在eclipse->help->help contents