JavaScript概述
JavaScript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用的复杂软件。它是一种基于对象(Object Based)和事件驱动(Event Driver)的编程语言。 JavaScript是动态的,它可以直接对用户或客户输入做出响应,无须经过Web服务程序。它对用户的反映响应,是采用以事件驱动的方式进行的。所谓事件驱动,就是指在主页(Home Page)中执行了某种操作所产生的动作,就称为“事件”(Event)。比如按下鼠标、移动窗口、选择菜单等都可以视为事件。当事件发生后,可能会引起相应的事件响应。
JavaScript是依赖于浏览器本身,与操作环境无关,只要能运行浏览器的计算机,并支持JavaScript的浏览器就可正确执行。即JavaScript源代码在发往客户端执行之前不需经过编译,而是将文本格式的字符代码发送给客户编由浏览器直接解释执行。
本章介绍了FineReport内置的JavaScript函数及其用法。
触发事件
控件的事件
在控件设置的事件编辑中,事件编辑共有七种触发事件:编辑前、编辑后、编辑结束、点击、初始化后、状态改变及回调。
其中编辑前、编辑结束只在表单填报时起作用。
编辑后、点击、初始化后、状态改变等在表单填报及参数界面上都可以使用。
1. 编辑前
该事件是在填报时进入编辑状态后被触发
简单例子
1.1 新建一张空白报表,然后设计成如下格式
 1.2 设置报表填报属性,在此不做赘述,具体设置方法可参考填报专题相关章节
1.3 定义单元格填报属性
将B2单元格控件类型设置为文本,并在B2控件中添加编辑前事件,在function fun()函数中添加一段JS代码: alert("事件编辑前触发");
如下图所示
 1.4 保存并填报
点击设计器中的填报预览,进入填报的编辑状态,效果如下
 此时当光标移至姓名单元格进行编辑时,编辑前事件被触发。
2. 编辑后
该事件在表单填报及参数界面上都可以被触发。
对于文本、数字控件,当输入任何字母或文字标点后触发;对于下拉框,复选框等控件,当选择下拉选项后被触发,具体设置方法类似于编辑前事件,在这不再赘述。
3. 编辑结束
该事件只有在填报确认单元格输入内容如键盘输入回车后才能被触发
具体设置方法类似于编辑前事件,在这不再赘述。
4. 点击
该事件是在点击按钮,或点击下拉框、下拉树、下拉复选框等之后被触发
简单例子
4.1 新建报表
4.2 使用默认的参数界面,如图
 4.3 控件设置
右击按钮控件,选择控件设置,打开控件设置面板,添加点击事件,在function fun()函数中添加一段JS代码: alert("点击我就触发该事件啦!");
如下图所示
 4.4 保存并预览
点击设计器中的分页预览,点击查询按钮,此时点击事件被触发,如下图
 5. 初始化后
该事件是按钮控件所特有,在点击分页预览或填报预览后初始化界面时被触发
简单例子
5.1 新建报表
5.3 控件设置
右击按钮控件,选择控件设置,打开控件设置面板,添加初始化后事件,在function fun()函数中添加一段JS代码: alert("初始化后就触发该事件啦!");
如下图所示
 5.4 保存并预览
点击设计器中的分页预览,就可以看见如下图所示效果
 6. 状态改变
该事件为单选按钮、复选框组控件所特有,在其状态改变时被触发
简单例子
6.1 定义报表参数p1,并设置其默认值为男
6.2 在参数界面上,定义参数p1的控件属性,如下图
 6.3 添加事件
右击p1的控件,选择控件设置,打开控件设置面板,添加状态改变事件,在function fun()函数中添加一段JS代码: alert("单选按钮的状态改变啦!");
如下图所示
 6.4 保存并预览
点击设计器中的分页预览,单选按钮默认选中“男”,当点击“女”时就会触发状态改变事件,如下图
 7. 回调
该事件为文件控件所特有,是在上传完文件之后触发该事件
简单例子
7.1 新建报表,定义文件控件,如下图:
 7.2 添加事件
点击文件控件,打开控件设置面板,添加回调事件,在function fun()函数中添加一段JS代码: alert("回调事件触发啦!");
如下图所示
 7.3 保存并预览
点击设计器中的填报预览,上传文件结束后,触发回调事件,如下图
 其他事件
除了各控件中可以添加事件外,超级链接也可以引用JavaScript,具体使用方法将在之后的章节中详述。同时在报表|报表Web属性及服务器|服务器配置中也可以添加各种JS事件,如下图所示
 
超链接引用JavaScript
该例子实现用户在点击超级链接的时候,根据输入的页码,来决定链接到指定的页面。
有两种引用方式:
1. 将写好的方法保存为js文件,放置在工程下,在超级链接中直接调用
1.1 新建报表
1.2 模板设计
在B3单元格中写入公式:=range(1,40),并将其扩张属性改为“从左到右扩展”,并将其设为居中,如下图所示:
 1.3 添加超链接
l 右击B3单元格,选择超级链接,进入超级链接界面,点击添加JavaScript,如下图所示
 l 写一段Js代码,内容为:
function demo() {
var test = function() {
var num = parseInt(arguments[0]);
contentPane.gotoPage(num);
};
var value = FR.Msg.prompt("输入", "页码", 2, test);
}
说明:
var num = parseInt(arguments[0]); //获得输入框中输入的页码
contentPane.gotoPage(num); //跳转到相应页码
var value = FR.Msg.prompt("输入", "页码", 2, test); //参数分别为对话框标题、对话框内容、输入框默认值、回调函数
将此段内容保存为test.js文件 ,放在WebReport目录下,在超级链接界面中插入该test.js,并在下面的function fun()函数中调用demo();
效果如下图所示:
 1.4 保存并预览
点击超级链接,出现如下图所示的输入提示对话框
 在输入对话框中输入需要跳转的页数,并点击确定按钮,就跳转到相应的页面。
2. 直接在超级链接界面上写js方法
2.1 新建报表
2.2 模板设计
在B3单元格中写入公式:=range(1,40),并将其扩张属性改为“从左到右扩展”,并将其设为居中,如下图所示:
 2.3 添加超链接
l 右击B3单元格,选择超级链接,进入超级链接界面,点击添加JavaScript,如下图所示
 l function fun(){}函数中写入如下JS语句:
function test(){
var num = parseInt(arguments[0]);
_g('${sessionID}').gotoPage(num);
};
var value = FR.Msg.prompt("输入", "页码", 2,test);
说明:
_g('${sessionID}').gotoPage(num); //跳转到相应页码
如下图所示
2.4保存预览
点击超级链接,出现如下图所示的输入提示对话框
在输入对话框中输入需要跳转的页数,并点击确定按钮,就会跳转到相应的页面。
参数控件触发事件
参数控件的取值与置数
参数界面中,最常见的就是获取参数的值进行运算或者将其作为另一个参数的判断依据,在FineReport报表网页脚本中,也提供了获取参数控件实际值,显示值并给参数置数的方法。
//取当前控件的实际值
var [ParaValue] = this.getValue();
//通过参数控件名称来获取参数控件实际值
var [ParaValue] = this.options.form.getWidgetByName("[ParaName]").getValue();
//通过arguments[i]获取当前参数控件显示值
var [DisplayedValue] = arguments[0];
//通过控件A获取控件B的显示值
var [DisplayedValue] = this.options.form.getWidgetByName("[ParaName]").options.items[0].text;
//获取某个参数控件,并给其置数(实际值)
var [Para] = this.options.form.getWidgetByName("[ParaName]");
[Para].setValue([Value]);
实例:
该实例通过添加参数控件的编辑后事件来实现用一个参数控制另一个参数,如用参数username来对state置数,username为下拉框自定义的几个用户名,state为单选按钮组表示状态1和2。当username有值时,state的状态置为1否则置为2。
1. 模板设计
1.1 新建报表
1.2 定义参数
在菜单栏中选择报表|报表参数,打开参数定义面板,定义参数state和username,如下图
1.3 参数设计
打开参数设计界面,参数控件布局如下
l username控件类型为下拉框,数据自定义,如图
l state控件类型选择单选按钮组,数据也为自定义,如图
1.4 添加事件
在username的事件编辑中添加编辑后事件,JS代码如下
var state= this.options.form.getWidgetByName("state");
var username = this.options.form.getWidgetByName("username").getValue();
if (!username){
state.setValue(2);
}else{
state.setValue(1);
}
该段代码是用来对state参数置数,当username为空时,!username为真,此时将state置数为2,否则当username有值时,将state置数为1,如图所示
2. 保存并预览
点击设计器分页预览,当username有值是,state置为1
当username为空时,state置为2
注意:state无法通过username置数为0,JS里面,state为0,默认返回false
且一个控件无法对另一个控件的显示值进行置数
参数校验-日期校验
内置参数查询界面当中可进行一些数据校验,例如有两个参数:开始时间和结束时间,结束时间必须在开始时间之后,否则进行提示。
1. 在提交按钮的事件编辑中写JS代码
1.1 新建报表
1.2 模板设计
按照下图设计模板
1.3 添加数据源
新建一个名为ds1的数据库查询,SQL语句:SELECT * FROM EMPLOYEE
1.4 绑定数据列
按照下表进行数据列绑定
单元格
|
数据集
|
数据列
|
属性
|
B5
|
ds1
|
EMPID
|
上到下扩展,居中,其余默认
|
C5
|
ds1
|
EMPNAME
|
上到下扩展,居中,其余默认
|
D5
|
ds1
|
SEX
|
上到下扩展,居中,其余默认
|
E5
|
ds1
|
BIRTHDATE
|
上到下扩展,居中,其余默认
|
F5
|
ds1
|
ORIGN
|
上到下扩展,居中,其余默认
|
G5
|
ds1
|
SCHOOL
|
上到下扩展,居中,其余默认
|
H5
|
ds1
|
TEL
|
上到下扩展,居中,其余默认
|
双击B5单元格,在过滤页面当中,定义条件类型为单元格,添加条件: BIRTHDATE 大于或等于 $begintime AND BIRTHDATE 小于 $endtime
1.5 定义参数
打开菜单栏中报表|报表参数,新定义两个个名为begintime,endtime的参数,如图
1.6 参数设计
l 打开参数设计界面,参数界面布局如下
l 日期控件设置
右击begintime的控件,选择控件设置,控件类型选择日期,控件名选择begintime,具体设置如下图所示
endtime的控件同上
1.7 数据校验
右击查询按钮,选择控件设置,打开控件设置面板,添加点击事件,如下图所示
在function fun(){}函数中写入如下JS语句:
var start = this.options.form.getWidgetByName("begintime").getValue();
var end = this.options.form.getWidgetByName("endtime").getValue();
if( start == ""){
alert("错误,开始时间不能为空");
return false;
};
if(end == ""){
alert("错误,结束时间不能为空");
return false;
};
if( start > end){
alert("错误,开始时间不能大于结束时间");
return false;
}
1.8 保存并预览
begintime输入为空,如下图所示
endtime输入为空,如下图所示
输入的endtime在begintime之前,校验如下图所示:
2. 在参数控件的事件编辑中写JS代码
2.1 设计模板
具体操作同上。
2.2 数据校验
l 右击begintime的控件,选择控件设置,添加编辑后事件,如下图所示:
在function fun(){}函数中写入如下JS语句:
var start = this.options.form.getWidgetByName("begintime").getValue();
if( start == ""){
alert("错误,开始时间不能为空");
return false;
};
说明:这段代码是为了验证begintime输入不能为空。
l 右击endtime的控件,选择控件设置,添加编辑后事件,如下图所示
在function fun(){}函数中写入如下Js语句:
var end = this.options.form.getWidgetByName("endtime").getValue();
if(end == ""){
alert("错误,结束时间不能为空");
return false;
};
if( start > end){
alert("错误,开始时间不能大于结束时间");
return false;
}
说明:这段代码是为了校验endtime输入不能为空以及结束时间大于开始时间。
2.3 保存并预览
效果与在提交按钮的事件编辑中写JS代码一样
参数控件动态显示
由于业务的需要,很多情况下需要当满足某个条件时,某些查询条件才显示出来,此时参数控件就需要动态的控制其是否可见。
//通过控件的visible()、invisible()属性控制其可视、不可视
var [Widget] = form.getWidgetByName("[ParaName]"); //通过控件名获取控件
[Widget].visible(); //设置该控件可见
[Widget].invisible(); //设置该控件不可见
实例:
该实例实现效果:当选择日报时,右侧出现一个日期查询控件,选择月报时,则让用户选择年月,例如2008年3月,选择年报时,即让用户选择年份。
1. 模板设计
1.1 新建报表
1.2 添加数据源
新建一个名为ds1的数据库查询,SQL语句:
SELECT equipment,amount,costs,updatetime,equipmentId
FROM EquipmentDetail
where 1=1
${if(type='日报'," and format(updatetime,'yyyy-mm-dd') = '" + date + "'","")}
${if(type='月报'," and month(updatetime) = "+ month + " and year(updatetime) = " + year,"")}
${if(type='年报'," and year(updatetime) = " + year,"")}
其中设置参数type的默认值日报,data的默认值是字符串2009-01-13
1.3 模板设计
模板样式如下
2.4 绑定数据列
按照下表进行数据列绑定
单元格
|
数据集
|
数据列
|
属性
|
C2
|
ds1
|
="财务报表( " + $type + ")"
|
不扩展,居中,其余默认
|
C4
|
ds1
|
=$type
|
不扩展,居中,其余默认
|
D4
|
ds1
|
=if(type=="日报",$date,if(type=="月报",$year+"."+$month,$year))
|
不扩展,居中,其余默认
|
C7
|
ds1
|
EquipmentID
|
上到下扩展,居中,其余默认
|
D7
|
ds1
|
Equipment
|
上到下扩展,居中,其余默认
|
E7
|
ds1
|
Amount
|
汇总求和,居中,其余默认
|
F7
|
ds1
|
costs
|
汇总求和,居中,其余默认
|
2.5 参数设计
2.5.1 打开参数设计界面,参数界面布局如下
2.5.2 控件设置
l type控件设置
右击type控件,选择控件设置,打开控件设置面板,控件类型为下拉框,控件名选择type,自定义数据,如下图所示
l date控件设置
右击date的控件,选择控件设置,打开控件设置面板,控件类型为日期,控件名选择date,自定义数据,如下图所示
l year控件设置
右击year的控件,选择控件设置,打开控件设置面板,控件类型为下拉框,控件名选择year,使用公式,dyear控件是由type的类型来决定他是否需要显示的,且我们默认的类型为日报,因此默认设置它为不可见,如下图所示
l month控件设置
右击month的控件,选择控件设置,打开控件设置面板,控件类型为下拉框,控件名选择month,自定义数据,并设为不可见,如下图所示
2. 事件编辑
右击type控件,选择控件设置,打开控件设置面板,添加编辑后事件,如下图所示:
在function fun(){}中添加如下代码:
var form = this.options.form;
var DateWidget = form.getWidgetByName("date");
var YearWidget = form.getWidgetByName("year");
var MonthWidget = form.getWidgetByName("month");
var value = this.getValue();
if(value == "日报"){
DateWidget.visible();
YearWidget.invisible();
MonthWidget.invisible();
}else if(value == "月报"){
DateWidget.invisible();
YearWidget.visible();
MonthWidget.visible();
}else if(value == "年报"){
DateWidget.invisible();
YearWidget.visible();
MonthWidget.invisible();
}else{
DateWidget.invisible();
YearWidget.invisible();
MonthWidget.invisible();
}
说明:此段代码的作用是选择日报,那么在其下方出现一个日期选择框;选择月报时,即让用户选择年月,例如2008年3月;年报与月报同理,即让用户选择年份。
3. 保存并预览
默认为日报,只显示出日期控件,预览效果如图
当选择月报时,右边弹出月份和年份下拉框,预览效果如图
当选择年报时,右边弹出年份下拉框,预览效果如图
表单填报触发事件
表单控件的取值与置数
在填报页面,也可以得到各控件的值及对控件进行置数,方法与参数界面中类似。
// 获得当前控件输入的值
var [Value] = this.getValue();
// 通过单元格名称获取其他单元格的值
var [curLGP] = arguments[1]; //首先,获得当前form对象
var [Cellvalue] = curLGP.getCellValue("[Cell]"); //通过单元格名称获得Cell单元格的值
// 对单元格进行置数并显示
var [curLGP] = arguments[1]; //首先,获得当前form对象
curLGP.setCellValue("[Cell]", null, [Value]); //给单元格Cell置数,改变其实际值,但不显示,字符串需要加上引号
curLGP.displayTDCell($("#[Cell]-0"), [Value]); //表示显示出Cell单元格的实际值Value
实例:
该实例实现了在填报页面上用一个表单控件控制另一个表单控件,当控件1输入之后,取控件2的值,判断一下条件,若不符合条件,则置数,符合则不变。
1. 设计模板
1.1 新建报表
1.2 模板设计,如图所示
1.3 设置控件属性
1.4 添加事件
在A2单元格控件的事件编辑中添加编辑结束事件,具体JS代码为:
var curLGP = arguments[1];
var C2value = curLGP.getCellValue("C2");
if(C2value != 10){
curLGP.setCellValue("C2", null, "10");
curLGP.displayTDCell($("#C2-0"), "10");
}
说明:
var curLGP = arguments[1]; //获得本form对象
var C1value = curLGP.getCellValue("C2"); //获得C2单元格的值
curLGP.setCellValue("C2", null, "10"); //给C2置数,改变其实际值,但不显示
curLGP.displayTDCell($("#C2-0"), "10"); //表示显示出C2的实际值
具体如图所示
2. 保存并预览
点击设计器中的填报预览,效果如图
在控件1中输入数据后回车,这时触发编辑结束事件,取C2单元格的值,根据判断,不是10,此时将C2单元格置数为10
及时校验-跨格数据校验
在实现填报时,有时需要在编辑完数据后跟其他具体某个格子对比,进行及时校验。当报表中提供的及时校验不能满足需求时,可以通过JS事件来进行及时校验。
1. 设计模板
2.1 新建报表
2.2 模板设计,如下图所示
2.3 控件设置
2.4 添加事件
l 对B2单元格控件添加编辑结束事件:
var D2value = arguments[1].getCellValue("D2");
if (this.getValue() < D2value){
FR.Msg.alert(FR.i18n.Alert, "该值不能小于" + D2value);
return false;
}
说明:D2value是自定义变量,用于获得D2单元格的值,if语句是用来判断该单元格输入后的值是否小于D2value,如果是则弹出警告:该值不能小于6。
l 对B3单元格控件添加编辑结束事件:
var D3value = arguments[1].getCellValue("D3");
if (this.getValue() != D3value){
FR.Msg.alert(FR.i18n.Alert, "该值应等于" + D3value);
return false;
}
说明:D3value是自定义变量,用于获得D3单元格的值,if语句是用来判断该单元格输入后的值是否等于D3value,如果不是是则弹出警告:该值应等于abc。
2. 保存并预览
点击填报预览,在B2单元格中输入数字5,并按回车确定,则弹出警告,如图
在B3单元格中输入add,并按回车确定,也弹出校验警告,如图
表单提交超级链接
在填报时,提交会出现两种结果,提交成功和提交失败,可以对这两种结果进行判断并作出反应,从而跳转到其他页面。原FineReport6.2中可以在报表填报属性中添加,如下图所示
在FineReport6.5中同样可以通过报表|报表Web属性|填报页面设置添加提交成功和提交失败事件进行编辑。主要用到的事件为加载页面事件:
// 通过页面路径加载相应页面
window.open("[URL]")
实例:
1. 打开模板
2. 添加提交事件
点击填报|报表Web属性,选择填报页面设置,进入填报页面设置窗口,在右边栏中添加提交成功和提交失败事件,如下图所示
具体的填报成功事件和填报失败事件代码如下
填报成功事件,添加JS代码:window.open("http://www.");
在填报成功后,连接到相应页面。
提交失败事件,JS代码:
window.open("http://localhost:8075/WebReport/ReportServer?op=fs");
该代码用于填报提交失败后打开产品演示文档。
填报页面居中
在填报时,填报预览默认填报页面是靠左的。但实际应用可能需要居中显示,FineReport报表可以通过在浏览器加载报表的时候引用一个页面样式来控制页面居中方式。
具体实现过程如下:
1. 添加加载结束事件
打开任意一张填报表,点击菜单栏报表|报表Web属性,选择填报页面设置,进入填报页面设置窗口,在右侧添加一个加载结束事件,如下图
具体的加载结束事件代码如图
JS代码如下:
var slmargin = ($('.content-container').width() - $('.sheet-container').width()) / 2;
$('.sheet-container').css('margin-left',slmargin);
说明:表示自定义一个变量slmargin,表示页面的居中位置,后面一句代码调用css表示页面加载时居中设置。
2. 保存并预览
点击设计器填报预览,页面居中设置 ,如图
自定义填报
在填报时,个别用户为了需求,需要自定义填报。FR报表在报表web属性中的填报页面设置中可以自定义填报功能。
实例:
该实例实现首先在工具栏上加一个按钮,通知服务器要做填报;然后服务器获得当前的SessionIDInfor,取出当前的报表,获得报表中A1、B1扩展后的格子,再把这组数据insert到数据库中;最后返回客户端一个讯息,表示填报成功了,客户端再弹个对话框,提示填报成功了。
1. 连接数据库FRDemo
2. 报表设计
2.1 新建报表
2.2 模板设计
添加一个名为ds1的数据库查询:SELECT * FROM customer,表样设计,如图
2.3 自定义报表填报属性
2.4 定义单元格空间属性
2.5 自定义报表Web属性
点击菜单栏报表|报表Web属性,进入报表Web属性窗口,在填报页面设置栏目中,将左边需要显示的按钮拖到中间的窗口中,并在右边窗口添加加载结束事件,实现自定义的填报功能,如图所示
在加载结束事件窗口中添加事件的JS代码
具体js代码如下
var $toolbar = $('.FR-ToolBar-disabled > table > tbody > tr');
var option = {
//"icon": "css:x-emb-email",
"listeners": [ {"once": false,
"action": function(e){
var xml = _g('${SessionID}').generateReportXML();
$.ajax({
url : "test.jsp",
type : 'POST',
data : {op : 'test1', sessionID : '${SessionID}',
reportXML : xml},
complete : function(res, status) {
FR.showDialog("Relation", 300, 400, res.responseText);
}})
},
"eventName": "click"
}],
"text": "测试",
"invisible": false,
"type": "button",
"disabled": false,
"render": true};
$button = $('<div></div>');
FR.comp.create($button, "button", option);
$tc = $("<td>").append($button);
$toolbar.append($tc);
此段JS代码引用了一个test.jsp,代码为:
<%@ page import="com.fr.web.CustomSubmit" %>
<%@ page contentType="text/html" %>
<%
CustomSubmit.dealWithTest(request, response);
%>
将该test.jsp文件放在设计器安装的WebReport目录下。
该test.jsp文件又引用了一个CustomSubmit类,将该类编译后的.class文件放在
%WebReport\WEB-INF\classes\com\fr\web目录下,该类的代码具体如下
package com.fr.web;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.fr.base.ColumnRow;
import com.fr.report.Report;
import com.fr.report.core.FormReport;
import com.fr.report.core.PackedReport;
import com.fr.web.ParameterConsts;
import com.fr.web.core.SessionDealWith;
import com.fr.web.core.SessionIDInfor;
import com.fr.web.core.WebUtils;
public class CustomSubmit {
public static void dealWithTest(HttpServletRequest req, HttpServletResponse res) throws Exception {
String sessionID = WebUtils.getHTTPRequestParameter(req,ParameterConsts.SESSION_ID);
SessionIDInfor sessionIDInfor = SessionDealWith.getSessionIDInfor(sessionID);
List cellRelation = new ArrayList();
for(int i = 0, len = sessionIDInfor.getWorkBook2Show().getReportCount(); i < len; i++) {
Report report = sessionIDInfor.getWorkBook2Show().getReport(i);
if (report instanceof FormReport && report instanceof PackedReport) {
Report fr = (PackedReport)report;
//请注意这步,我想要取的是A1和B1两个格子扩展以后的他们之间关系和值,如果是想拿A1,B1,D5,对应添加ColumnRow.valueOf("D5")既可
List rl = ((FormReport)report).getExtendColumnRowList(new ColumnRow[] {ColumnRow.valueOf("A1"), ColumnRow.valueOf("B1")});
for (int c = 0, cl = rl.size(); c < cl; c++) {
ColumnRow[] crs = (ColumnRow[])rl.get(c);
ColumnRowValue[] crvs = new ColumnRowValue[crs.length];
for (int index = 0, il = crs.length; index < il; index++) {
crvs[index] = new ColumnRowValue(crs[index], fr.getCellValue(crs[index].column, crs[index].row));
}
cellRelation.add(crvs);
}
}
}
//cellRelation 里面存放着扩展以后的格子之间的关系和格子的值
//以111.cpt模板为例,数据列扩展后 城市NewYork对应ID 1和4,在cellRelation里面就是 cellRelation.get(0)和cellRelation.get(1),对应着两个 ColumnRowValue[]
//第一个ColumnRowValue数组的ColumnRowValue[0]的ColumnRow是A1,Value是NewYork,ColumnRowValue[1]的ColumnRow是B1,Value是1
//第二个ColumnRowValue数组的ColumnRowValue[0]的ColumnRow是A1,Value是NewYork,ColumnRowValue[1]的ColumnRow是B2,Value是4
if (cellRelation.size() > 0) {
PrintWriter writer = WebUtils.createPrintWriter(res);
for (int i = 0, len = cellRelation.size(); i < len; i++) {
ColumnRowValue[] crvs = (ColumnRowValue[])cellRelation.get(i);
StringBuffer sb = new StringBuffer();
for (int v = 0, vl = crvs.length; v < vl; v++) {
if (v != 0) {
sb.append(" ");
}
sb.append(crvs[v].toString());
if (v == vl - 1) {
sb.append("<br />");
}
}
writer.println(sb.toString());
}
writer.flush();
writer.close();
}
}
public static class ColumnRowValue {
private ColumnRow cr;
private Object value;
public ColumnRowValue(ColumnRow cr, Object value) {
this.cr = cr;
this.value = value;
}
public ColumnRow getColumnRow() {
return cr;
}
public Object getValue() {
return value;
}
public String toString() {
return new StringBuffer().append(cr.toString()).append(":").append(value.toString()).toString();
}
}
}
3. 保存并预览
点击填报预览,BS界面除了FR报表自带的提交按钮和数据校验按钮外,还多了一个测试按钮
点击测试按钮,出现测试界面
自定义控件CSS
在实际项目中,为了更符合使用者的审美观或者让FineReport报表和总体框架协调,可能需要修改一些页面显示的样式表(CSS),如更换控件的图标或者改变填报表单控件的显示样式等。
自定义控件图标
如下以下拉树控件为例说明如何改变控件的图标。
1.下拉树模板制作
1.1 新建报表
1.2 定义参数
在菜单栏中选择报表|报表参数,定义报表参数tree。
1.3 参数界面设置,如下图所示
1.4 控件设置,如下图所示
类型选择下拉树,层次有两层,定义如下图
1.5 分页预览
分页预览可以看到默认的控件图标如下
2. 引用CSS更换控件图标
2.1 收集图标
收集好需要使用的图标,推荐大小为16×16,假设想让树叶的图标为leaf.gif。
2.2 保存图标
在WebReport目录下(即和WEB-INF平行的地方)新建一个文件夹,文件名为custom,将第一步的图标放入该文件夹内。
2.3 生成CSS样式
在custom文件夹内新建一个css文件,如叫custom_tree.css,内容如下:
.bbit-tree-node-leaf{background:url("leaf.gif");}
说明:该语句是用来置换树叶的样式。
2.4 引用CSS
打开使用下拉树控件的报表,点击菜单报表|报表Web属性|引用css,在控件自定义样式表界面点插入按钮后写上custom_tree.css的相对路径:
custom/custom_tree.css
确定后保存报表。
2.5 分页预览
点击设计器中的分页预览,可看到更换图标后的下拉树效果
3. 控件相关CSS
下拉树控件
.bbit-tree-node-expanded.bbit-tree-node-icon //节点展开的样式
.bbit-tree-node-leaf.bbit-tree-node-icon //树叶的样式
.bbit-tree-node-collapsed.bbit-tree-node-icon //闭合的样式
.bbit-tree-node-loading.bbit-tree-node-icon //正在加载的样式
填报焦点框变成红色
默认情况下,填报预览时,焦点所在的编辑框是用黑色加重显示的,FineReport也可以让用户通过引用CSS样式来改变焦点框的颜色,以下就以用红色加重显示焦点框来做说明。
3.1 打开reportlets\doc\Tutorial\Form\stuff.cpt 报表。
3.2 引用CSS改变焦点框颜色
l 在WebReport目录下新建一个文件夹,文件名为write,在write文件夹下新建一个名为custom_cell.css的文件,文件内容为:
.fDtop, .fDbottom, .fDleft, .fDright, .fDdot{ border:1px solid red; }说明:该语句是用来改变焦点框的颜色
l 引用CSS
打开stuff报表,依次点击菜单报表|报表web属性|引用Css,在控件自定义样式界面点插入按钮后写上custom_cell.css的相对路径:
write/custom_cell.css
确定后保存报表
3.3 分页预览
点击设计器中的分页预览,可以看到进入编辑状态的焦点框变成红色了
注:同理,冻结线也可以按照类似的步骤进行自定义。
其他JS函数
FineReport包含的大量的JS函数供用户调用,现列表如下
1. 对象函数
Array:
indexOf //计算一个参数,返回它在数组中的位置,如果不在数组中,则返回-1
remove //移除数组对象中一个指定的元素,并返回一个新的数组
String:
leftPad //返回一个左对齐的字符串
format //返回格式化后的字符串
startWith //判断一个字符串是否以指定的字符串开始
endWith //判断一个字符串是否以指定的字符串结束
2. 常态函数
FR.isArray //判断一个对象是否是一个数组
FR.toRE //将普通字符串转化为表示正则表达式的字符串
FR.extend //实现JavaScript类的继承
FR.SessionMgr.get //根据sessionID生成BasePane
FR.cjkEncode //返回对中日韩问做了特殊转换的字符串
FR.cjkDecode //将cjkEncode处理过的字符串转化为原始字符串
FR.jsonEncode //返回json格式的字符串
FR.jsonDecode //将json格式的字符串转化为对象
FR.object2String //将object转换为一个字符串并以json的格式来写这个字符串
FR.contains //判断对象c是否包含在对象p中
FR.accDiv //精确除法
FR.accMul //精确乘法
FR.accAdd //精确加法
FR.accMin //精确减法
3. UI函数
FR.showDialog //显示一个对话框
FR.showIframeDialog //在一个iframe中显示对话框
FR.showRemoteDialog //显示一个异步加载的对话框
FR.closeDialog //关闭对话框
FR.Msg.Alert //对window的alert方法的替代实现
FR.Msg.Confirm //确认信息对话框
FR.Msg.Prompt //输入信息对话框
4. 打印
FR.doURLPDFPrint //使用PDF打印指定url的报表
FR.doURLAppletPrint //使用Applet打印指定url的报表
FR.doFlashURLPrint //使用Flash打印指定ur的报表
5. jQuery布局
__border__ //把指定dom元素按东南西北中的方式布局
__grid__ //把指定的dom元素按格子分布方式布局
6. 组件注册和生产
FR.comp.reg //注册是一个指定type的组件
FR.comp.create //在指定dom节点上生成一个组件
7. FR.OB(事件观察者)
fireEvent //触发一个有FR.OB对象定义的事件
on //给FR.OB对象添加一个事件
once //给FR.OB对象添加一个仅执行一次的事件
un //从一个FR.OB中移除掉指定事件
purgeListeners //移除掉一个FR.OB下的所有事件
8. FR.Widget(控件) extends OB
isEnable //判断一个控件是否可用
isVisible //判断一个控件是否可见
enable //使控件可用
disable //使控件不可用
9. FR.Form(表单) extends OB
formSubmit //表单提交
getValueByName //根据名字获取表单对象中控件的值
getWidgetByName //很据名字获取表单对象中的控件
getWidgetByCell //根据单元格获取控件
10. FR.BasePane extends Widget
Load //加载报表页面(展现、填报)
loadReportPane
zoom // IE6下的放大镜
11. FR.BaseEditor extends Widget
getValue //获取编辑器的值
setValue //设置编辑器的值
reset //重置编辑器的值,设为字符串
isValidate //判断当前编辑器的值是否有效
getErrorMsg //获取编辑器值无效时的错误信息
startEditing //编辑器开始编辑
stopEditing //编辑器停止编辑
12.
FR.FileUploadEditor(文件上传控件) extends BaseEditor
FR.CheckBoxGroup(复选按钮组控件) extends BaseEditor
FR.RadioGroup(单选按钮组控件) extends BaseEditor
FR.ToogleButton extends BaseEditor
Selected //检查button的选中状态或者设置button的选中状态
FR.CheckBox extends ToogleButton
FR.Radio extends ToogleButton
FR.TextEditor(文本控件) extends BaseEditor
selectText //选取文本编辑器值的指定位置的字符串
FR.NumberEditor(数字控件) extends TextEditor
FR.DateTimeEditor(日期时间控件) extends TextEditor
FR.TriggerEditor extends TextEditor
onTriggerClick //点击trigger图标的事件
FR.ComboBoxEditor(下拉框控件) extends TriggerEditor
onTriggerClick
setMode //设置下拉框的模式,通过该设置可以让下拉框强制重新加载数据
isExpanded //判断下拉框的下拉菜单是否已经展现
expand //打开下拉框的下拉菜单
collapse //关闭下拉框的下拉菜单
FR.CheckboxEditor(下拉复选框) extends ComboBoxEditor
FR.TreeComboBoxEditor(下拉树) extends CheckboxEditor
13.
FR.PagePane extends BasePane
currentPageIndex //全局变量:该ReportPage所属的ReportPage集中的序号
reportTotalPage //全局变量:该ReportPage所属的ReportPage集所生成的总的ReportPage的个数
gotoPage //将页面跳转到指定页
gotoFirstPage //页面跳转至首页
gotoLastPage //页面跳转至最后一页
gotoPreviousPage //页面跳转至当前页的上一页
gotoNextPage //页面跳转至当前页的下一页
printReportServer //服务器打印
emailReport //邮件发送
pdfPrint // PDF打印
appletPrint // Applet打印
flashPrint // Flash打印
exportReportToPDF //将报表导出成PDF
exportReportToExel //将报表导出成excel
exportReportToWord //将报表导出成word
14.
FR.WritePane extends BasePane
curLGP //变量:填报页面当前的逻辑数据处理对象
getCellValue //获取指定格子的值
setCellValue //设置指定格子的值
stopEditing //停止当前填报面板的编辑
verifyAndWriteReport //在自动校验后才提交报表入库,如果校验失败,则不会入库
writeReport //直接提交报表入库
saveReport //保存报表
verifyReport //校验报表
pdfPrint // PDF打印
flashPrint // Flash打印
exportReportToPDF //将报表导出成PDF
exportReportToExcel //将报表导出成Excel
exportReportToWord //将报表导出成Word
printReportServer //服务器端打印
emailReport //邮件发送
FR.WLGP(WritePane的逻辑数据处理对象) extends FR.OB
Idx //变量:报表索引
getCellValue //获取指定格子的值
setCellValue //设置指定格子的值
fireCellValueChange //单元格值改变后出发该函数
isSelectable //判断该dom的tdCell是否可被选中
selectTDCell //选中dom tdCell。也就是加个黑边框,并确保tdCell在屏幕显示范围内
editTDCell //编辑dom tdCell
clearCellSelection //清除格子的选中状态
displayTDCell //把值显示在td里面
|