历史版本5 :自定义校验 返回文档
编辑时间: 内容长度:图片数:目录数: 修改原因:

目录:

1. 描述编辑

在web页面录入数据后,提交前,可能存在一些特殊的业务逻辑,用FineReport现有的校验公式现实起来比较复杂,或者是用户已经有了一套校验标准,希望FineReport能够将这种校验交付给用户自己的程序来判断,然后将结果返回给FineReport,这个时候就可以用自定义校验

2. 模板设计编辑

用自定义校验来验证每个销售员的销售总额数据是否正确,所有的销售总额数据均不能小于2000。
新建数据查询ds1:SELECT * FROM [销售总额]
将数据列拖曳至模板中,并为数据列所在单元格添加文本控件,如下图:
点击模板>报表填报属性,添加一个内置sql,如下图:

3. 自定义校验类编辑

自定义校验功能,该功能是指用户可以通过java类来校验填报页面上数据是否符合规则,并获得返回值。
自定义校验类既可通过接口类com.fr.data.VerifyJob.class对每条记录进行校验,校验失败时定位至出错单元格,也可以通过com.fr.data.TotalVerifyJob接口类对页面数据进行校验,下面分别介绍:
注:不论继承哪个接口类,都需要定义一个私有变量type(名称可改变),用来返回校验结果,type=0,表示校验成功,type=1表示校验失败,默认type=0。
3.1 方法一、
com.fr.data.VerifyJob.class
通过该接口编写自定义校验类,可以对每条记录进行校验,校验失败时可以定位至出错单元格。该接口类有一下方法:
doJob(Calculator calculator)calculator可以获得当前报表、当前单元格;
getType() 获取用户设置的标志位type的值;
getMessage()根据type类型设置返回信息。
VerifyJob接口是每一条记录执行一次doJob方法,执行完后将该记录的结果get出来,放到list里面,返回信息,以便在BS下定位错误单元格。继承VerifyJob接口时,用户在其自定义校验类中定义的field名必须与添加的属性名称匹配。
下面编写VerifyJobDemo类,继承自VerifyJob,对填报页面数据进行校验,如果销售总额的值小于2000,则提示“销量值不能小于最小基数”,否则提示“恭喜你,校验成功”。
代码如下:
package com.fr.demo;        import java.util.logging.Level;     import java.util.logging.Logger;     import com.fr.base.FRContext;     import com.fr.base.Utils;     import com.fr.data.DefinedVerifyJob;     import com.fr.data.JobValue;     import com.fr.function.LOG;     import com.fr.script.Calculator;          public class VerifyJobDemo  extends DefinedVerifyJob{         /*        * 必须要定义此私有变量,变量名可改,表示校验状态        * 0  表示校验成功,默认校验状态位为0        * 1  表示校验失败        */         private int type = 0;                   /**        * 当模板自定义事件增加的属性 名称与下面变量有对应时,则会自动赋值于此对应变量        */         private JobValue salenum;   // JobValue对应单元格         private int minnum;       // 非单元格,则对应具体类型值              public void doJob(Calculator calculator) throws Exception {             /*            * 如这边提供一个简单的判断来模拟执行过程            * 校验规则为销量需要大于等于最小基数:salenum >= minnum            * 校验不通过,提示“销量值不能小于最小基数”            */             if(salenum != null){                 int sale = 0;                 if(salenum.getValue() instanceof Integer){ //将单元格值转为整型以便用于比较                     sale = (Integer)salenum.getValue();                                           }else {                     sale = Integer.parseInt(Utils.objectToString(salenum.getValue()));                 }                                  if(sale < minnum){ //校验判断                     type = 1;                 }             }else {                 type = 1;             }              }              public String getMessage() {             // 根据校验状态是成功还是失败,设置对应的返回信息             if(type == 0){                 return "恭喜你,校验成功";             }else{                 return "销量值不能小于最小基数";             }                      }         public int getType() {             // 返回校验状态             return type;         }          @Override       public void doFinish(Calculator arg0) throws Exception {           // TODO Auto-generated method stub                  }              }  
编译上述java类,将class文件复制到%FR_HOME%|WebReport\WEB_INF\classes\com\fr\demo文件夹下。
如上代码,定义了3个变量type、salenum、minnum,其中type是结果变量,其他两个变量则是通过报表填报属性>数据校验>自定义校验中传过来的属性名称,如下图,在数据校验中添加一个自定义校验,点击选择按钮选中VerifyJobDemo类,并添加2个属性,分别与java类中的2个变量对应,由于salenum变量为JobValue对象,故其对应的值应该为单元格(必须是单元格),minnum变量则是一般类型的变量:
注:如果继承自com.fr.data.VerifyJob.class接口类,那么模板填报属性-数据校验中的属性名称必须与java类中的变量名称保持一致。
  • 效果查看
填报预览模板,点击提交按钮,如下图:
3.2 方法二、
com.fr.data.TotalVerifyJob.class
通过该接口类编写的自定义校验类,通过Data参数(以二维表排列的所有提交数据)获取所有属性值,在类中逐条逐条对数据进行校验,并返回一个最终的校验结果。该接口类有以下方法:
doTotalJob(Data data> Calculator calculator)Data以二维表中的形式存储了自定义校验界面添加的属性对应的值,calculator可以获得当前报表、当前单元格;
getType()获取用户设置的标志位type的值;
getMessage()根据type类型设置返回信息。
编写TotalVerifyJobDemo类,集成自TotalVerifyJob类,对填报页面数据进行校验,如果销售总额小于2000,则提示“销量值不能小于最小基数”,否则提示“恭喜你,校验成功”。
完整代码如下:
package com.fr.demo;      import com.fr.base.Utils;      import com.fr.data.JobValue;   import com.fr.data.TotalVerifyJob;   import com.fr.script.Calculator;      public class TotalVerifyJobDemo extends TotalVerifyJob{       /*       * type : 必须要定义此私有变量,变量名可改,表示校验状态       * 0  表示校验成功,默认校验状态位为0       * 1  表示校验失败       */       private int type = 0;               protected void doTotalJob(Data data, Calculator calculator)        throws Exception { // @param data 以二维表排列的所有提交数据           int sale, min;           JobValue salenum, minnum;               int row = data.getRowCount(); // 获取一共多少行数据           for (int i = 0; i < row; i++) {  // 遍历每行,进行校验               salenum = (JobValue) data.getValueAt(i, 0);               sale = Integer.parseInt(Utils.objectToString(salenum.getValue()));                               minnum = (JobValue) data.getValueAt(i, 1);               min = Integer.parseInt(Utils.objectToString(minnum.getValue()));                              if(sale < min){ //校验判断                   type = 1;               }           }                    }          public String getMessage() {           // 根据校验状态是成功还是失败,设置对应的返回信息           if(type == 0){               return "恭喜你,校验成功";           }else{               return "销量值不能小于最小基数";           }       }          public int getType() {           // 返回校验状态           return type;       }      }  
编辑java文件,将class文件保存到%FR_HOME%|WebReport\WEB_INF\classes\com\fr\demo文件夹下。
不同于VerifyJob接口类中的方法,TotalVerifyJob接口是先将自定义校验中添加的所有属性值全部取出来,组成一个二维列表,存放在Data参数中,然后在类中一个一个校验,并且不论属性值的单元格对象还是一般类型数值,都必须先转换为JobValue对象,然后再将JobValue对象转换为实际的数据类型,故自定义校验中需要添加几个属性,那么java类中就需要定义几个JobValue对象。
如上代码,定义了5个变量type、salenum、minnum、sale、min,其中type是结果变量,salenum和minnum是JobValue对象,用来接收Data参数中存储的2个属性值,sale和min变量则是相应的具体数据类型,用来在校验时,存储转换之后的实际值,并进行校验。如下图,在数据校验中添加一个自定义校验,点击选择按钮选中TotalVerifyJobDemo类,并添加2个属性,属性名称不一定要与java类中JobValue对象保持一致:
注:不同于VerifyJob方法,这里的属性名称不一定要与java类中JobValue对象的名称一致,其是按照位置对应的,即自定义校验时,FR会将这两个属性值以二维列表形式存放在Data参数中,按照顺序取数,Data的第一列为第一个属性对应的值,如果属性值为单元格,则获取单元格扩展后的所有值,如果为固定值,则该列的所有行均为该值,行数由单元格扩展的行数确定。
  • 效果查看
如下图:

4. 总结编辑

自定义校验类有2个接口可以继承,VerifyJob接口类可定位到具体出错单元格,其是根据属性名称一条一条校验,故可定位到具体出错单元格,而TotalVerifyJob接口类不能定位到具体出错单元格,其是西先将所有属性值全部取出来存放到Data参数中,然后再通过Data参数进行比较,故无法定位到具体出错单元格位置。