概述
随着FineReport的发展,它提供的设计器和服务器应该能够满足您绝大部分的需求,完全实现零编码的软件开发,革命性地加快软件开发速度,提高软件稳定性。但是需求是千变万化的,而FineReport所包含的功能是报表行业中比较普遍的、典型的,也许某些个性化的功能通过FineReport软件无法实现。因此FineReport开放了能够进行二次开发的接口,来更好的满足您软件产品或项目中的个性化的需求。您可以根据该引擎API文档学习各类接口的使用方法,另外若您是一名程序员,且对FineReport报表深感兴趣,希望更深入地了解FineReport软件的内部原理,您也可以阅读该章节。
FineReport引擎API文档对如何定义类、编译类文件及JAVA开发平台使用等JAVA基础知识未作介绍,因此在您查看引擎API文档前请确保您有一定的JAVA基础。
目录
1. 程序数据源
2.1 简单程序数据集 2.2 带参程序数据集 2. 自定义函数
3.1 自定义函数
3.2 SubSection函数-Oracle查询参数个数限制 3.3 自定义函数生产UPC条形码 3. 导出api
注:另有报表调用的相关代码,如有需要可以另行下载。
程序数据集
简单程序数据集
FineReport报表的数据来源可以是数据库数据或是文本数据,并且还可以是其它任何类型的数据,因为FineReport是通过TableData接口来读取数据源的,而上述所有的数据来源都实现了该接口,因此用户只要实现了TableData接口,也就可以用自定义类型的数据源了(程序数据集),FineReport报表引擎就能够读取定义的数据源作为报表数据源使用。
TableData接口主要有5个方法,如下: //获取TableData的总列数 public int getColumnCount();
//获取TableData中第columnIndex列的列名 public String getColumnName(int columnIndex);
//判断是否存在第rowIndex行,这主要是用于处理超大数据时,完全遍历所有数据获取总行数相当困难,用这个方法来判断第rowIndex行是否存在,存在则可读取 public boolean hasRow(int rowIndex); //获取TableData的总行数 public int getRowCount();
//获取TableData中第columnIndex列,第rowIndex行的数据
public Object getValueAt(int rowIndex, int columnIndex); 使用程序数据集分为如下三个步骤:
在某些应用场景中,需要在程序中对数据进行处理后再作为报表的数据源使用,以下例子即为一个简单的不带参程序数据集ArrayTableData的使用过程,并以此简要说明程序数据集的使用方法。
1. 定义程序数据源
由之前的概述可知,程序数据集需要实现TableData接口,可以直接继承该接口,实现其5个方法,也可以从AbstractTableData扩展,因为AbstractTableData已经实现了默
认的hasRow(int rowIndex)方法。
该例中的程序数据集ArrayTableData就是直接从AbstractTableData扩展的,完整代码如下:
package com.fr.data;
import com.fr.data.AbstractTableData;
public class ArrayTableDataDemo extends AbstractTableData { //定义程序数据集的列名与数据保存位置 private String[] columnNames; private Object[][] rowData;
//实现构建函数,在构建函数中准备数据 public ArrayTableDataDemo(){
String[] columnNames ={\,\};
Object[][] datas = {{\,new Integer(15)},{\,new Integer(22)},{\,new Integer(99)}};
this.columnNames = columnNames; this.rowData = datas; }
//实现TableData的其他四个方法,因为AbstractTableData已经实现了hasRow方法 public int getColumnCount(){ return columnNames.length; }
public String getColumnName(int columnIndex){ return columnNames[columnIndex]; }
public int getRowCount(){ return rowData.length; }
public Object getValueAt(int rowIndex, int columnIndex){ return rowData[rowIndex][columnIndex];
} }
1.1 把上面代码复制到txt文档重命名为ArrayTableDataDemo.java
放到报表环境/WebReport/WEB-INF/classes/com/fr/data这个目录下
1.2 编译ArrayTableData.java生成ArrayTableData.class类
将生成的类文件拷贝到报表工程/WEB-INF/classes目录下。由于该类是在com. fr.data包中的,因此最终应该将该ArrayTableData.class放在
/WEB-INF/classes/com/fr/data下面。此时该程序数据源便定义好了。
2. 配置程序数据源 2.1 新建报表
在报表数据集中新建程序数据源,选择我们定义好的程序数据集,如下图 名字可以自定义,如student
3. 使用程序数据集
配置好程序数据源后便可以使用定义的student程序数据集了,与其他类型的数据集使用方法是相同的,可以通过拖拽方法实现单元格数据列绑定。如下图
带参程序数据集
在实际应用中,可能需要根据表名动态地改变数据源,比如在程序数据集中,通过传
进的表名参数,到数据库取出对应的表作为数据源。因为FineReport是通过TableData接口来读取数据源的,而上述所有的数据来源都实现了该接口,因此用户只要实现了
TableData接口,也就可以用自定义类型的数据源了(程序数据集),FineReport报表引擎就能够读取定义的数据源作为报表数据源使用。以下就对这种情况举例说明。
TableData接口主要有5个方法,如下: //获取TableData的总列数 public int getColumnCount();
//获取TableData中第columnIndex列的列名 public String getColumnName(int columnIndex);
//判断是否存在第rowIndex行,这主要是用于处理超大数据时,完全遍历所有数据获取总行数相当困难,用这个方法来判断第rowIndex行是否存在,存在则可读取 public boolean hasRow(int rowIndex); //获取TableData的总行数 public int getRowCount();
//获取TableData中第columnIndex列,第rowIndex行的数据 public Object getValueAt(int rowIndex, int columnIndex); 使用程序数据集分为如下三个步骤: ?定义程序数据源 ?配置程序数据源 ?使用程序数据集
1. 定义程序数据源
首先在构建函数中定义好所用的程序数据集表结构,通过参数获得表名;其次在初始化函数中准备数据并放入定义的表中;完整代码如下: package com.fr.data;
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.Statement; import java.util.ArrayList;
import java.util.logging.Level; import com.fr.base.FRContext;
import com.fr.data.AbstractTableData; import com.fr.report.parameter.Parameter;
public class ParamTableDataDemo extends AbstractTableData { // 列名数组,保存程序数据集所有列名 private String[] columnNames = null; // 定义程序数据集的列数量 private int columnNum = 10; // 保存查询表的实际列数量 private int colNum = 0; // 保存查询得到列值
private ArrayList valueList = null;
// 构造函数,定义表结构,该表有10个数据列,列名为column#0,column#1,。。。。。。column#9
public ParamTableDataDemo() { // 定义tableName参数
this.parameters = new Parameter[] { new Parameter(\) }; // 定义程序数据集列名
columnNames = new String[columnNum]; for (int i = 0; i < columnNum; i++) {
columnNames[i] = \ + String.valueOf(i); } }
// 实现其他四个方法
public int getColumnCount() { return columnNum; }
public String getColumnName(int columnIndex) { return columnNames[columnIndex]; }
public int getRowCount() { init();
return valueList.size(); }
public Object getValueAt(int rowIndex, int columnIndex) { init();
if (columnIndex >= colNum) {