FineReport报表软件API源代码之程序数据集自定义函数和导出API.docx
《FineReport报表软件API源代码之程序数据集自定义函数和导出API.docx》由会员分享,可在线阅读,更多相关《FineReport报表软件API源代码之程序数据集自定义函数和导出API.docx(12页珍藏版)》请在冰点文库上搜索。
![FineReport报表软件API源代码之程序数据集自定义函数和导出API.docx](https://file1.bingdoc.com/fileroot1/2023-5/20/ea1e0be3-2006-446f-9318-44b352585f0c/ea1e0be3-2006-446f-9318-44b352585f0c1.gif)
FineReport报表软件API源代码之程序数据集自定义函数和导出API
FineReport报表软件API源代码之程序数据集、自定义函数和导出API
概述
随着FineReport的发展,它所提供的设计者和服务器应该能够满足您的大部分需求,完全实现零编码软件开发,革命性地加快软件开发并提高软件稳定性然而,需求是不断变化的,而FineReport中包含的功能在报告行业中是常见和典型的。
也许有些个性化功能无法通过FineReport软件实现因此,FineReport打开了一个界面,可用于二次开发,以更好地满足您的软件产品或项目的个性化需求。
您可以学习如何根据引擎的API文档使用各种接口。
此外,如果你是一名程序员,并且对FineReport报表非常感兴趣,如果你想更深入地了解FineReport软件的内部原理,你也可以阅读本章。
接口报告引擎API文档没有引入JAVA基础知识,如如何定义类、编译类文件和使用JAVA开发平台。
因此,在查看引擎应用编程接口文档之前,请确保您有一定的JAVA基础
1。
程序数据源
2.1简单程序数据集2.2带参数的程序数据集2。
自定义函数
3.1自定义函数
3.2子节函数-甲骨文查询参数限制3.3自定义函数生成UPC条形码3。
导出api
注意:
报表调用还有其他相关代码,如有必要可以单独下载
程序数据集
简单程序数据集
报表数据源可以是数据库数据或文本数据,也可以是任何其他类型的数据,因为FineReport通过TableData接口读取数据源,并且所有上述数据源都实现了该接口。
因此,只要用户实现了TableData接口,他们还可以使用自定义数据源(程序数据集)。
FineReport报表引擎可以读取已定义的数据源,并将其用作报表数据源对于
TableData接口,主要有五种方法,如下:
//获取TableData公共int中的列总数GetColumnCount();
//获取表数据中列索引列的列名,公共字符串列名(IntColumnDex);
//判断行索引行是否存在。
这主要用于处理超大数据。
很难完全遍历所有数据来获得总行数。
此方法用于判断行索引行是否存在。
如果存在,可以读取公共布尔散列行(内部行索引)。
//获取表数据公共intgetRowCount()的总数;
//获取表中列索引列和行索引行的数据数据
公共对象GetValue(IntRowIndex,IntrolinDex);程序数据集的使用分为以下三个步骤:
在某些应用场景中,数据需要在程序中进行处理,然后才能用作报告的数据源。
下面的例子是一个不带参数的数组表数据的简单使用过程,并简要说明了程序数据集的使用方法。
1。
程序数据源
的定义从前面的概述来看,程序数据集需要实现TableData接口,它可以直接继承来实现它的五个方法,或者从抽象表数据扩展而来,因为抽象表数据已经实现了被mur
识别的hasRow(introwIndex)方法
本例中的程序数据集ArrayTableData是从抽象表数据直接扩展而来的。
完整的代码如下:
packagecom.fr.data;
importcom.fr.data.AbstractTableData;
PUBLICCLaSSArrayTableDataDemoExtensions抽象表数据{//定义程序数据集的列名和数据存储位置私有字符串[]列名;私有对象[][]行数据;
//实现构建函数,并准备数据PUBLICArrayTableDataDemo(){
String[]列名={\,\};
对象[][]数据={{\,新整数(15)},{\,新整数(22)},{\,新整数(99)}};
this.ColumnNames=ColumnNames;this.rowData=数据;}
//实现了TableData的其他四个方法,因为抽象表数据已经实现了hasRow方法publicintGetColumnCount(){returnColumnNames.length;}
公共字符串getColumnName(内部列索引){返回列名[列索引];}
公共intgetRowCount(){返回rowData.length}
公共对象getValueAt(内部行索引,内部列索引){返回行数据[行索引][列索引];
}}
1.1将上述代码复制到txt文档中,并将其重命名为ArrayTableDataDemo.java
以报告环境/网络报告/网络-信息/类/COM/FR/数据此目录
1.2编译ArrayTableData.class以生成数组表数据。
类类
将生成的类文件复制到报告工程/网络-信息/类目录因为班级在学校里。
fr.datapackage,ArrayTableData.class最后应该放在
/Webb-INF/class/com/fr/data下。
此时,程序数据源被定义
2。
配置器数据源2.1新报表
在报表数据集中创建新的程序数据源,并选择我们定义的程序数据集。
下图的名称可以自定义。
例如,学生
3。
在用程序数据集
配置程序数据源之后,可以使用定义的学生程序数据集。
它与其他类型的数据集相同,单元格数据列绑定可以通过拖动来实现。
如下图所示
带参数程序数据集
在实际应用中,可能需要根据表名动态改变数据源。
例如,在程序数据集中,通过传递表名参数
,从数据库中提取相应的表作为数据源因为FineReport通过TableData接口读取数据源,并且上述所有数据源都实现了该接口,所以用户也可以使用自定义数据源(程序数据集),只要他们实现了
TableData接口,并且FineReport报表引擎可以将定义的数据源读取为报表数据源下面是这种情况的一个例子对于
TableData接口,主要有五种方法,如下:
//获取TableData公共int中的列总数GetColumnCount();
//获取表数据中列索引列的列名,公共字符串列名(IntColumnDex);
//判断行索引行是否存在。
这主要用于处理超大数据。
很难完全遍历所有数据来获得总行数。
此方法用于判断行索引行是否存在。
如果存在,可以读取公共布尔散列行(内部行索引)。
//获取表数据公共intgetRowCount()的总数;
//获取TableDatapublicobjectgetvaluat(introwindex,intcolumnindex)中的columnIndex列和rowIndex行的数据;使用程序数据集分为以下三个步骤:
定义程序数据源?
配置器数据源?
使用程序数据集
1。
定义程序数据源
首先定义在构建函数中使用的程序数据集的表结构,并通过参数获得表名;其次,在初始化函数中准备数据,并将其放入定义的表中。
完整的代码如下:
packagecom.fr.data;
导入Java.SQL.connection;导入java.sql.DriverManager。
导入Java.SQL.ResultSet;
importJava.SQL.ResultSetMetadata;导入语句;导入java.util.ArrayList。
导入Java.util.logging.level;导入com.fr.base.FRContext。
importcom.fr.data.AbstractTableData;导入参数;
publicsclassparamtabledatademandextensionsabstracttabledata{//列名数组,它保存程序数据集privatestring[]columnnames=null的所有列名;//定义程序数据集中的列数私有int列数=10;//保存查询表中私有int列数=0的实际列数;//保存从查询中获得的列值
privateArrayListvaluelist=null;
//构造函数,它定义了一个表的结构,该表有10个数据列,分别命名为列#0、列#1,列#9
publicparameterdatademand(){//定义了表名参数
this.parameters=newparameter[]{newparameter(\)};//定义程序数据集列名
列名=新闻字符串[列号];对于(intI=0;I列名[i]=\+字符串值(I);}}
//实现其他四个方法
publicintgetcolumncount(){returncolumnum;}
公共字符串getColumnName(内部列索引){返回列名[列索引];}
publicintGetRowCount(){init();
返回值LiST.size();}
公共对象getValueAt(introwIndex,intColumnIndex){init();
if(ColumnIndex>=ColNum){
返回null}
返回((对象[])值列表.获取(行索引))[列索引];}
//准备数据
publicvoid(){
//确保if(值列表!
=null){return;}
//保存的数据库表名
stringtablename=参数[0]。
getvalue()。
tostring();//构造SQL语句并打印出
字符串。
FRContext.getLogger()。
日志(级别。
信息,
\+SQL);//保存获得的结果集
值列表=新数组列表();
//数据库连接将在下面建立。
查询连接连接=此。
GetConnection(),根据刚才的SQL语句。
尝试{
语句stmt=conn.CreateStatement();结果集RS=stmt.ExecuteQuery(SQL);//获取记录的详细信息,然后获取列总数
ResultSetMetadatarsmd=RS.GetMetadata();colNum=rsmd.GetColumnCount();//用对象
对象[保存数据]对象数组=空;而(rs.next()){
objArray=新对象[列号];对于(intI=0;iObjarray[I]=RS.GetObject(I+1);}
//将该行数据值列表添加到值列表。
}
//发布数据库资源RS.close();stmt.close();conn.close();
//打印从frcontext.getlogger()获取的数据行的总数。
日志(level.info,
\+ValueList.size()+\);}捕获(异常e){e.PrintStackTrace();}}
//获取数据库连接驱动程序名称和url可以由公共连接getconnection()替换{
stringdrivername=\;字符串url=\(*。
MDB)};DBQ=C:
\\\\FineReport6.5\\\\WebReport\\\\FrDemo.MDB\;字符串用户名=\;字符串密码=\;连接con=空;请尝试{
Class.forName(驱动名称);
con=Drivermanager.GetConnection(URL、用户名、密码);}捕获(异常e){e.PrintStackTrace();返回null}
返回con}
//发布一些资源。
因为可能会有重复的调用,所以需要释放值列表来释放最后一个查询的结果。
公共无效释放()引发异常{super。
发布();this.valueList=null}}
1.1将上述代码复制到txt文档中,并将其重命名为ParamTableDataDemo.java
到报告项目\\网络报告\\网络-信息\\类\\COM\\演示
1.2在此目录下编译ParamTableDataDemo.java
,将生成的参数表数据演示类文件复制到报告项目
/网络-信息/类目录因为这个类在com.fr.data包中,所以最终应该放在/Webb-INF/class/com/fr/data下。
此时,程序数据源被定义
2。
配置程序数据源
创建新报告
在报告数据集中创建新的程序数据源,并选择我们定义的程序数据集。
下图的名称可以自定义。
例如,divtable
3。
在用程序数据集
配置程序数据源之后,可以使用定义的可分程序数据集。
选择数据集并单击预览
按钮。
也就是说,您可以输入表名来动态获取相应的数据表并制作模板。
从下图
中可以看出,我们已经将stscore表中的数据提取到程序数据集表中。
像其他类型的数据集一样,我们可以通过拖动来实现单元格数据列绑定。
自定义函数
函数定义规则
FineReport提供了大量独立的函数,足以满足用户在正常情况下的报表制作需求。
然而,在某些特殊领域,可能需要一些特殊功能。
在这种情况下,FineReport提供了一种定制的功能机制。
用户可以根据自己的业务需求定义一些功能,但这些功能必须符合FineReport功能定义规则。
接口报告函数定义规则:
函数名(段,段,...),其中函数名是函数名,Para是参数
函数原理
在FineReport中,每个函数被定义为一个类。
这个类必须实现函数接口。
在操作过程中,首先通过反映函数名来获得这个类,然后调用它的run(Object[]agrs)方法。
让我们以SUM为例packagecom.fr.report.script;
importcom.fr.report.script.core.Farray;导入com.fr.report.script.core.FuncTionHelper;
公共类SUM扩展标准函数{公共对象运行(对象[)参数){双结果=0;
(intI=0;结果+=解析对象(参数[I));}
返回FuncTionHelper.ParsePrimitiveDouble(结果);
}
私有双解析对象(Objectobj){if(objinstanceofNumber){
返回((Number)obj)。
doublevalue();}否则,如果(布尔的对象实例){
返回((布尔)对象)。
布尔值()?
1:
0;}否则if(objinstanceofFArray){FArray数组=(FarRay)obj;双总和=0;
(intI=0;isum+=parseObject(数组元素(I));}
返回总和;}否则,如果(obj!
=null){尝试{
返回Double.ParseDouble(obj.ToString());}catch(NumberFormatExceptionexp){返回0;}}
返回0;}}程序可以看到
。
SUM类用于计算SUM函数。
它继承了NormalFunction类,NormalFunction实现了函数接口。
当操作一个函数时,首先根据函数名获得操作该函数的类,如SUM(2,4,真)。
该函数首先根据函数名获取SUM类,然后调用SUM类的run(对象[]args)方法。
SUM函数的参数存储在参数中,可以从参数中获取参数进行运算如果执行结果是SUM(2,4,真)=2+4+1=7
自定义函数使用步骤
自定义函数编译自定义函数注册自定义函数使用自定义函数
自定义函数使用分为四个步骤,如下:
简单自定义函数
下面用一个简单的自定义函数例子来说明使用自定义函数的四个步骤我们定义了一个函数STRINGCAT,它的功能是以字符串的形式连接所有的参数。
stringcat函数的使用规则是STRINGCAT(段,段,段...);其中,Para是函数的参数,数量不限。
1。
自定义函数
的定义从概述中可以看出,NormalFunction实现了这个接口,所以STRINGCAT可以直接继承NormalFunction类。
完整的代码如下:
Packagecom.fr.demo;
importcom.fr.report.script.NormaLFunction;
公共类stringcat扩展标准函数{公共对象运行(对象[)参数){字符串结果=\;对象段;
(intI=0;i返回结果;}
}描述:
当
使用函数STRINGCAT(Para,Para,Para…)时,它获得根据函数名操作函数的STRINGCAT,将参数传递给类中的args对象数组,并执行类的run函数
,在run函数中,传入的参数以字符串的形式连接并返回最后一个字符串
2。
编译自定义函数
放置编译后的STRINGCAT。
在FineReport安装目录下的类目录下的类。
因为STRINGCAT.JAVA属于演示包,STRINGCAT。
类需要放在类\\com\\fr\\演示目录下
3。
注册自定义函数
生成该函数的类需要在设计器中注册后才能使用该函数打开服务器|函数管理器,选择刚刚定义的STRINGCAT类。
下图
函数名可以自定义。
例如,它在这里被定义为stringcat。
同时,您可以添加该功能的描述,如上图所示。
4.向自定义函数
注册自定义函数后,您可以在制作报告时直接使用它。
使用方法与内置函数相同。
4.1新报告
4.2定义了两个报告参数para1和para2,类型分别为字符串类型和整形。
默认值分别是空字符
string和0
。
在空白报表的任何单元格中写入公式:
=Stringcat($para1。
$para2)(注意:
在编写公式时,添加$,表示这是使用的参数)
单击预览弹出一个对话框来填充参数。
将参数值写为
后,可以看到结果
,表明STRINGCAT公式可以正常使用。
子部分函数
的甲骨文查询参数限制如果有一个参数查询语句:
SELECT*Fromstscore,其中stdnoin(${studentno})
实际上studentno可能是根据其他条件查询的结果列表,可能超过1000个学生编号。
如果最终结果为
,请从stscore中选择*其中stdnoin(10001,10002,10003,10004,10005,10006,10007,10008,10009,10010,10011,10012,10013,...,10989,10990,10991,10992,10993,10994,10995,10996,10997,10998,10999,11000,11001)
直接执行上述语句。
由于studentno参数的数量超过1000,数据库端将报告ORA-01795错误。
下图
如何解决问题?
此时,如果studentno参数被分成多个段,例如500个单元,则11001个参数值被分成3个部分以形成3个查询条件,这个问题可以被避免
变为从st分数中选择*其中stdnoin(10001,10002,...,10500)或stdnoin(10501,10502,...,11000)或stdnoin(11001)
fineport没有实现此功能的内置函数。
在这种情况下,我们可以定制一个SubmIt分组函数
。
该函数的使用规则是:
SubRate(para)
para参数为字符串形式。
该函数将字符串参数划分为500个单位,并返回划分后形成的数组完整的代码如下:
packagecom.fr.demo;
importcom.fr.report.script.NormaLFunction;importcom.fr.report.script.core.Farray;
publicclasssuppleextensionsnormalfunction{publicobjectrun(Object[)args){
//获取第一个对象,即获取传入的参数Objectpara=args[0];
字符串parastr=para.tostring();//因为它是一个检查参数,所以应该删除\和\
if前后的参数(parastr.startswith(\parastr=parastr.substring(1,parastr.length()-1);}
//将字符串转换为\分区数组stringtest[]=parastr.split(\intlength=test.length);intloopnum=len/500;if(lenP0!
=0){loopnum+=1;};
//返回的值是一个数组,需要定义为内部类型FarrAYFarrAYresult=newFarrAY();字符串字符串=\intk=1;
(intI=0;i