填报自定义提交设置
作者:finereport
浏览:19,942
发布时间:2023.7.30
自定义报表问题描述
用户在做填报报表时,希望点击提交按钮并不是往数据库中填报数据,而是要获取到填报页面的数据进行进一步处理,这个该如何解决呢?
自定义报表解决思路
在报表填报属性中介绍了报表填报属性有2种设置方式,一个是内置SQL直接绑定字段,往数据库中填报数据,另外一种是添加自定义事件,如果需要获取数据对数据进行进一步处理,则可选择添加自定义事件,下面详细介绍。
自定义报表示例
获取填报页面的值,通过自定义事件获取到数据并在后台打印出来。
自定义事件类
自定义事件继承自DefinedSubmitJob这个接口,通过JobValue接口获取填报页面单元格,JobValue与报表填报属性处的属性绑定,然后用getValue()方法获取单元格的值,getValueState()获取值的状态,值状态有四种:VALUE_STATE_CHANGED、VALUE_STATE_INSERT、VALUE_STATE_DELETED和VALUE_STATE_DEFAULT。
方法一
在类里面定义几个JobValue,每一个JobValue对应一个单元格,在报表填报属性中通过属性列表中将其与对应的单元格绑定起来,具体使用如DemoSubmitJob1:
package com.fr.data;
import com.fr.data.DefinedSubmitJob;
import com.fr.data.JobValue;
import com.fr.script.Calculator;
public class DemoSubmitJob1 extends DefinedSubmitJob {
/**
* 当模板自定义事件增加的属性 名称与下面变量有对应时,则会自动赋值于此对应变量
*/
private JobValue studentno; // JobValue对应单元格
private JobValue name;
private JobValue grade;
private boolean isPass; // 非单元格,则对应具体类型值
/**
* 每一条记录执行一次此方法
* 同一提交事件在一个处理事务内,此对象是唯一的
*/
public void doJob(Calculator calculator) throws Exception {
// JobValue的getValueState()方法获取此对应单元格的状态
if (studentno.getValueState() == JobValue.VALUE_STATE_CHANGED) {
// 此单元格的值在报表初始化后被修改过
} else if (studentno.getValueState() == JobValue.VALUE_STATE_INSERT) {
// 此单元格是在报表初始化后新增的(例如执行了插入行操作)
} else if (studentno.getValueState() == JobValue.VALUE_STATE_DELETED) {
// 此单元格所在的记录被执行了删除操作
} else if (studentno.getValueState() == JobValue.VALUE_STATE_DEFAULT) {
// 此单元格在报表初始化后没有变化
}
// 值获取
System.out.print(" 学号: " + studentno.getValue()); // 通过JobValue的getValue方法获得单元格的值
System.out.print(" 姓名: " + name.getValue());
System.out.print(" 总分: " + grade.getValue());
System.out.print(" 是否达标: " + isPass);
System.out.println();
}
}
注:可以讲所有变量全部定义成JobValue对象,通过getValue()获取对象的值。
方法二
通过doJob的方法参数Calculator中的 Property_Value属性, Property_Value属性对应一个map对象,Map中包含报表填报属性中所有属性名称以及它们对应的值,使用map中的getValue()方法获取属性值,即单元格,接着使用JobValue的getValue()方法获取单元格的值,详细如DemoSubmitJob2:
package com.fr.data;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import com.fr.data.DefinedSubmitJob;
import com.fr.data.JobValue;
import com.fr.script.Calculator;
public class DemoSubmitJob2 extends DefinedSubmitJob {
/**
* 每一条记录执行一次此方法
* 同一提交事件在一个处理事务内,此对象是唯一的
*/
public void doJob(Calculator calculator) throws Exception {
// 同样可以直接在传入的calculator中获取定义的属性及其对应的值
Map map = (Map)calculator.getAttribute(PROPERTY_VALUE);
if (map == null) return;
Set set = map.entrySet();
Iterator it = set.iterator();
Entry entry;
// 遍历Map获取所有属性及其值
while (it.hasNext()) {
entry = (Entry)it.next();
System.out.print(" " + entry.getKey() + ": ");
// JobValue对应单元格
if (entry.getValue() instanceof JobValue) {
JobValue ce = (JobValue)entry.getValue();
// JobValue的getValueState()方法获取此对应单元格的状态
if (ce.getValueState() == JobValue.VALUE_STATE_CHANGED) {
// 此单元格的值在报表初始化后被修改过
} else if (ce.getValueState() == JobValue.VALUE_STATE_INSERT) {
// 此单元格是在报表初始化后新增的(例如执行了插入行操作)
} else if (ce.getValueState() == JobValue.VALUE_STATE_DELETED) {
// 此单元格所在的记录被执行了删除操作
} else if (ce.getValueState() == JobValue.VALUE_STATE_DEFAULT) {
// 此单元格在报表初始化后没有变化
}
System.out.print(ce.getValue()); // 通过JobValue的getValue方法获得单元格的值
} else {
// 非单元格,则对应具体类型值
System.out.print(entry.getValue());
}
}
System.out.println();
}
}
方法三
自定义事件除了可继承自DefinedSubmitJob这个接口之外,还可以继承TotalSubmitJob接口,这两个接口的区别在于DefinedSubmitJob多次执行,即一行一行的获取模板中的数据,获取一行数据则执行一次自定义事件,而TotalSubmitJob接口只执行一次,即先获取到模板中所有的数据,然后在类里面循环,具体使用如DemoTotalSubmitJob:
package com.fr.data;
import com.fr.data.JobValue;
import com.fr.data.TotalSubmitJob;
import com.fr.script.Calculator;
public class DemoTotalSubmitJob extends TotalSubmitJob {
/**
* 同一提交事件,在一个提交事务内只执行一次
* @param data 以二维表排列的所有提交数据
*
*/
protected void doTotalJob(Data data, Calculator calculator)
throws Exception {
data.getColumnCount(); // 获取列的数量,每一列对应一个添加的属性
for (int i = 0; i < data.getColumnCount(); i++) {
System.out.println(data.getColumnName(i)); // 获取对应的属性名称
}
for (int i = 0; i < data.getRowCount(); i++) { // getRowCount 获取一共多少行数据
System.out.print("ROW " + i + " {");
for (int j = 0; j < data.getColumnCount(); j++) {
if (j > 0) System.out.print(", ");
Object value = data.getValueAt(i, j); // 获取对应位置的值
if (value instanceof JobValue) {
JobValue ce = (JobValue)value;
// JobValue的getValueState()方法获取此对应单元格的状态
if (ce.getValueState() == JobValue.VALUE_STATE_CHANGED) {
// 此单元格的值在报表初始化后被修改过
} else if (ce.getValueState() == JobValue.VALUE_STATE_INSERT) {
// 此单元格是在报表初始化后新增的(例如执行了插入行操作)
} else if (ce.getValueState() == JobValue.VALUE_STATE_DELETED) {
// 此单元格所在的记录被执行了删除操作
} else if (ce.getValueState() == JobValue.VALUE_STATE_DEFAULT) {
// 此单元格在报表初始化后没有变化
}
value = ce.getValue(); // 通过JobValue的getValue方法获得单元格的值
}
System.out.print(data.getColumnName(j) + " : " + value);
}
System.out.print("}");
System.out.println();
}
}
}
填报页面主体设置
数据准备
新建数据库查询ds1:SELECT * FROM [STSCORE] where name <> ''。
主体界面
将studentno,name和grade求和拖曳至单元格中,并为之添加控件,如下图:
B4和D4单元格为数字控件,C4单元格为文本控件。
报表填报属性设置
如上所述,实现自定义事件获取填报页面的值有三种方法,则下面根据上述的不同方法介绍填报属性的不同设置。
方法一——DemoSubmitJob1
将类文件放置到%FR_HOME%WebReportWEB-INFclassescomfrdata文件夹下面。
点击模板>报表填报属性,添加自定义事件,选择DemoSubmitJob1这个类,为类中定义的变量绑定单元格或公式,如下图:
注:该方法中属性名称跟类文件中定义的JobValue是一一对应的,必须保证报表填报属性处添加的属性名称与类文件中定义的名称保持一致,并且如果在类文件中对应参数类型不是JobValue的话,则就必须与属性的数据类型保持一致,一般来说,为了便于维护,可以讲java类中的所有变量全部设为JobValue对象,不论报表填报属性中的属性类型是什么,均可以通过GetValue获取其值。
效果展示
后台打印效果如下:
方法二——DemoSubmitJob2
将类文件放置到%FR_HOME%WebReportWEB-INFclassescomfrdata文件夹下面。
点击模板>报表填报属性,添加自定义事件,选择DemoSubmitJob2这个类,为类中定义的变量绑定单元格或公式,如下图:
注:方法二中是通过Calculator参数属性PROPERTY_VALUE来获取报表填报属性处的属性与属性值,再通过JobValue来得到单元格的值,在类文件中并不是一一对应的获取属性与属性值,而是通过map遍历来获取属性与属性值,所以在报表填报属性处增加属性时,属性名字可随意定义,但是后面的值如果是单元格的话,必须选择单元格类型。
效果展示
后台打印效果如下:
方法三——DemoTotalSubmitJob
将类文件放置到%FR_HOME%WebReportWEB-INFclassescomfrdata文件夹下面。
点击模板>报表填报属性,添加自定义事件,选择DemoTotalSubmitJob这个类,为类中定义的变量绑定单元格或公式,如下图:
注:方法三与方法二中的使用方式类似。
效果展示
后台打印效果如下:
其他应用
自定义事件不仅可用于报表填报属性处,也可用于按钮控件中的提交事件,具体可查看上传文件至指定路径。
报表工具产品更多介绍:www.finereport.com