一种自定义报表的生成管理方法及系统的制作方法

文档序号:6587448阅读:327来源:国知局
专利名称:一种自定义报表的生成管理方法及系统的制作方法
技术领域
本发明涉及计算机领域,更具体地说,涉及一种自定义报表的生成管理方法及系统。
背景技术
目前国内各行业的各种应用系统对二次开发的要求越来越高。其中很多系统都明确指出 了软件系统要有自定义报表系统,可由用户自行设计、定义报表。 一些软件产品中也实现了 自定义报表模块,但却不是完全意义上的自定义报表,只是提供了一些标准的报表样式,操 作员可在提供的报表样式上选择一些系统提供的数据项,用来生成报表。这种报表有几个缺 陷扩展性差,如果需要的数据项报表模块未提供或如果所需的数据展示样式有所改变,而 系统提供的已有样式不支持,就无法生成所需报表;也不能支持完全的自定义査询条件定义 。另有一些软件产品,如iR印ort,Birt等,这些报表工具提供了自定义的报表设计器,可以 在报表里使用SQL査询、Java Bean。但这些报表工具只是一个报表生成工具,运行时要靠外 部程序来调用并提供参数或数据才能生成报表文件,本身并不是一个报表运行平台,不能进 行报表发布,生成自定义査询条件。

发明内容
本发明要解决的技术问题在于,针对现有技术的上述扩展性差、不支持自定义査询条件 的缺陷,提供一种扩展性好、支持自定义査询条件的一种自定义报表的生成管理方法及系统
本发明解决其技术问题所采用的技术方案是构造一种自定义报表生成管理方法,用于 浏览器/服务器结构,包括如下步骤
A) 在浏览器上调用服务器上运用程序,显示服务器上所有报表清单的报表页面, 选择其中一个报表;
B) 服务器生成所选报表,传送到所述浏览器。 在本发明所述的自定义报表生成管理方法中,还包括在所述服务器上建立报表文件,其
包括
M)使用Excel生成多个存储在服务器内的报表文件。在本发明所述的自定义报表生成管理方法中,所述步骤M)中进一步包括如下步骤 Ml)使用Excel得到报表模板,生成模板文件;
M2)将所述模板文件分区段,并定义所述模板文件中的每个区段,生成样式文件 M3)定义上述各区段中的数据,生成定义文件;
M4)将上述文件传送到服务器的报表目录中指定位置,得到一个报表文件。 在本发明所述的自定义报表生成管理方法中,所述步骤M2)中所述定义区段包括定义 该区段中放置的数据项、所述数据项的位置以及所述数据的显示格式。
在本发明所述的自定义报表生成管理方法中,所述步骤M3)中所述定义所述区段中的数 据包括数据的来源、数据査询方式、数据査询条件、数据计算以及数据填充。
在本发明所述的自定义报表生成管理方法中,所述步骤M4)进一步包括如下步骤 M41)将所述模板文件、样式文件和定义文件传送到所述服务器指定目录中; M42)刷新报表页面,得到上述文件所生成的报表之清单。 在本发明所述的自定义报表生成管理方法中,所述步骤B)进一步包括 Bl)产生该报表査询条件输入页面;
B2)依据所述査询条件输入页面的内容,査询数据,生成报表; B3)输出生成的报表到所述浏览器。
本发明还揭示了一种自定义报表生成管理系统,用于浏览器/服务器架构,所述服务器
上包括
报表运行引擎用于解析报表定义文件,査询报表需要的数据以及生成报表; 报表管理平台用于发布、管理各类报表;
报表运行平台用于显示在所述管理平台上发布的报表清单,当所述报表清单中 的一个被选中时,调用所述运行引擎,査找、生成报表,并输出。
在本发明所述的系统中,所述报表运行引擎进一步包括用于在所述报表清单中一个报表 被选拔中时产生査询条件输入页面的査询条件输入页面产生单元。
在本发明所述的系统中,所述报表管理平台包括用于存放所述报表定义文件的报表定 义文件存放目录、用于存放所述报表模板文件和样式文件的报表模板文件和样式文件存放目 录、用于存放于报表绑定数据源的自定义数据源绑定报表存放目录、用于存放申明文件的自 定义函数申明文件存放目录以及用于存放所述査询页面的自定义査询条件页面存放目录。
实施本发明的自定义报表的生成管理方法及系统,具有以下有益效果由于每个报表文件的模板中包括模板文件、样式文件和定义文件,因此,生成报表时报表的格式和报表的数 据是分开生成后在组合的。故其扩展性较好、支持自定义査询条件。


图l是本发明自定义报表的生成管理方法及系统实施例中报表的生成流程图;
图2是所述实施例中报表清单生成流程图3是所述实施例中系统结构示意图4是所述实施例中报表管理平台中目录结构示意图。
具体实施例方式
下面将结合附图对本发明实施例作进一步说明。
如图1所示,在本发明自定义报表的生成管理方法及系统实施例中,其报表生成方法包
括如下步骤
步骤Sll显示报表清单,并选中其中一个在本步骤中,在浏览器上调用服务器上运用 程序,显示服务器上所有报表清单的报表页面,并选中其中一个报表。
步骤S12产生报表査询输入页面服务器收到浏览器提交的被选中报表后,在上述浏览 器上产生一个报表査询输入页面,该査询输入页面的作用是用来进一步定义该报表的数据来 源、数据格式等与报表中数据相关的事项。
步骤S13依据所述査询输入页面内容,査询数据,生成报表由于报表的模式和报表中 的数据都已被定义,所以,在本步骤中,就是将上述各部分组织起来,生成报表。
步骤S14输出所生成的报表在本步骤中,将上述生成的报表传送到所述浏览器上显示 出来。
上面的步骤可以描述如下点击一个报表,按照配置的输入参数生成输入査询条件的页
面,输入指定的査询条件并提交,报表引擎査询数据,生成报表文件并以Html格式输出到浏 览器显示出来。也可输出为Excel文件。根据定义中的输入参数生成输入査询条件的页面; 输入査询条件,提交査询;从提交的表单中获得査询参数的输入值;将査询条件送给各个数 据源执行査询;将査询返回的结果放在数据对象集合中;对数据对象集合中的数据进行再计 算、统计等处理;生成ExcelR印ort对象,将数据对象集合中的数据输出到ExcelR印ort对象 ,生成报表文件。
在图1中,我们直接调用了报表清单,但是,该报表清单同样是需要在事先构建的。图2示出了报表清单的构造流程,在图2中,包括如下步骤
步骤S21使用Excel得到报表模板,生成模板文件在本步骤中,按照需求,用Excel画 报表模板。生成一个Excel格式的模板文件(xls文件)。
步骤S22生成上述报表模板的样式文件将模板按以上方式分好各个区段,定好每个区 段中要放置的数据项。以及数据项的位置,显示格式等。将这些配置信息记录在样式文件中 。生成一个样式文件(xml文件)。
步骤S23生成上述报表模板的定义文件设计报表的数据来源,如何査询,査询条件。 原始査询数据是否需要再计算处理。数据填充(与样式文件中定义的数据项相匹配)。将这 些配置信息记录在报表定义文件中。生成一个定义文件(xml文件)。
步骤S24存储上述文件到指定目录,得到报表文件在本步骤中,将上述三个文件上传 到服务器指定目录中,即可得到报表文件。
步骤S25刷新报表页面,得到报表清单在报表页面里刷新列表,就可以看到新提交的 报表。
事先多次重复上述步骤S21到S25,即可配置多个报表模板,当然,如果临时需要增加一 个报表模板,也可以单独执行上述步骤S21到S25。
在本实施例中,样式文件中定义了报表的输入参数,数据源,数据计算方法,数据输出 等;而定义文件是一个标准格式的XML文件,其格式符合XML文件格式的要求。以UTF-8作为 编码格式。
本实施例中还揭示了一种自定义报表生成管理系统,该系统用于浏览器/服务器架构, 所述服务器上包括用于解析报表定义文件,査询报表需要的数据以及生成报表的报表运行 引擎l、用于发布、管理各类报表的报表管理平台3和用于显示在所述管理平台上发布的报表 清单、当所述报表清单中的一个被选中时,调用所述报表运行引擎l去査找、生成、输出报 表的报表运行平台2。上述报表运行引擎l、报表运行平台2和报表管理平台3之间的结构如图 3所示。其中,所述报表运行引擎l进一步包括用于在所述报表清单中一个报表被选拔中时产 生査询条件输入页面的査询条件输入页面产生单元。
如上所述,报表管理平台3用于发布管理各类报表,其实质上是对这些报表的目录进行 管理,如图4所示,报表管理平台3中得目录包括用于存放所述报表定义文件的报表定义文 件存放目录31 、用于存放所述报表模板文件和样式文件的报表模板文件和样式文件存放目录 32、用于存放于报表绑定数据源的自定义数据源绑定报表存放目录33、用于存放申明文件的 自定义函数申明文件存放目录34以及用于存放所述査询页面的自定义査询条件页面存放目录35。
如前所述,在本实施例中,系统启动,加载自定义函数声明文件,加载字典表定义、数 据源定义等;当一个自定义报表名称被选中时,系统启动自定义报表引擎(Engine)处理, 其过程如下首先根据报表定义文件构造一个报表定义对象(R印c)rtDefine对象),然后根 据该定义对象构造一个自定义报表处理引擎(Engine)类实例;从
R印ortDefine. inputParameters中可得知为该报表定义的自定义査询条件,为每一个査询条 件生成对应的査询条件输入控件。最后生成输入各个査询条件的页面。输入完査询条件后提 交时,系统按照査询条件中定义的检验方法对输入值进行校验,校验成功才可以提交査询。 提交査询之后,系统处理提交的査询条件,将所有的参数输入值放入Engine. inputData中; 并逐个处理R印ortDefine中的数据源定义对于SQL数据源,处理SQL中的嵌入式表达式,得 到目标SQL语句,执行査询,得到査询结果,将査询结果DataSet放入Engine. data中;对于 Java数据源,通过调用自定义函数,执行一个Java方法。将该方法返回的数据对象放入 Engine, data中;对于DSF数据源,首先构造一个DSF对象,然后在该对象上执行査询,将返 回的DataSet对象放入Engine. data中。在处理完上述数据源定义后根据R印ortDef ine中 .calData部分的定义,Engine, data中存放的数据对象进行再计算,比方说产生一些统计数 据等。可修改已有对象中的数据,也可产生新数据。新输入一般存入一个新的map中。当上 述数据再计算完成后,根据报表样式文件构造一个ExcelEngine对象,然后按照 R印ortDefine. segmentDatafile中对各区段的数据项定义输出数据至UExcelEngine对象;如 果绑定整个区段到一个数据对象上的,将数据对象从Engine. data中取出来,直接提交给 ExcelEngine对象,生成报表的相应部分;如果区段数据项为逐个配置的,首先构造一个新 的map,调用自定义函数和嵌入式表达式处理引擎,对数据项配置公式进行计算,将数据项 名称和计算结果放入map,该区段的全部数据项都处理完后,将整个map提交给ExcelEngine 对象,生成报表的相应部分。至此,报表生成完毕。
如果需要按Html样式将报表内容显示在客户浏览器上,那么调用ExcelEngine的e邓ort 方法,得到Html格式的报表内容,然后将Html内容写入到response,最终显示在客户浏览器 上。 一般来说,报表内容应显示在独立的frame里;如果需要生成Excel文件供客户下载到本 机,那么调用ExcelEngine的export方法,得到byte[]格式的Excel文件内容,然后将数据直 接写入response,客户浏览器就会提示下载或打开Excel文件;如果需要在服务器端生成 Excel文件,可调用ExcelEngine.write方法,将报表内容写入到Excel格式的文件中。至此 ,报表输出到客户端。上面说过,定义文件是一个标准格式的XML文件,其格式符合XML文件格式的要求。以 UTF-8作为编码格式。本实施例中的定义文件如下 普通明细表—SQL数据源—操作员清单.xml 〈?xml version=〃l.0〃 encoding=〃UTF-8〃 ?〉 〈r印ortdef ine〉 〈r印ort-def ine name = 〃操作员清单" type = 〃grid〃
stylefile薩e = 〃DataSet普通明细表—操作员清单—style, xml〃 /〉
〈input-parameters〉 〈item
no = 〃1〃
name = "s—gdj"
displaytext = 〃所属供电局
datatype = 〃c〃
allowignore = "false"
min = 〃〃
max = "" /〉 /input-parameters)
〈datasource〉 〈sql name = 〃czy〃
sql = 'select a.氺,b. s—itemvalue as s—gdj—text, c. s—mc as s—js—text
from czy a,pub—dictitem b,js c
where a. s—gdj = b. s—itemid and b. n—typeid = 7
and a. s—jsbh = c. s—jsbhorder by a. s—czybh'
Zdatasource〉
〈caldata〉 〈/caldata〉
segment-data〉 〈title bind = 〃false〃 〉
〈item name = 〃title〃 formula = ,getlnput (e,〃s—gdj. text〃), / 〈item name = 〃printdate〃 formula = ' today()' /〉 〈/title〉
〈body bind = 〃true〃 type = 〃dataset〃 source = 〃czy〃 /
/segment-data〉
〈remark〉xml文本中,小于-< 大于-> 双引号-" 单引号
'〈/remark〉
〈/reportdefine〉
该文件就是一个标准格式的XML文件,格式符合XML文件格式的要求。以UTF-8作为编码 格式。
注意在定义节点属性时,属性内容必须符合XML文件的格式要求。其中的几个特殊字 符应使用转义符。小于(〈)-< 大于(>)-> 双引号(")-"单引号(')-
fe邻os;
〈和 > 符号必须使用转义符。
如果属性定义是以双引号开头的,那么属性内容里可使用单引号,但双引号必须使用转 义符。
如果属性定义是以单引号开头的,那么属性内容里可使用双引号,但单引号必须使用转 义符。
在本实施例的定义文件中,根节点的名称为〈r印ortdefine〉, 〈r印ortdefine〉的第一个 子结点是〈r印ort-define〉,该节点是对整个报表的定义,有以下属性 〈report-define name = 〃操作员清单" type = 〃grid〃
stylefile薩e = 〃DataSet普通明细表—操作员清单—style, xml〃 /> 在上面描述的属性中,name :报表名称,String,运行时如果输出Excel文件,则 Excel文件名就是这个名字。
type : 报表类另J, Sting, 可选值card/grid/group card -卡片报表,单记录, 一个表体 grid -明细报表, 一个表头、表尾,多个明细区
group -分组报表, 一个表头、表尾,多个分组。每个分组里可以有一个分组头、分 组尾,多个明细区。
stylefilename :该报表所使用的样式文件名,String,注意只有文件名 ,没有路径,路径定义在全局参数里。
在本实施例的定义文件中,输入参数定义在〈input-parameters〉段里。这些参数可以是 简单输入参数、映射到数据源字段上的输入参数、复杂输入参数以及自定义査询条件页面。 如果报表不需要输入参数,〈input-parameters〉段可以没有子结点。 当这些参数是简单输入参数时,其代码如下 〈input-parameters〉 〈item no = 〃1〃 name = "s—gdj"show = "true" datatype = 〃c〃 allowignore = "false" min = 〃〃 max ="" initralue = "0001,, /〉 〈/input-parameters〉 每一个输入参数是一个Item项。其中
no :该输入参数的序号,int, >=1,不能省略 name :该输入参数的名称,String,不能省略 displaytext :该输入参数的标签。String,该标签运行时显示在输入控件的左边 。如果设置了mapping属性,可使用字段的中文名做标签,可省略。
show :是否显示该输入参数。Boolean。默认为true。如果设置为false,则程序 运行时只输出一个名为name的〈hidden〉对象,但不显示该输入参数。可在程序中设置值。 show = false时,其他mapping属性,render属性都不再起作用。
datatype :该输入参数的数据类型,String,可选值为c/n/d,即字符型/数字 型/日期时间型。默认为字符型。参数为简单输入参数时,不可省略。
allowignore :该输入参数是否可忽略,Boolean, " true" /" false",默认为" true"。如果该参数定义为false,则运行时必须输入该参数査询才可提交。
min :允许输入的最小值,String。数据类型为数字型或日期型时起作用。如果不为 空,则输入完该参数提交査询时会进行最小值检査。如果不需要检査,则为空。
max :允许输入的最大值,String。数据类型为数字型或日期型时起作用。如果不为 空,则输入完该参数提交査询时会进行最大值检査。如果不需要检査,则为空。
initvalue :初始值。String,可为空。运行时该值会显示在输入控件中作为默认 值。Initvalue可使用嵌入式表达式。如initvalue =
'[%=getSessionAttr(〃GDJBH—String〃)%]'运行时将会以当前登录操作员所在的供电局编号 作为初始值。关于嵌入式表达式,将在后续章节介绍。
以上定义了一个最基本的输入参数。运行时査询页面会显示一个文本框用来手动输入供 电局编号。并且不能为空。如果需要使用其他方式输入参数,如使用下拉框来显示可选供电局,或者使用 dtpicker来显示一个日期,那么可使用映射到数据源上的某个字段的配置信息来生成输入参 数(关于数据源的含义请参阅相关文档),其代码如下 〈item no= 〃1〃 name = "s—gdj" display text = 〃所属供电局" mapping = 〃unireport—inputparameter.s—gdj〃 allowignore = 〃false〃 initvalue = "0001" />
其中,mapping :映射到某个数据源对象的某个字段上。String。格式为数据源对 象名称.字段名称。比如说,系统数据源unir印ort—inputparameter中定义了一个名为 s—gdj的字段,那么运行时就会生成一个不可编辑的下拉框,然后以字典表"供电局"中的 项目来填充该下拉框。
映射到数据源字段上的输入参数可表现为文本框,可编辑的下拉框,不可编辑的下 拉框,checkbox, DTPicker,按钮等各种样式。并且可以设置最大值最小值等条件。
对某些特别复杂的输入参数,如输入供电局时,希望输入控件为一个〈hidden〉记录供电 局编号,然后再显示一个不可编辑的文本框显示供电局名称,然后旁边再显示一个选择按钮 。按下选择按钮弹出一个选择供电局的窗口,选择了一个供电局之后,将选择供电局的编号 记录在〈hidden〉中,将选择供电局的名称显示在文本框中。这种复杂的情况,可使用 render方法渲染出一个特殊的输入控件。其代码如下 〈item no= 〃1〃 name = "s—gdj" show = 〃true〃 displaytext = 〃供电局〃 render = "Render—Gdj (' s—gd j')" initvalue = ' 00011园区供电局' />
其中,render :定义渲染方法。String。这里渲染方法是指程序运行时在标签右边先生成一个名为div—s—gdj的层,内容为空,然后在页面的body—onload事件里再调用JS脚 本中相应的渲染对象生成div—s—gdj的内容。如上生成文本框和按钮,并响应按钮按下事件
如上,事先在一个名为userfunction. js文件中定义了Render—Gdj这渲染对象。代码如

var Render—Gdj = Class, create (); Render—Gdj. prototype-{
id:〃〃,
text: 〃〃,
initialize:f皿ction(id) { this, id = id; this, text = id + 〃.text〃;
toString:function 0 { return 〃〈i叩ut type=, hidden' id=, 〃 + this, id + 〃' name=, 〃 + this, id
〃'〉〃 +
〃〈i叩ut type = 'text' id=, 〃 + this, text + 〃' name二'〃 + this, text + class=' input—80width' readonly〉〃 +
〃〈i叩ut type二' button' value二' V title二'选择供电局'class二' button' style='width:15'onclick='javascript:render—〃 + this, id + 〃.onclick 0 ;'〉"
onclick:f皿ctioiiO { var ret = pub—select—record(
〃请选择一个供电局",
〃供电局编号I 10 I cT供电局名称I 20 I c〃,
"select s—itemid, s—itemvalue from pub—dictitem where n—typeid = 7 order by s—itemid〃);
if (ret == null) return;$ (this. id), value = ret[O]; $(this.text).value = ret[l];
render:function(div){ if(div == null || div == undefined){
$(〃div—〃 + this. id). i匿r匿L = this. toString(); }else{
$(div).imierHTMl = this. toString();
setValue:function(value){ if(value == null || value == return; var ss = value, split ('T); $ (this, id). value = ss[O]; if(ss.length > 1) { $(this, text).value = ss[l];
运行时,査询条件页面会生成一个名为render—s—gdj的JS对象,然后调用 render—s—gdj. render ()方法生成div—s—gdj的内容。通过使用渲染对象,可生成任何复杂的 査询条件输入框。
对于特别复杂的査询条件。如果无法使用以上方法生成,那操作员也可自定义査询条 件的页面,保存为html文件或jsp文件。然后将文件上传到指定目录中,并在 〈input-parameters〉节点里添加属性searchpage指明该报表使用一个自定义的査询页面。 如
〈input-parameters searchpage二" /unireport—searchpage/operator—list, jsp
指定了自定义的査询页面后,无需再配置各个输入参数。自定义配置文件一般存放在一个虚拟目录中。
此外,每个报表都要定义数据源。 一个报表中可以有一个或多个数据源。系统运行时 ,根据数据参数,进行查询,获取数据。获取的数据存储在数据对象集合中。在本实施例中 ,数据源定义在〈datasource〉段里。如以下数据源定义 〈datasource〉 〈sql name = "dlsd"
sql = 〃select n—zxygz, dat印art (Hour, d—cjsj) as n—hour from dlsd where s—bbh = , [%=getInput (,, s—bbh,, )%], and d—cjsj 〉= , [%=getInput (,, d—rq,, )%] and d—cjsj 〈 , [%=getInput (,, d—rql" )%], order by d—cjsj" /〉 〈sql
name = 〃ssl〃
sql = "select n—ua, n—ub, n—uc, dat印art (Hour, d—cjsj) as n—hour from ssl where s—bbh = , [%=getInput (,, s—bbh,, )%], and d—cjsj 〉= , [%=getInput (,, d—rq,: )%], and d—cjsj 〈 , [%=getInput (,, d—rql" )%], order by d—cjsj" /〉 〈/datasource〉
每个数据源定义在一个子结点中。每个数据源都有一个name属性,定义该数据源的名 称。之后程序访问数据源对象里的数据也是按照名称来访问。不同数据源应配置不同的名称 。系统支持三种数据源SQL数据源通过定义一个査询数据的SQL语句,到数据库中执行査 询,将査询结果作为数据源内容。SQL语句中支持嵌入式表达式。Java数据源通过访问一 个Java方法,获得所需的数据。该Java方法可以是本地类的方法,也可以是一个远程EJB方 法调用。DSF数据源通过访问DSF(DataSourceDefine)对象,获取所需数据。査询数据源, 返回字段都已定义在DSF对象中,査询时只需提交査询条件即可。可认为是SQL数据源的高级 版,即将基础表数据中编码字段进行转换后返回。并且可对字段值进行格式化处理。在一个 报表中可以同时配置多个多种数据源。
当数据源执行完査询后返回的数据对象有以下几种
BEAN-单个的Java Bean,实际就是一个Java类实例。通过访问指定的方法获得数据。 MAP- Java Map对象。通过Key可从Map中获得数据。
ARRAY - Java Array对象,即数组。里面的数据只能按顺序(索引)访问。LIST- Java List对象。同Array类似,里面的数据只能按顺序(索引)访问。 DATASET—ROW- Java DataSet对象。即数据集对象对象,但只使用DataSet中的当前记录。
LIST—BEAN - Java List〈Bean〉对象,Bean对象的集合。
MAP—BEAN - Java MapX寸象,Map〈BeanName, BeanOb ject〉。 一次调用返回多个Bean。返 回后,将以数据源名字.BeanName为名字将BeanObject放入返回数据对象集合中。 一般不需 要定义返回值类型为MAP—BEAN的Java数据源方法。可定义多个数据源,每个数据源的Java调 用方法返回单个Bean。
LIST—MAP - Java List〈Map〉对象。List中的每个元素是一个Map。 DATASET -数据集对象。(自定义),类似于ResaultSet。其中可包含多条记录。 GROUP—MAP - Java Map〈Beanl, List〈Bean2》对象。 一般用来给分组报表提供数据。 Beanl用来提供分组的数据,List〈Bean〉用来给该分组的明细区提供数据。
上述BEAN、 MAP、 ARRAY、 LIST、 DATASET—ROW对象可当作是单条记录,只包含一个实体 的多个属性数据。可用来填充报表中的各个区段。
上述LIST—BEAN、 LIST—MAP、 DATASET包含多条记录,可以用来填充明细区。 上述GROUP—MAP既包含分组数据,也包含分组明细数据,用来给分组报表提供数据。 上述MAP—BEAN包含多个互不相干的Bean。
SQL数据源和DSF数据源只返回DATASET数据对象,Java数据源可返回任何一种数据对象
以sql作为子结点名称定义的数据源是SQL数据源,其代码如下 〈sql name = "dlscT
sql = 〃select n—zxygz,datepart(Hour, d—cjsj) as n—hour from dlsd where s—bbh = ' [%=getInput(" s—bbh" )%]' and d—cjsj >= ' [%=getInput(" d—rq" )%]' and d—cjsj 〈 ' [%=getInput(" d—rql" )%]' order by d—cjsj" /> 其中
Name :该数据源的名称。String 。
Sql :査询数据的SQL, String,支持嵌入式表达式。以上的例子中为了浏览 清楚,将SQL中的转义符改回原始值,实际配置时应注意。 SQL数据源返回的结果是一个记录集(DataSet)对象。以java作为子结点名称定义的数据源是java数据源,Java数据源是指在运行时刻访问一 个java方法得到的数据源。其代码如下 〈Java name = 〃czy〃
method = , getCZYList (getlnput(〃s—gdj〃)), return = 〃list—bean〃 /〉 其中
Name :数据源名称,String
Method :方法名称,String。支持自定义函数。 Return :返回数据类型,String,可选值包括 bean, m即,array, list, dataset—row, list—bean, map—bean, list—m即,dataset, group—map;
在上述内容中,method方法可以使用自定义函数。自定义函数的声明文件应在web服务 器启动时加载。
如以上的方法getCZYList (getlnput (〃s—gdj〃))中,使用了一个自定义函数 getCZYList (getlnput (e, 〃s—gdj〃)),该函数的声明如下
public static ArrayList getCZYList(String gdj)throws UniException{
声明了该方法以后,就可以在自定义函数中使用了。 方法执行完毕后返回的数据先存放在返回数据集合中。 以dsf作为子结点名称定义的数据源是DSF数据源,其代码如下 〈dsf name = 〃czy〃 alias = "xt—czy" preset—where = "s—isadmin ='0'" preset—orderby = "s—czybh" /> 其中
Name :该数据源的名称。String 。
Alias :数据源的别名,String。 Preset—where :预置的査询条件。String。可省略。 Preset—orderby :预置的排序条件,String。可省略。DSF数据源可看做是SQL数据源的升级,它也是返回一个DataSet对象。但DSF数据源是通过在在DSF对象上进行査询,返回事先定义好的字段。并且按照DSF中定义的转码方式对原始数据进行Value-Text的转换及一些数据格式化的处理。査询时会将Presetwhere和运行时输入的査询条件结合在一起进行査询(两个査询条件之间是And关系)。如上例,査询结果中只会得到不是管理员的操作员。并且默认的排序条件是按操作员编号进行排序。
在本实施例的定义文件中,数据再计算过程定义在〈caldata〉段里。可为空。例如〈caldata〉mymap = new HashMap ();
mymap. put(〃usercount〃, getDataSet(〃czy〃).count (〃氺〃));mymap. put("avg—age", getDataSet("czy"). avg("age"));pubData(e, 〃totaldata〃, mymap);〈/caldata〉
系统对各个数据源进行处理完后,将返回的数据对象放在数据对象集合中。对数据对
象集合中的数据可以进行再计算。再计算一般包含对数据虚拟列的计算(如DataSet);对数据进行统计(如计数、求和、求最大值最小值平均值等),产生的统计结果数据可存储到新的数据对象(如新产生一个Map)。
再计算过程都是通过自定义函数来实现的。通过在〈caldata〉节点之间配置自定义函数来实现。自定义函数可以是多条,每条语句末尾为分号(;),语法要符合Java语言的语法规则。多条语句之间顺序执行。
在上述例子中,首先生成一个HashMap对象mymap,然后给该map中添加了两个数据项:usercount 数据集czy的记录数求和,avg—age 数据集czy对全部人员年龄求平均值。最后将这个map添加到数据对象集合中。在输出程序也可以使用该数据对象。
数据再计算完毕后,就进行数据输出步骤,在本实施例的定义文件中,数据输出定义在〈segment-data〉段里。如下〈segment-data〉〈titlebind = 〃false〃 >
〈item name = "title" formula = ' getlnput("s—gdj. text")' />〈item name = "printdate" formula = 'today()' />〈/title>〈bodybind = 〃true〃type = 〃list—bean〃source = "czy" /〉〈/segment-data〉
在本实施例中,数据输出指的是将数据按区段提交给ExcelEngine对象,由ExcelEngine对象生成报表区段,并填充数据,最后生成报表。
在〈segment-data〉段里定义了报表的每个区段中的每个数据项绑定到数据对象集合中的哪个数据对象上。可将一个区段绑定在一个数据对象上,也可以配置一个区段中的各个数据项绑定在不同的数据对象的不同字段(或属性)上。〈segment-data〉段的各个子结点名称应以报表区段名称为节点名称。其中
Bind: 该区段是否绑定在一个数据对象上。Boolean,不可省略。如果bind ="false",表示该区段中的数据项需要逐个配置。每个数据项的配置在〈item〉子结点中。Item子结点Name :数据项名称,String。
Formula :数据输出公式,String。使用自定义函数。其中,Item的Name需要与报表样式文件中定义的数据项名称相匹配。如以上报表,样式文件中表头段的数据项定义为〈r印ort-title-def ine〉〈item name=〃title〃 row=〃2〃 col二〃b〃 display二〃true〃 format二〃o/olSs操作员清单〃format—data—type二〃c〃 length=〃0〃 datatype c〃 /〉
〈item name=〃printdate〃 row=〃3〃 col=〃e〃 display=〃true〃 format二〃〃leiigth=〃0〃 datatype d〃 /〉〈/r印ort-title-def ine〉其中定义了两个数据项title禾口printdate。如果bind = "true",就不需要再逐个配置数据项了 。
Type: 数据X寸象类另U, String, 可选值bean, map, array, list,dataset—row, list—bean,list—map, dataset
Source:数据对象名称,String,可使用数据对象集合中的任何对象。会直接把数据对象交给ExcelEngine对象去填充区段中的单元格。但要保证数据对象中的各数据名称和报表样式文件中定义的数据项名称相匹配(按名称访问数据项时)或顺序相匹配(按顺序访问数据项时)。
在本实施例中,如果报表被定义为一个分组报表(〈r印ort-define type=" group" >),那么还需要定义分组数据输出段。如果报表是其他类型,则不需要该段代码〈group-dat3datasource = 〃dataset〃dsgroup= 〃yh〃dsbody = 〃gdjl〃filterfield = 〃s—bbh〃 /〉其中
datasource :数据源类别,String,可选值dataset/map。表示使用哪种数据源。datasource = "dataset"时,需定义以下属性-
dsgroup :分组部分数据集(DataSet)对象名称,Stringdsbody :分组明细部分数据集对象名称,Stringfilterfield :过滤字段名称,String
datasource = "map"是,需定义以下属性Map :分组数据对象(Map)名称,String。可使用两种方式为分组报表提供数据。其一使用两个数据集对象。dsgroup和dsbody。运行时按顺序读取dsgroup中的数据作为分组数据项,然后按filterfield字段到dsbody过滤,得到当前分组记录对应的明细数据项,再生成该分组的明细数据。其二是使用一个Map对象,〈groupBean, List〈Bean》,groupBean提供分组部分数据,List〈Bean〉部分提供该分组的明细数据。
注意报表定义为分组报表时,报表的表头表尾部分还需要按区段定义,分组部分定义在〈group-data〉中。
此外,在本实施例中,系统也可使用自定义函数。自定义函数可以单独使用,也可以放在嵌入表达式中。比如initvalue =
'[%=getSessionAttr(〃GDJBH—String〃)%]|[%=getSessionAttr(〃GDJMC—String〃)%]'中,getSessionAttr(〃GDJBH—String〃)就是个自定义函数放在嵌入式表达式中的例子。又如sql = 〃select n—zxygz,datepart(Hour, d—cjsj) as n—hour from dlsd where s—bbh='[%=getInput(" s—bbh" )%]' and d—cjsj >= ' [%=getInput(" d—rq" )%]' and d—cjsj〈'[%=getlnput(" d—rql" )%]' order by d—cjsj〃也是嵌入式表达式的例子。
嵌入式表达式是指该内容本身是一段文本,其中嵌入有[%.......%]这样的标签,标签
里是嵌入式表达式,运行时系统可解释执行嵌入表达式,用计算结果替换标签。将最终结果文本提供给程序使用。标签[% y。]中的内容应是一个有效的Java语句,可包含自定义函数,系统函数,各种运算符。但最终计算结果应返回一个字符串。标签里的语句应以=(等号)开始。并且内部表示一个字符串变量时,应以双引号(")作为字符串两端的边界。又如〈item name = 〃title〃 formula = ' getlnput (〃s—gdj. text〃)' />, 就是^^个直接使用的例子的自定义函数
自定义报表中访问所在应用系统函数、变量,都是通过自定义函数进行的。系统运行时,通过引擎调用自定义函数,进行数据计算,返回计算结果输出到报表中。因此系统所有和数据访问计算相关的功能都是通过自定义函数实现的。自定义函数也是系统的一大特色。系统安装时,已提供了一部分自定义函数。在实际运行中,如果已提供的还不够,可自己再开发相应的Java程序,开发完后打包成Jar文件,发布在应用服务器的相应lib目录中,然后将函数的声明添加到自定义函数声明文件中,就可以使用新加的自定义函数了 。自定义函数实际上使用了BSH包来计算自定义函数或表达式。在本实施所述的自定义报表产生管理系统中,管理平台实际上就是管理报表定义文件的目录结构,文件上传下载与删除。其中,其数据文件目录结构如下Unir印ort :数据文件根目录
-define :报表定义文件存放目录。存放报表定义文件(xml格式)
该目录下可任意创建子目录名,目录名就作为报表的分类名,目录级数没有限制。报表定义文件扩展名为.xml。
-dsf :自定义数据源绑定报表存放目录。目录下是全部数据源
绑定报表的定义。该目录下可任意创建子目录名,目录名就作为报表的分类名,目录级数没有限制。每个报表定义一个空文件。文件名为"报表显示名称 对应数据源别名.txt",扩展名任意,无扩展名也可。
-model :报表模板文件和样式文件存放目录。模板文件(xls格
式),样式文件(xml格式)
-userfunction :自定义函数声明文件存放目录。声明文件是文本文
件(txt格式)-unir印ort—searchpage :自定义査询条件页面存放目录。运行时将该目录映射为web服务器下的一个虚拟目录。如果web服务器不支持映射虚拟目录,也可将该目录直接放在webapps下。
在本实施例中,结构与文件目录结构及报表文件名相同,这样简化了报表的分类与发布管理。创建新的分类时,只需在指定目录下创建新目录即可,而发布新报表也只需要将报表文件上传到指定目录即可。
在本实施例中,运行平台实际上就是系统的操作界面。操作员登录后,可看到已发布的各个报表,点击一个报表名称,系统根据该报表中定义的输入参数生成査询条件输入页面。操作员输入査询条件后提交即可看到报表内容。在本实施例中,系统启动时,加载自定义函数声明文件,加载字典表定义、数据源定义等。系统运行时,操作员点击一个自定义报表名称,启动自定义报表引擎(Engine)处理过程首先根据报表定义文件构造一个报表定义对象(R印ortDefine对象),然后根据该定义对象构造一个自定义报表处理引擎(Engine)类实例;从R印ortDef ine. inputParameters中可得知为该报表定义的自定义査询条件,为每一个査询条件生成对应的査询条件输入控件。最后生成输入各个査询条件的页面。输入完査询条件后提交时,系统按照査询条件中定义的检验方法对输入值进行校验,校验成功才可以提交査询。之后,报表引擎处理提交的査询条件,将所有的参数输入值放入Engine. inputData中,并逐个处理R印ortDefine中的数据源定义。处理完数据源定义后,根据R印ortDefine中.calData部分的定义,对Engine. data中存放的数据对象进行再计算,比方说产生一些统计数据等。可修改已有对象中的数据,也可产生新数据。新输入一般存入一个新的map中。之后,根据报表样式文件构造一个ExcelEngine对象,然后按照R印ortDefine. segmentDatafile中对各区段的数据项定义输出数据至UExcelEngine对象。其中,对于SQL数据源,处理SQL中的嵌入式表达式,得到目标SQL语句,执行査询,得到査询结果,将査询结果DataSet放入Engine. data中;对于Java数据源,通过调用自定义函数,执行一个Java方法。将该方法返回的数据对象放入Engine. data中;对于DSF数据源,首先构造一个DSF对象,然后在该对象上执行査询,将返回的DataSet对象放入Engine. data中。而当绑定整个区段到一个数据对象上的,将数据对象从Engine. data中取出来,直接提交给ExcelEngine对象,生成报表的相应部分。当区段数据项为逐个配置的,首先构造一个新的map,调用自定义函数和嵌入式表达式处理引擎,对数据项配置公式进行计算,将数据项名称和计算结果放入map,该区段的全部数据项都处理完后,将整个map提交给ExcelEngine对象,生成报表的相应部分。在输出报表时,如果需要按Html样式将报表内容显示在客户浏览器上,那么调用 ExcelEngine的export方法,得到Html格式的报表内容,然后将Html内容写入至l」response, 最终显示在客户浏览器上。 一般来说,报表内容应显示在独立的frame里;如果需要生成 Excel文件供客户下载到本机,那么调用ExcelEngine的export方法,得到byte[]格式的 Excel文件内容,然后将数据直接写入response,客户浏览器就会提示下载或打开Excel文件 ;如果需要在服务器端生成Excel文件,可调用ExcelEngine. write方法,将报表内容写入到 Excel格式的文件中。
以上所述实施例仅表达了本发明的几种实施方式,其描述较为具体和详细,但并不能因 此而理解为对本发明专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在 不脱离本发明构思的前提下,还可以做出若干变形和改进,这些都属于本发明的保护范围。 因此,本发明专利的保护范围应以所附权利要求为准。
权利要求
1.一种自定义报表生成管理方法,用于浏览器/服务器结构,其特征在于,包括如下步骤A)在浏览器上调用服务器上运用程序,显示服务器上所有报表清单的报表页面,选择其中一个报表;B)服务器生成所选报表,传送到所述浏览器。
2 根据权利要求l所述的自定义报表生成管理方法,其特征在于,还 包括在所述服务器上建立报表文件,其包括M)使用Excel生成多个存储在服务器内的报表文件。
3 根据权利要求2所述的自定义报表生成管理方法,其特征在于,所 述步骤M)中进一步包括如下步骤Ml)使用Excel得到报表模板,生成模板文件;M2)将所述模板文件分区段,并定义所述模板文件中的每个区段,生成样式文件 M3)定义上述各区段中的数据,生成定义文件;M4)将上述文件传送到服务器的报表目录中指定位置,得到一个报表文件。
4 根据权利要求3所述的自定义报表生成管理方法,其特征在于,所 述步骤M2)中所述定义区段包括定义该区段中放置的数据项、所述数据项的位置以及所述 数据的显示格式。
5 根据权利要求4所述的自定义报表生成管理方法,其特征在于,所 述步骤M3)中所述定义所述区段中的数据包括数据的来源、数据査询方式、数据査询条件 、数据计算以及数据填充。
6 根据权利要求5所述的自定义报表生成管理方法,其特征在于,所 述步骤M4)进一步包括如下步骤M41)将所述模板文件、样式文件和定义文件传送到所述服务器指定目录中;M42)刷新报表页面,得到上述文件所生成的报表之清单。
7.根据权利要求l所述的自定义报表生成管理方法,其特征在于,所 述步骤B)进一步包括Bl)产生该报表査询条件输入页面;B2)依据所述査询条件输入页面的内容,査询数据,生成报表; B3)输出生成的报表到所述浏览器。
8. 一种自定义报表生成管理系统,用于浏览器/服务器架构,其特征 在于,所述服务器上包括报表运行引擎用于解析报表定义文件,査询报表需要的数据以及生成报表; 报表管理平台用于发布、管理各类报表;报表运行平台用于显示在所述管理平台上发布的报表清单,当所述报表清单中 的一个被选中时,调用所述运行引擎,査找、生成报表,并输出。
9.根据权利要求8所述的自定义报表生成管理系统,其特征在于,所 述报表运行引擎进一步包括用于在所述报表清单中一个报表被选拔中时产生査询条件输入页 面的査询条件输入页面产生单元。
10.根据权利要求9所述的自定义报表生成管理系统,其特征在于, 所述报表管理平台包括用于存放所述报表定义文件的报表定义文件存放目录、用于存放所 述报表模板文件和样式文件的报表模板文件和样式文件存放目录、用于存放于报表绑定数据 源的自定义数据源绑定报表存放目录、用于存放申明文件的自定义函数申明文件存放目录以 及用于存放所述査询页面的自定义査询条件页面存放目录。
全文摘要
本发明涉及一种自定义报表生成管理方法,用于浏览器/服务器结构,包括如下步骤在浏览器上调用服务器上运用程序,显示服务器上所有报表清单的报表页面,选择其中一个报表;服务器生成所选报表,传送到所述浏览器。本发明还涉及一种自定义报表生成管理系统。实施本发明的自定义报表的生成管理方法及系统,具有以下有益效果由于每个报表文件的模板中包括模板文件、样式文件和定义文件,因此,生成报表时报表的格式和报表的数据是分开生成后在组合的。故其扩展性较好、支持自定义查询条件。
文档编号G06F17/24GK101650712SQ200910305760
公开日2010年2月17日 申请日期2009年8月18日 优先权日2009年8月18日
发明者邓志峰 申请人:深圳市科陆电子科技股份有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1