打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
web报表工具填报功能全攻略
表单提交超链接……………………………………………………… 2
单元格不改变时不参与更新………………………………………… 6
及时校验……………………………………………………………… 8
跨格数据及时校验…………………………………………………… 12
扩展数据的数据校验………………………………………………… 16
批量修改单元格……………………………………………………… 17
填报保存值类型……………………………………………………… 19
填报流水号…………………………………………………………… 22
填报自动匹配值……………………………………………………… 26
文本域换行…………………………………………………………… 29
下拉框的快速查询…………………………………………………… 33
行式报表……………………………………………………………… 34
用户自定义填报……………………………………………………… 39
表单提交超链接
在填报时,提交会出现两种结果,提交成功和提交失败,可以对这两种结果进行事件编辑,在FineReport6.5中可以通过报表->报表Web属性->填报页面设置添加提交成功和提交失败事件进行编辑。
1. 打开模板
2. 添加提交事件
点击填报|报表Web属性,选择填报页面设置栏目,进入填报页面设置窗口,在右边栏中添加提交成功和提交失败事件,如下图所示
具体的填报成功事件和填报失败事件代码如下
填报成功事件,添加JS代码:window.open(“http://www.baidu.com”);
在填报成功后,打开百度连接。
提交失败事件,JS代码:
window.open("http://localhost:8079/WebReport/ReportServer?op=fs");
该代码用于填报提交失败后打开产品演示文档。
3. 填报并预览
点击设计器的填报预览,效果如图
点击提交,显示提交成功
点击确定按钮,这是触发提交成功事件,链接到百度首页
不填用户编号时提交失败,如图
点击确定按钮,触发提交失败事件,页面跳转到产品演示文档
单元格不改变时不参与更新
填报提交时,将根据情况进行insert/update操作,当填报列数较多时,速度可能较慢,因为他要对所有字段进行操作。此时可以设置单元格不改变时不参与更新,这样,相应的数据列在数据不改变时,不会参与更新操作,即SQL语句中update中不包含该列,进而提高填报的效率。但这个功能只有在填报更新数据的时候有效,如果是插入操作的话仍是插入所有字段,因此需要在使用报表主键的的基础上使用该功能。
1.  新建报表
新建一张空白报表,添加数据库查询ds1,SQL语句为:SELECT * FROM stscore WHERE studentno=1014,设计成如下格式的报表
2.  控件设置
给单元格加上控件,分别定义如下单元格控件属性
单元格
B3
C3
D3
E3
F3
G3
控件类型
文本
文本
文本
文本
文本
文本
3.  报表填报属性
添加内置SQL,具体设置如下图,将studentno设为主键,所有的单元格设置不改变时不参与更新,这样进行update操作时只有单元格改变的列才参与更新。
4.  保存并预览
保存模板,点击设计器的填报预览,结果如下图所示
我们修改Achilles这个学生的英语成绩,原为93,我们改为100,点击提交
此时,日志面板中的更新语句为
INFO:UPDATE [STSCORE] SET [GRADE]=?  WHERE [STUDENTNO]=? AND [COURSE]=?
可以看到,数据库只更新了GRADE的值,且只对三个字段进行了操作。
但若是不设置“单元格不改变时不参与更新”,同样的操作我们将会得到如下更新语句:
INFO:UPDATE [STSCORE] SET [CLASSNO]=?,[NAME]=?,[SEX]=?,[GRADE]=?  WHERE [STUDENTNO]=? AND [COURSE]=?
数据库对每个字段都进行了更新操作,若列数量多的情况就会非常耗时了。
及时校验
现有的控件设置面板中包含有各种及时校验,如文本控件的填写规则校验、数字的精度校验、日期时间可以规定范围等,以下介绍几种常用的及时校验设置。
1.       文本控件及时校验
文本控件类型有不为空的校验,也有填写规则校验,更有自定义校验,FineReport报表中自带有长度,邮件,身份证,邮政编码,电话 ,手机等及时校验,自定义校验可以根据需要自己书写正则表达式。
例如输入验证用户密码的正则表达式:“^[a-zA-Z]\w{5,17}$”表示密码规则是以字母开头,长度在6-18之间,只能包含字符、数字和下划线。
l  \d任意一个数字,0~9中的任意一个
l  \w任意一个字母或数字或下划线,也就是A-Z,a-z,0-9中任意一个
l  \s包括空格、制表符、换页符等空白字符的其中任意一个
l  .小数点可以匹配除了换行符(\n)以外的任意一个字符
l  ^开始
l  $结束
一些表达式的作用:
{n}:表示重复n次,比如"\w{2}" 相当于 "\w\w";"a{5}" 相当于 "aaaaa"
{m,n}:表示至少重复m次,最多重复n次,比如"ba{1,3}"可以匹配 "ba"或"baa"或"baaa"
{m,}:表示至少重复m次,比如"\w\d{2,}"可以匹配 "a12","_456","M12344"
:匹配表达式0次或者1次,相当于 {0,1},比如"a[cd]?"可以匹配 "a","ac","ad"
+:表达式至少出现1次,相当于 {1,},比如"a+b"可以匹配 "ab","aab","aaab"
*:表达式不出现或出现任意次,相当于 {0,},比如"\^*b"可以匹配 "b","^^^b"。
一些常用小例子举例:
(1)       检查手机号是否合法:/^1(3\d|5[36789])\d{8}$/
说明:手机号共11位,第一位为1,第二位为3或者5,当第二位为5的时候,第三位只能是36789中的一个
(2)       检查中文名是否合法:/^[\u4e00-\u9fa5]+$/
说明:若不是中文或中文的前后有空格,都认为是不合法的
(3)       检查html标记是否匹配:/<(.*)>.*<\/\1>|<(.*) \/>/
说明:如若只出现<html> 而无对应的</html>,则检验结果是html 标记不匹配
(4)       检查URL格式是否合法:”[a-zA-z]+://[^\s]*”
说明:URL合法格式应该以字母连接:// 开头
(5)       检查IP格式是否合法:/(\d+)\.(\d+)\.(\d+)\.(\d+)/
说明:IP的格式是点分十进制格式,例如:192.168.100.11就是正确的IP
(6)       检查账号是否合法:/^[a-zA-Z][a-zA-Z0-9_]{4,15}$/
说明:账号字母开头,其他位可以有大小写字母、数字、下划线,允许5-16字节
(7)       检查QQ号是否合法:/^\s*[.0-9]{5,10}\s*$/
说明:QQ号码必须是数字,最长10位
(8)       检查邮政编码是否合法:/^[1-9]\d{5}$/
说明:邮编首位不为0,长度是6位的数字
(9)       检查身份证号是否合法:/(^\d{15}$)|(^\d{17}([0-9]|X)$)/
说明:身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
2.       数字控件及时校验
数字控件有不为空校验,同时也可以控制其是否允许小数与父数,还可以设置数值的范围。
3.       日期和时间控件及时校验
日期和时间控件可以设置其所在范围,如下图
4.       下拉框的不为空
对于下拉框、下拉复选框、下拉树等下拉选项控件,他们的允许为空设置除了表示该控件不允许为空值,同时也可以控制他们的下拉选项中不允许有空选项,结合“空值将显示为:”一起使用。例如下图设置
此时下拉选项中空值记录便会显示为ALL,效果如下
若未选择任何项,确定后编辑其他单元格时将弹出及时校验对话框
跨格数据及时校验
在实现填报时,有时需要在编辑完数据后跟其他具体某个格子对比,进行及时校验。当报表中提供的及时校验不能满足需求时,可以通过js事件来进行及时校验
1.  连接数据库FRDemo
2.  设计模板
2.1 新建报表
2.2 表样设计,如下图所示
2.3 定义单元格填报属性
l  设置B2的控件类型为数字,如图所示
l  设置B3的控件类型为文本,如图所示
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。
3.  保存并预览
点击填报预览,在B2单元格中输入数字9,并按回车确定,则弹出警告,如图
在B3单元格中输入add,并按回车确定,也弹出校验警告,如图
扩展数据的数据校验
在填报模块中,有时需要对扩展的数据进行数据校验,例如:已知商品的价格,数量,总额,在填报提交时需要对总额进行校验,看总额是不是等于价格*数量。
1.  连接数据库FRDemo
2.  设计模板
2.1 新建报表
新建一张空白报表,添加数据集ds1:SELECT orders.orderid,amount,quantity,price FROM orders,ordersdetail WHERE orders.orderid = ordersdetail.orderid AND orders.orderid<’10006’。然后设计成一张如下格式的报表:
2.2 定义报表填报属性,添加两个内置SQL,具体设置如图
l  内置SQL1
l  内置SQL2
2.3 定义单元格填报属性
单元格分别定义如下填报属性
单元格
属性
B3
文本
C3
文本
D3
文本
E3
文本
2.4 数据校验
打开报表|报表填报属性,选择数据校验,插入新的验证信息。校验公式为
D3>=5&&D3<=100,表示D3单元格中的数据必须小于5并且小于100,否则数据校验时报错
3.  保存并预览
点击设计器中的填报预览,并在BS界面点击数据校验,发现有一条数据不符合规范,报错,如图
批量修改单元格
在大批量数据填报时,有时可能需要将置数单元格整体偏移多行或多列,若手动进行修改将会很麻烦,FineReport提供了批量修改单元格的功能,可以对大批量数据进行处理。
1.  打开报表
打开已有报表
2.  调整报表布局
3.  报表填报属性
打开报表|报表填报属性,如下图所示
我们发现,修改了样式后,所有填报的值对应的单元格存在偏差,应为A3、B3、C3、D3、E3、F3,此时一个一个的修改可能比较麻烦,我们可以利用批量修改单元格,具体操作如图
点击确定后,填报单元格统一进行了修改,如图
这样填报的值对应的单元格就通过批量修改单元格修改成功了!
填报保存值类型
在填报时控件类型为日期或者数字时,如果数据库Oracle中类型与填报控件中的类型不一致,填报时就无法插入数据,需要对填报控件进行处理才能插入。下面对Oracle数据中数据类型为Date 和 Number 类型数据进行填报介绍。
1.  连接数据库Oracle10g
点击报表菜单栏服务器|自定义数据连接,添加数据库,名为Oracle10g,JDBC数据库选择Oracle,URL为:jdbc:oracle:thin:@192.168.100.169:1521:orcl10g,用户名为:temp,密码为:temp123,具体配置如下图
2.  新建报表
新建一张空白的表格,添加数据ds1: SELECT * FROM temp.testdate
然后设计一张如下格式的报表
3.  定义报表填报属性
自定义如下填报属性
4.  自定义单元格填报属性
单元格分别定义如下填报属性
单元格
属性
A2
文本
B2
文本
C2
文本
D2
日期
E2
数字
其中D2单元格的控件需要处理,日期的返回值类型选择日期
5.  保存并预览
点击设计器填报预览,如图
在生日单元格中修改数据,并提交
提交成功
对于电话填报,Oracle中的数据类型是Number时,当Oracle中的Number大小小于10位时,填报中能保存的数字位数为Number的大小,即Oracle中Number大小是多少,填报就能保持几位;当Oracle中的Number大小大于10时,填报数字控件只能保存10位数字。
填报流水号
在填报中,批量数据处理时为了方便,需要使用流水号来作为自增长型主键进行数据的更新。在Oracle数据库中,提供了序列的功能,可以通过Oracle的序列及触发器,实现主键的自增长。下面具体介绍自增长的实现。
1.  连接数据库
点击报表菜单栏服务器|自定义数据连接,添加数据库oracle10g116, JDBC数据库选择Oracle,URL为:jdbc:oracle:thin:@192.168.100.116:1521:orcl10g,用户名为:temp,密码为:temp123,具体配置如下图
2.  创建表,序列,触发器,插入数据
进入Oracle数据库的Sqlplus窗口,创建表,序列,触发器
l  创建表:create table list (id number,name varchar2(50));
l  创建序列:
create sequence list_seq
minvalue 1           //最小值为1
maxvalue 9999        //最大值为9999
start with 1         //以1为初始值
increment by 1       //以1为增长间隔
cache 20             //缓存大小为20
order;
l  创建触发器
create or replace trigger list_tg
before insert on list    //触发器依据的表
for each row             //逐行触发
begin                    //触发器主体
select list_seq.nextval into:new.id from dual;
end;
l  插入数据
insert into list values(‘’,’aaa’);
insert into list values(‘’,’bbb’);
l  提交
commit;
3.  模板设计
3.1  新建模板
3.2  表样设计
新建一张空白的表格,添加数据ds1: SELECT * FROM temp.list
然后设计一张如下格式的报表
3.3  定义报表填报属性
自定义如下填报属性
3.4  自定义单元格填报属性
单元格分别定义如下填报属性
单元格
属性
B1
文本
B2
文本
4.  填报并预览
点击设计器填报预览,ID列实现了自增长
在NAME控件中填入cccc,并提交,显示填报成功
再次刷新,ID列自增长
填报自动匹配值
在填报中,有时需要在输入一个数据后,自动从数据库中获取对应的数值,自动匹配至
相应的单元格,这样就避免了填报时手动一个一个输入,该例子主要是通过写公式实现。
1.  新建报表
2.  报表设计
如下设计报表
单元格
公式
说明
B3
=range(1,10)
设置从上到下扩展,批量插入10条数据
D2
=if(len(C3)==0,"",sql("FRDemo","SELECT customername FROM customer WHERE customerid = "+C3,1,1)
查询表customer获得对应id的姓名
E2
=if(len(C3)==0,"",sql("FRDemo","SELECT country FROM customer WHERE customerid = "+ C3,1,1))
同上
F2
=if(len(C3)==0,"",sql("FRDemo","SELECT city FROM customer WHERE customerid = "+ C3,1,1))
同上
G2
=if(len(C3)==0,"",sql("FRDemo","SELECT tel FROM customer WHERE customerid = "+ C3,1,1))
同上
3. 控件设置
右击C3单元格|控件设置,控件类型选择下拉框,具体设置如下
D3至H3单元格控件类型设置为文本,如下图
4. 填报属性设置
打开菜单报表|报表填报属性,如下图所示设置
5. 将A2列宽设置为零,进行隐藏
6. 保存模板,点击填报预览
在客户编号中选中相应的编号,后面的客户姓名,国家,城市,电话会自动匹配,如下图所示,只需要输入金额数值即可入库
选择客户编号后点击其他地方,后面的信息就会自动匹配进来。
7. 批量匹配数据
同时若我们将需要的客户编号写入excel文件中,导入到页面中,就可以批量的匹配数据了
l  在报表|报表Web属性|填报页面设置中,给默认的工具栏加上excel导入按钮。
l  新建一个excel,在C3至C12中输入1至10
l  点击填报预览,导入该excel,导入后,即会批量进行置数。
文本域换行
在填报中,有时需要输入大量的文本,这时就需要用到文本域这个控件,但在用这个控件时,换行不能直接按Enter键,必须按Ctrl+Enter,才能达到换行的效果。
1.       新建报表
新建一张空白的表格,添加数据ds1: SELECT * FROM employee WHERE empid=‘1001‘
然后设计一张如下格式的报表
2.       定义报表填报属性
定义如下填报属性
3.       定义单元格填报属性
单元格分别定义如下填报属性:
单元格
属性
C2
文本
C4
文本
E2
文本域
4.       保存并填报
点击设计器中的填报预览
在员工地址文本域中输入地址,换行时用Ctri+Enter键,不能用Enter键(Enter键使用后表示清空)
下拉框的快速查询
在填报控件或者参数控件的下拉框类型控件中,下拉框有快速查询的功能,即输入部分值之后自动将符合条件的值显示出来。
1.  连接数据库FRDemo
2.  设计模板
2.1  新建模板
2.2  表样设计,具体样式如下图所示
2.3  定义报表填报属性,具体设置如图
2.4  定义单元格填报属性
单元格分别定义如下填报属性
单元格
属性
A2
文本
B2
文本
C2
文本
D2
下拉框
E2
文本
D2单元格控件设置的类型是下拉框,具体如图
3.  保存并预览
点击设计器的填报预览,如下图所示
在城市的下拉框中,输入W会出来所有以W开头的城市名,这就是下拉框的快速查询功能,预览如图所示
行式报表
在填报时,有时行式填报希望能从数据库取出来的行不能编辑,只能编辑通过添加行产生新的行,FR报表软件可以通过条件属性来设置
1.       新建报表
新建一张空白的表格,添加数据ds1: SELECT * FROM employee
然后设计一张如下格式的报表
2.       定义报表填报属性
自定义如下填报属性
3.       自定义单元格填报属性
单元格分别定义如下填报属性
单元格
属性
B2
文本
C2
文本
D2
文本
E2
文本
F2
文本
A2的填报属性可以用条件属性设置
4.       条件属性设置
右击A2单元格,选择条件属性,进入条件属性窗口,添加条件属性,属性选择空间,并选中使用控件,编辑,控件类型选择文本,并添加公式(row()-1)>rowcount(“ds2”)
该公式表示,如果当前行号大于数据集中的总行数,则行号控件可用,具体如图
5.       填报并预览
点击设计器中的填报预览,如下图,从数据库中取出来的行的行号是不可编辑的
在BS界面上选中最后一行,并在上方的工具栏中点击增加记录,新出现一行,该行的行号可编辑,如图
用户自定义填报
在填报时,个别用户为了需求,需要自定义填报。FR报表在报表web属性中的填报页面设置中可以自定义填报功能
1.  连接数据库FRDemo
2.  设计报表
2.1  新建报表
2.2  表样设计
添加一个名为ds1的数据库查询:SELECT * FROM customer,表样设计,如图
2.3  自定义报表填报属性
2.4  定义单元格填报属性
单元格
属性
A1
文本
B1
文本
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报表自带的提交按钮和数据校验按钮外,还多了一个测试按钮
点击测试按钮,出现测试界面
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
快、准、狠!秒杀Excel的报表工具,十分钟教你做好数据填报
使用ActiveReports报表服务器创建并发布报表设计报表布局
你还在用Excel? 用这工具,5步完爆Excel表格
Excel ActiveX 控件到底有啥用?如此美貌的下拉菜单,非它不可
Spread for Windows Forms高级主题(2)
不想再被报表需求烦到炸,4个妙招让你实现批量制表
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服