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

目录:

1.概述编辑

1.1 问题描述

用户在做填报报表时,希望点击提交按钮并不是往数据库中填报数据,而是要获取到填报页面的数据进行进一步处理,这个该如何解决呢?

1.2 实现思路

在 报表填报属性  中介绍了报表填报属性有 2 种设置方式,一个是内置 SQL 直接绑定字段,往数据库中填报数据,另外一种是添加自定义事件,如果需要获取数据对数据进行进一步处理,则可选择添加自定义事件,下面详细介绍。

2.示例编辑

2.1 准备数据

新建数据查询数据集 ds1,SQL 语句为:SELECT studentno,name,grade FROM STSCORE where name <> ''

1607420921356618.png

2.2 设计填报表格

1)设计填报表格,将数据集相应字段拖到单元格中,A2 和 C2 单元格添加「数字控件」,B2 单元格添加「文本控件」,表格样式如下图所示:

Snag_29ec6364.png

2)C2 单元格设置为汇总求和,如下图所示:

Snag_29f2bbf7.png

3)点击「模板>报表填报属性」,新增一个自定义提交,点击编辑按钮,如下图所示:

1596178832950191.png

2.3 自定义提交类

2.3.1 方法一

1)在类里面定义几个 JobValue,每一个 JobValue 对应一个单元格,在报表填报属性中通过属性列表中将其与对应的单元格绑定起来,具体使用如  DemoSubmitJob1:

package com.fr.data;

import com.fr.script.Calculator;

public class DemoSubmitJob1 extends DefinedSubmitJob {
   /**
    * 当模板自定义事件增加的属性 名称与下面变量有对应时,则会自动赋值于此对应变量
    */
   public String getJobType(){
       return " ";
   }
   private JobValue studentno;   // JobValue 对应单元格
   private JobValue name;
   private JobValue grade;
   private boolean isPass;       // 非单元格,则对应具体类型值

   /**
    * 每一条记录执行一次此方法
    * 同一提交事件在一个处理事务内,此对象是唯一的
    */
   public void doJob(Calculator calculator) throws Exception {

       // JobValue 的 getValueState()方法获取此对应单元格的状态
       //单元格有六种状态:
       // 删除(JobValue.VALUE_STATE_DELETED)
       // 默认(JobValue.VALUE_STATE_DEFAULT)
       // 修改(JobValue.VALUE_STATE_CHANGED)
       // 插入(JobValue.VALUE_STATE_INSERT)
       // 修改删除(单元格修改值之后被删除JobValue.VALUE_STATE_CHANGED_AND_DELETED)
       // 插入修改(插入状态的单元格再被修改JobValue.VALUE_STATE_CHANGED_AND_INSERT)
       if (studentno.getState().checkChanged()) {
           // 此单元格的值在报表初始化后被修改过(包含修改和修改删除和修改插入三种状态)
       } else if (studentno.getState().checkInsert()) {
           // 此单元格是在报表初始化后新增的(包括插入和修改插入两种状态)
       } else if (studentno.getState().checkDeleted()) {
           // 此单元格所在的记录被执行了删除操作(包含删除和修改删除两种状态)
       } else if (studentno.getState().checkDefault()) {
           // 此单元格在报表初始化后没有变化
       }

       // 值获取
       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() 获取对象的值。

2)将 Java 代码拷贝到自定义函数编辑界面,点击「编译」按钮,显示编译成功后,点击「保存」按钮,如下图所示:

注:也可以将外部编译得到的 class 文件放到 %FR_HOME%\webapps\webroot\WEB-INF\classes 文件夹下,然后点击选择按钮引用 class 文件。

1596179070793852.gif

3)点击增加属性按钮,给提交事件添加 4 个属性,注意值的选择为「单元格」和「公式」,如下图所示:

1602663186176380.png

注1:属性名称跟类文件中定义的 JobValue 是一致的,必须保证「报表填报属性」处添加的属性名称与类文件中定义的名称保持一致。如果在类文件中对应参数类型不是 JobValue 的话,则必须与属性的数据类型保持一致。

注2:一般来说,为了便于维护,可以将 Java 类中的所有变量全部设为 JobValue 对象,不论报表填报属性中的属性类型是什么,均可以通过 GetValue 获取其值。

2.3.2 方法二

1)通过 doJob 的方法参数 Calculator 中的 Property_Value 属性, Property_Value 属性对应一个 map 对象,Map 中包含报表填报属性中所有属性名称以及它们对应的值,使用 map 中的 getValue() 方法获取属性值,即单元格,接着使用 JobValue 的 getValue() 方法获取单元格的值,具体使用如  DemoSubmitJob2:

package com.fr.data;
import com.fr.script.Calculator;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class DemoSubmitJob2 extends DefinedSubmitJob {
   /**
    * 每一条记录执行一次此方法
    * 同一提交事件在一个处理事务内,此对象是唯一的
    */
   public String getJobType(){
       return " ";
   }
   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()方法获取此对应单元格的状态
               //单元格有六种状态:
               // 删除(JobValue.VALUE_STATE_DELETED)
               // 默认(JobValue.VALUE_STATE_DEFAULT)
               // 修改(JobValue.VALUE_STATE_CHANGED)
               // 插入(JobValue.VALUE_STATE_INSERT)
               // 修改删除(单元格修改值之后被删除JobValue.VALUE_STATE_CHANGED_AND_DELETED)
               // 插入修改(插入状态的单元格再被修改JobValue.VALUE_STATE_CHANGED_AND_INSERT)
               if (ce.getState().checkChanged()) {
                   // 此单元格的值在报表初始化后被修改过(包含修改和修改删除和修改插入三种状态)
               } else if (ce.getState().checkInsert()) {
                   // 此单元格是在报表初始化后新增的(包括插入和修改插入两种状态)
               } else if (ce.getState().checkDeleted()) {
                   // 此单元格所在的记录被执行了删除操作(包含删除和修改删除两种状态)
               } else if (ce.getState().checkDefault()) {
                   // 此单元格在报表初始化后没有变化
               }
               System.out.print(ce.getValue());         // 通过 JobValue 的 getValue 方法获得单元格的值
           } else {
               // 非单元格,则对应具体类型值
               System.out.print(entry.getValue());
           }
       }
       System.out.println();
   }
}

2)将 Java 代码拷贝到自定义函数编辑界面,点击编译按钮,只有显示编译成功后,才能保存,如下图所示:

注:也可以将外部编译得到的 class 文件放到 %FR_HOME%\webapps\webroot\WEB-INF\classes 文件夹下,然后点击选择按钮引用 class 文件。

485E83F1-7D37-44D5-AEBA-7D0C947A9F9F.GIF

3)点击增加属性按钮,给提交事件添加 4 个属性,如下图所示:

image.png

注:方法二中是通过 Calculator 参数属性 PROPERTY_VALUE 来获取报表填报属性处的属性与属性值,再通过 JobValue 来得到单元格的值,在类文件中并不是一一对应的获取属性与属性值,而是通过 map 遍历来获取属性与属性值,所以在报表填报属性处增加属性时,属性名字可随意定义,但是后面的值如果是单元格的话,必须选择单元格类型。

2.3.3 方法三

1)自定义事件除了可继承自 DefinedSubmitJob 这个接口之外,还可以继承 TotalSubmitJob 接口,这两个接口的区别在于 DefinedSubmitJob 多次执行,即一行一行的获取模板中的数据,获取一行数据则执行一次自定义事件,而 TotalSubmitJob 接口只执行一次,即先获取到模板中所有的数据,然后在类里面循环,具体使用如 DemoTotalSubmitJob:

package com.fr.data;

import com.fr.script.Calculator;

public class DemoTotalSubmitJob extends TotalSubmitJob {
   /**
    * 同一提交事件,在一个提交事务内只执行一次
    *
    * @param data 以二维表排列的所有提交数据
    */
   public String getJobType() {
       return " ";
   }

   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()方法获取此对应单元格的状态
                   //单元格有六种状态:
                   // 删除(JobValue.VALUE_STATE_DELETED)
                   // 默认(JobValue.VALUE_STATE_DEFAULT)
                   // 修改(JobValue.VALUE_STATE_CHANGED)
                   // 插入(JobValue.VALUE_STATE_INSERT)
                   // 修改删除(单元格修改值之后被删除JobValue.VALUE_STATE_CHANGED_AND_DELETED)
                   // 插入修改(插入状态的单元格再被修改JobValue.VALUE_STATE_CHANGED_AND_INSERT)
                   if (ce.getState().checkChanged()) {
                       // 此单元格的值在报表初始化后被修改过(包含修改和修改删除和修改插入三种状态)
                   } else if (ce.getState().checkInsert()) {
                       // 此单元格是在报表初始化后新增的(包括插入和修改插入两种状态)
                   } else if (ce.getState().checkDeleted()) {
                       // 此单元格所在的记录被执行了删除操作(包含删除和修改删除两种状态)
                   } else if (ce.getState().checkDefault()) {
                       // 此单元格在报表初始化后没有变化
                   }
                   value = ce.getValue();               // 通过 JobValue 的 getValue 方法获得单元格的值
               }
               System.out.print(data.getColumnName(j) + " : " + value);
           }
           System.out.print("}");
           System.out.println();
       }
   }
}

2)将 Java 代码拷贝到自定义函数编辑界面,点击编译按钮,只有显示编译成功后,才能保存,如下图所示:

注:也可以将外部编译得到的 class 文件放到 %FR_HOME%\webapps\webroot\WEB-INF\classes 文件夹下,然后点击选择按钮引用 class 文件。

166495C9-819F-4DD9-8FB4-C23F2625AAA3.GIF

3)点击增加属性按钮,给提交事件添加 4 个属性,如下图所示:

image.png

注:方法三与方法二中的使用方式类似。在报表填报属性处增加属性时,属性名字可随意定义,但是后面的值如果是单元格的话,必须选择单元格类型。

2.4 效果预览

2.4.1 方法一

1)保存报表,选择「填报预览」,前端点击「提交」按钮,如下图所示:

1596181014246125.png

2)成功提交后,文件夹 %FR_HOME%\bin 下会生成文件 out.log,如下图所示:

1602662154468004.png

3)记事本打开 out.log,可以看到导出的填报信息,如下图所示:

1607421734566857.png

2.4.2 方法二

1)保存报表,选择「填报预览」,前端点击「提交」按钮,如下图所示:

1596181014246125.png

2)成功提交后,文件夹 %FR_HOME%\bin 下会生成文件 out.log,如下图所示:

1602662154468004.png

3)记事本打开 out.log,可以看到导出的填报信息,如下图所示:

1607421872649714.png

2.4.3 方法三

1)保存报表,选择「填报预览」,前端点击「提交」按钮,如下图所示:

1596181014246125.png

2)成功提交后,文件夹%FR_HOME%\bin下会生成文件out.log,如下图所示:

1602662154468004.png

3)记事本打开out.log,可以看到导出的填报信息,如下图所示:

1607421872230014.png

2.5 其他应用

自定义事件不仅可用于报表填报属性处,也可用于按钮控件中的提交事件,具体应用参见文档:上传下载文件插件

3.模板下载编辑

1)方法一

已完成模板可参见:%FR_HOME%\webapps\webroot\WEB-INF\reportlets\doc\Form\LineForm\填报自定义提交.cpt

点击下载模板:填报自定义提交.cpt

2)方法二

已完成模板可参见:%FR_HOME%\webapps\webroot\WEB-INF\reportlets\doc\Form\LineForm\填报自定义提交2.cpt

点击下载模板:填报自定义提交2.cpt

3)方法三

已完成模板可参见:%FR_HOME%\webapps\webroot\WEB-INF\reportlets\doc\Form\LineForm\填报自定义提交3.cpt

点击下载模板:填报自定义提交3.cpt