第1章 性能优化
1.1 报表设计优化
1.1.1 数据的预处理
为提升海量数据下报表响应速度,可以对参与报表计算的数据做必要的预处理。如根据报表内容定义中间数据库表(业务开发中常称为“中间表”),然后周期性的同步数据到这个表中,也可以在报表生成前调用存储过程同步数据到中间表。
1.1.2 选择合适的缓存策略
为了提高报表的显示速度,提高并发访问量, UniEAP Report设计了独有的多级缓存技术,并提供良好的缓存扩展机制。用户可以根据实际情况选择合适的缓存策略。
通过UniEAP Report,可以分别对报表定义及报表实例进行缓存。
1.报表定义缓存是指缓存从报表支撑数据库中取得的报表定义文件(即在报表设计器中设计的rdj文件)。UniEAP Report对报表定义提供SingleServerCache、MultiServerCache两种缓存策略,分别适用于以下两种使用场景:
- SingleServerCache
是单服务器缓存策略,如果报表设计器发布报表连接的服务器与Web端浏览报表时访问的服务器为同一个应用服务器,可以采用此策略; - MultiServerCache
是多服务器缓存策略,在报表应用服务器集群环境下以及多应用共同使用同一个报表支撑数据库情况下,为了保证每次Web端访问的报表都是最新定义的报表,而不是从缓存中读取的未修改的报表,则需要使用MultiServerCache缓存方式。
2.报表实例缓存是指对报表运算结果的缓存。UniEAP Report提供三种报表实例缓存策略:
- DummyResultCache
是不使用缓存策略,如果不需要对报表运算结果进行缓存则配置成这种方式。 - SimpleResultCache
是简单缓存策略,按用户ID进行缓存,缓存效率高,不支持一个用户ID通过多个客户端(浏览器)浏览报表,这时会缓存最后一次访问的数据。 - LongResultCache
这种方式是每创建报表都进行缓存,并生成新的缓存ID和缓存文件,这种方式解决了简单缓存策略不能支持一个用户ID通过多个客户端浏览报表的限制。 - QuickResultCache
这种方式是每创建报表都进行缓存,生成新的缓存文件,但是会设定缓存临时文件的数量,一旦超出用户设定的数量上限,系统会自动清除最早生成的临时文件,从而避免临时文件过大。用户还可以自行设置是否在次日00:00时清空所有缓存文件。
1.1.3 大数据量列表分段加载数据
当Web端浏览数据量过大(超过1万条数据)的报表时,若一次将所有数据取出,对系统的访问速度以及性能势必造成一定的影响,对于这种大数据量数据列表,UniEAP Report提供了分段数据加载方式以解决其数据量过大造成的数据加载问题。
定义详细方法参见《UniEAP Report最佳实践之——海量数据报表》。
1.1.4 数据集执行成本过高
当数据集一次性取出数据过多时,可能会造成数据集执行成本过高的情况,以至于内存占用过大,这对系统的访问速度以及性能势必造成一定的影响。
当遇到这种情况时,请首先检查报表定义,分析确认是否真的需要查询出这么多数据。如果查询量确实要达到几万甚至几十万条,UniEAP Report为了解决这种问题,增加了保护机制,提供了分段数据加载方式以解决其数据量过大造成的数据加载问题。定义详细方法参见《UniEAP Report最佳实践之——海量数据报表》。
1.1.5 导出的PDF文件过大的解决办法
通常导出的PDF文件都会很大,当报表页数较多时,导出的PDF文件就会有十几MB,甚至几十MB,文件过大可能会导致电子邮件无法发送或者下载速度过慢。
UniEAP Report默认的PDF导出方式为“‘图形方式’”,PDF中所有元素都以图形方式存储。如果希望文件尽量小,可以将PDF导出方式配置为“‘文字方式’”。
配置方法如下:
使用解压缩软件,解压缩WEB-INF\lib\unieap-report-engine-*.jar文件,在该jar包中找到com\neusoft\report\engine\export目录,修改该目录下的配置文件exporter.properties;
将如下内容
2=com.neusoft.report.engine.export.pdf.PdfExporter
修改为:
2=com.neusoft.report.engine.export.pdf.PdfExporterWithFonts
把iTextAsian.jar放在WEB-INF/lib下;
把fonts文件夹放在WEB-INF\conf\UniEAP\report\下,fonts文件夹包括配置文件及ttf字体库文件;使用该种方式,需要自行配置字体文件位置,来保证导出的PDF中字体与最初所设置的字体相同;如果需要除宋体外的其它字体, 则需要配置fonts.xml文件。
Fonts.xml配置文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<fonts>
<font>
<name>黑体</name>
<path>C:\WINDOWS\Fonts\SIMHEI.TTF</path>
</font>
<font>
<name>楷体_GB2312</name>
<path>SIMKAI.TTF</path>
</font>
</fonts>
在该配置文件中每个font节点代表一种字体,其中name子节点代表字体名称,path代表字体库文件路径,可以是绝对路径,如““C:\WINDOWS\Fonts\SIMHEI.TTF”“,也可以是相对路径SIMKAI.TTF,相对路径是指WEB-INF\conf\UniEAP\report\fonts\目录下。
【注意】这里仅需要配置需要的字体。如果找不到相应字体库文件,则默认为宋体。
配置完成后,需要重新启动应用服务器,使配置生效。
再次导出PDF,会发现导出的PDF文件明显变小。两种方式导出PDF文件大小大约相差10倍左右。
1.1.6 打印大数据量报表
UniEAP Report的java打印与lodop打印方式支持灵活的打印控制,可以解决大数据量打印问题。
1.1.7 可使用任务调度定时生成大数据量报表
对于一些不需要实时查看的大数据量报表,可以使用UniEAP Report提供的任务调度功能设置计划任务选择系统访问量很小或无人访问的时间段自动触发报表生成,以避免影响其它业务访问。
1.1.8 巧用各种公式
数据集函数使用col_index会比使用col_name效率高,例如“=group( 'ds1', 0)”;
对于基于单元格的sum操作,应尽量sum高级的(存在依赖关系的)单元格,尤其对于多层分组汇总式报表;
如下图所示,e3单元格计算的是每个客户的订单总额,e4单元格计算的是每个地区下所有客户的订单总额,则e4单元格中的公式是sum( cell(‘e3’,null,’’)),这样比sum e2单元格效率更高,同理e5单元格中sum e4单元格比sum e3或e2单元格的效率更高。
对于多层分组报表,在最外层分组单元格的Group公式中进行排序,比在内层分组单元格中排序效率更高;
如下图所示,在a2单元格的Group公式中对数据按照地区排序,而在其余单元格的公式中不再设置排序字段。
UniEAP Report对单元格的解析规则是:从上到下、从左到右,所以对单元格的引用,最好出现在这个单元格的右方或下方,避免逆向引用。
对于大数据量列表,尽量减少单元格之间的运算,将大部分的计算工作转移到数据库执行。如合计、字符串拼接、平均值、字段排序等操作。
如下图所示,为提高报表运算效率,“小计”、“合计”单元格中直接采用数据集函数,而没有使用单元格间运算的形式。
1.1.9 数据集优化
1.1.9.1 多数据集和单数据集的选择
列表式、交叉式报表尽量使用单数据集;
例如下面的报表,这是一张多层交叉报表:
此报表定义方法有两种,第一种采用单数据集,将横、纵向分组所需的字段,在一个sql中进行关联,定义如下:
第二种方法,定义四个数据集,每一层分组的字段都来自不同的数据集,通过单元格关联过滤数据,定义如下:
第一种方法比第二种方法在性能上有所提高,原因如下:
- 在数据集SQL里就对表头字段先进行分组聚集,这样取过来的记录数大大减少,加快了取数速度和报表的运算速度;
- 交叉汇总运算不需要再对记录表进行检索遍历,而是直接对当前组集里的记录进行汇总,因此速度大大提高了;
- 多源分片、主从关系式报表尽量使用多数据集;
- 运算单元格较多时使用多数据集。
若报表的数据量很大,并且从数据库中取出数据后,还要经过大量的运算才能获取需要显示在报表单元格中的数据,这种情况可以采用定义多个数据集的方式,使运算在数据库中进行。 例如下面的报表:
这是一张分组报表,表头是固定的,数据经过运算得到,有两种定义该报表的方法: 第一种方法:
这种方法定义了一个数据集,运算使用报表公式在单元格中进行。 第二种方法:
这种方法定义了多个数据集,在数据库中运算,单元格显示运算后的数据并根据过滤条件进行关联。
第二种方法比第一种方法在性能上有明显提高,原因如下:
- 在数据集SQL里就对数据先进行分组聚集,这样取过来的记录数大大减少,加快了取数速度和报表的运算速度;
- 数据运算不需要报表服务器再对所有内存中的数据进行运算,而是直接取得已经在数据库中运算好的结果,因此速度得到提升。
1.1.9.2 通过SQL语句优化性能
在SQL中对数据进行排序,则使用数据集函数时,不设置排序属性,可提高效率;
在SQL中对数据进行过滤,避免在报表函数中进行过滤,这样取到报表服务器端的记录数大大减少,既加快了取数的速度,也加快了报表的运算速度;
尽量在SQL中进行分组,以减少取到报表服务器的记录数,加快取数和报表运算的速度;
sum,count计算在SQL中进行,报表运行速度可得到提升,尤其对于大数据量的报表效果较为明显;
使用todate 代替tochar;
尽量不要使用select from,这样相当于将表中所有字段的数据都取到报表服务器端,增加了报表服务器端的内存占用以及减慢了运算速度,使用时将替换为所需的字段。
1.1.9.3 灵活应用存储过程数据集
对于大数据量报表,可以适当使用存储过程数据集,存储过程可以使SQL语句更加灵活和高效,通过存储过程预先准备好数据,将运算操作转移到数据库中执行,以减轻报表数据运算压力。
1.1.10 其它
- 删除不必要的空白行列;
- 慎用隐藏行列;
报表中为了进行一些复杂的运算,往往需要用到隐藏行列来处理中间的运算,而这些隐藏行列中被用到的单元格往往只有一两个格子,整行整列的单元格的个数很多,此时没被用到的单元格会额外浪费内存。
若对样式要求不是很严格,推荐使用导出CSV来代替导出Excel,因为导出CSV文件的效率会高于导出Excel文件。
1.2 环境优化
1.2.1 应用服务器
数据库连接池采用应用服务器的提供的连接池,会提高访问数据的性能;
将JVM虚拟机内存设置到最大
当访问数据量很大的报表时,内存使用会迅速地增长,当需要的内存超出设置的最大值时虚拟机就会提示内存溢出,一般建议最大值设置为可用内存的最大值的80%;
采用应用服务器集群的部署方式,增强系统性能;
当报表作为系统中非关键业务时,推荐把报表作为一个独立的应用,单独部署。
- 因为报表生成是需要访问大量业务数据,可能对系统性能造成影响;
- 独立部署报表应用,减少业务应用中集成报表应用的复杂度;
- 多个业务应用都需要报表,并且报表内容有重复,为了在多个业务应用间共享。
每种应用服务器都有对应的优化策略和方法,具体优化参数请查找对应的应用服务器资料。
1.2.2 数据库
数据库连接方式的选择
- JDBC方式方式优于DRM方式;
- 关键字段建立索引,加快对表中记录的查找或排序;
- 业务数据源和系统数据源分开,建立不同的表空间,平衡I/O访问,避免I/O瓶颈;
- 访问数据量非常大时,推荐采用数据库集群方式。
各种数据库的具体优化方法请查找对应的数据库资料。
第2章 报表定制技巧
2.1 大数据量报表中,使用子布局,以避免出现交叉维
在大数据量报表中,应尽量使用子布局以避免交叉维的出现,因为交叉维中的数据要在行/列依赖格的基础上运算获得,过多的运算操作势必影响效率,例如下面的两张报表定义界面截图,若对于数据量较大的报表,使用子布局的方式定义的报表性能将优于普通交叉报表定义方式。
2.2 针对不同场景选择序号和排名公式
UniEAP Report提供的序号公式有: Offset及seqNum,与它们比较类似的公式有Indexof,它们分别适用于不同的使用场景,针对场景选择适合的公式可以有助于提高报表运算效率。
- Indexof适用场景(已不推荐使用该公式)
适用于排名需求,索引从0开始。 - Offset适用场景
适用于序号需求,索引从0开始。 - seqNum适用场景
适用于序号需求,但索引从1开始。
2.3 动态报表效果
几乎所有的单元格属性中均可以定义公式,以实现动态的效果,例如交替背景色、动态行高/列宽等。
2.4 模糊查询条件
除了可以在数据集的SQL语句中定义模糊查询外,也可以使用Like公式作为模糊查询过滤条件,例如:
select( 'ds1', 'name', {like('张.*',&get( 'ds1', 'name'))=false}, 'name asc'),获得第一个字不为“张”的所有值。
2.5 获取非空数据
UniEAP Report提供的isnull公式可用于获取数据集中的非空数据,例如:
select( 'ds1', 'name', {isnull(&get( 'ds1', 'name'))=false}, 'name asc'),获得名称不为空的所有值。
若想查找值为null的数据,用如下公式:
select( 'ds1', 'name', {isnull(&get( 'ds1', 'name'))=true}, 'name asc')
2.6 提高大数据量报表的翻页效率
在Web端展现报表时,多数情况下会对报表进行分页,且默认为按照行数分页,如每页显示20行,当在数据量很大时,经常会出现翻页速度很慢的现象,尤其在页数跳转跨度较大时(如:100页跳转到200页),需要等待很久的时间。
在每一张报表中,都可能会包含隐藏行、图片、图表、分页符(格上分页、格下分页)、分栏等元素,这些元素,被视为分页干扰因素,当一张报表存在分页干扰因素时,不能简单的通过行数的计算来锁定某一页的数据,仅能通过从第一页到指定目标页的依次计算,这时势必会影响到翻页时的体验;当分页时,如果没有分页干扰因素,则采用直接定位数据的方式,这是一种高效的方式。
因此,如果需要提高翻页效率,则应尽量避免使用分页干扰因素:隐藏行、图片、图表、分页符(格上分页、格下分页)、分栏。
2.7 注意null与 ’’ 的使用规则
cell公式所在的单元格,只有列依赖,没有行依赖,则水平方向偏移量输入null;
cell公式所在的单元格,只有行依赖,没有列依赖,则垂直方向偏移量为null,因为垂直方向偏移量为最后一个参数,所以可以省略垂直方向偏移量;
cell公式所在的单元格,既有行依赖又有列依赖,而水平和垂直方向不需要偏移,则水平和垂直方向偏移量均输入’’。
2.8 一维条码与二维条码的尺寸
一维条码与二维条码的编码及绘制形式不同,如果使用设计器默认提供的尺寸值,在选择一维条码和二维条码时得到的条码大小可能会有较大差异,以下以一维条码的默认尺寸做基准,使用相同数据,对二维条码的高度/宽度设置做一个简单的比较,供报表设计时做参考。
2.9 数据集为存储过程,返回结果集
存储过程数据集的定义方式使用call procedureName($name1,#name2...)语法。
call是调用命令。
procedureName是数据库中存储过程的名称
(…)中为参数,此语法支持两类参数in和out
- in参数
存储过程的输入参数,等价于报表中的参数,在存储过程中引用的方式同样为$name,可以包含多个。 - out参数
存储过程通过输出参数来返回结果。
返回的结果有两种:单值和结果集,且两种情况不能同时返回。即不能既返回单值,又返回结果集。
2.10 实现只显示数据的前几条,丢弃剩余数据
报表的一栏只有有限的14行,当超过14行时,需要丢弃处理,不显示在页面上。这样可以实现简历格下面分页的效果,而不希望将简历在二页中显示。
- 方法1:
将该栏单元格合并,并定义一个子布局。然后将子布局填充方式设置为截断即可。在子布局中扩展简历内数据。
可以在子布局扩展时使用topN公式,这样不设置截断同样实现这一效果。 - 方法2:
简历栏只预留1行,公式中使用topN纵向扩展,指定只能扩展出N行,topN公式当不足N时,可以以空行补足。
2.11 定义出显示N满页的报表(智能补行)
报表为横向扩展报表,打印时每页只显示3列,最后一页不满3列时需要用空列来补满3列。
在打印时每页显示3列内容,调整好列的宽度后,可以使用控制左右边距的方式,使其每页正好显示3列内容
不满3列的补满:可以使用topN公式,一般情况下,topN公式只能在知道N为多少才可以计算。而这个N可以在公式中动态计算。
=topN(select('ds1','colid'),count(select('ds1','colid'))+3-mod(count(select('ds1','colid'),3)),true)
写公式会使计算量增加,导致性能下降,还可以调优。比如记录条数你在另外一个数据集里用sql来统计,放在一个独立的格子里头,然后就不需要使用count(select('ds1','colid')),而直接引用那个格子就行了。
2.12 在图表中使用sum公式求合计
图表定义中不能直接使用sum公式,因为图表的系列以及分类轴都必须是能返回一组数据的集合函数。如果需要显示合计后的数据,需要在报表中定义一个单元格来计算合计,再将该单元格设置为不显示就可以达到求合计的效果了。
例如在报表定义的a3单元格中计算合计,然后将a3所在列设置为不显示。图表定义中直接写 =cell(‘a3’)引用这个合计。
2.13 报表输出时URL中包含中文参数的处理方法
针对URL中传输中文问题,UniEAP Report中内臵了解决方案: 报表引擎中提供的JS文件/unieap/pages/report/js/encode.js可以对中文进行base64编码,中文URL通过base64编码后提交到服务器,服务器再对中文进行base64解码,即可得到对应的中文。 使用详细步骤如下:
1.Jsp页面引入encode.js文件;
<script src="/path/encode.js"></script>
2.使用JavaScript提供的函数将参数进行base64编码;
Var myParam = “中文字符”;
myParam = encodeto64(myParam);
【注意】编码时仅需要对参数值进行编码,不需要对整个URL编码;如果有多个参数,必须全部编码,在一个URL中不能出现部分参数编码部分参数未编码的情况。
3.将编码后的参数拼接入URL中,并加入已编码参数encode=true通知后台参数已经编码,需要后台进行解码。
也可将1,2步骤和在一起,URL形式如下:
【注意】在一些项目中,由于中文编码方式不同,为了防止解码乱码,还需要传递字符集参数paramCharset=GBK
2.14 记录报表的查看、导出记录
UniEAP Report在3.3rc版(2009-06)之后,支持事件框架,提供了一个事件接口,com.neusoft.report.common.event.EventHandler
这个接口的业务实现可以配置到report-engine-config的配置文件中。
在对报表进行访问、导出、发布等各种操作是都会调用该接口,在接口中可以获得操作类型以及操作结果,如‘导出excel、成功’。
现在这个接口的默认实现是在日志中记录了一条log.可以根据业务需要进行数据库写入操作。
2.15 将代码值使用代码表翻译为代码名称
1.如果代码表为使用UniEAP代码表组件实现,可以直接使用EAPCodelist公式即可;
2.如果不是使用UniEAP代码表,则实现方法如下:
a).新建一个数据集(ds2),这个数据集有两个字段,一个是code,一个是name
b).在需要字段翻译的单元格中,设置‘标题’属性,输入公式=select('ds2','name',{$get('ds2','code')=cellvalue()})
2.16 让自定义参数页面访问报表时也出现进度条
在UniEAP Report中,如果使用报表自动生成参数页面,或者报表钻取功能,都会出现进度条,而在自定义的参数页面,如果访问/Report-ResultAction.do时,却没有进度条。报表提供了/Report-Guage.do这个Action,功能为带进度条显示报表,将上面的Action换成这个就可以了。
2.17 键盘快捷翻页功能
通过使用键盘的方向键做报表的快捷翻页操作,其实现方法如下:
在报表的unieap/pages/report/js/report.js 文件最后面,加入如下代码即可:
//以下为增加键盘翻页操作,如果不需要该特性可以将其删除。
NeuReport.addOnLoad(
function(){
var nextpage = document.getElementById('nextpage');
if(nextpage){
var body = document.getElementsByTagName('body')[0]; body.onkeydown=keydown;
window.focus();
body.focus();
}
}
);
function keydown(){
var resultForm = document.getElementsByName('resultForm')[0];
var e = (typeof event!='undefined')?event:arguments[0];
var code = e.keyCode;
if(code==39||code==40){
var nextpage = document.getElementById('nextpage');
if(nextpage){
var command = nextpage.getAttribute('onclick'); eval(command);
}
}
else if(code==37||code==38){
var prepage = document.getElementById('lastpage');
if(prepage){
var command = prepage.getAttribute('onclick');
eval(command);
}
}
}
【注意】在报表加载后,这里增加了一个报表焦点聚焦的动作,这样键盘的响应才能起作用。需要确认在点击相关菜单后,没有其他与之相冲突的其它键盘事件。
2.18 报表单元格内容根据条件动态设置文件加粗效果
公式标签页中有一个字体样式属性,在该属性中输入公式,返回值列出如下:
private static final int NORMAL = 0;
public static final int BOLD = 1; //加粗
public static final int ITALIC = 2; //倾斜
public static final int UNDERLINE = 4;//下划线
public static final int STRIKEOUT = 8;//删除线
public static final int ALL_FONTSTYLE = 15;
将以上的值转为二进制后看一下,是按照二进制位来标记的;比如只需要加粗,那么返回1就行了,例如:
=case(cellvalue()=2,1,0) 这个公式的意思是,当前单元格值为2则加粗,否则不加粗
2.19 Report解析sql报错的问题
带参数的复杂SQL的处理分两种情况
1.设计器解析出错:
设计器解析是为了能够获取sql中查询的所有字段信息,而这些信息是和条件无关的,在过于复杂无法解析通过时,可以将带参数的sql删除,然后解析即可成功,解析到字段后,再增加这些条件。这个过程不影响执行结果的。
2.引擎解析出错:
这种情况仅发生在sql中存在参数,但是参数却为空的时候,这种情况下,定义SQL中带参数的条件时,将参数所在的条件范围使用{# #}符号括起来,这个在《工具手册》中可以找到详细说明。
2.20 在页面中嵌入一张报表
每张报表就是一个Html页面,你可以在任意的页面框架中嵌入报表的html页面;每张报表都有唯一的Id来标识,在页面菜单、超链接、按钮、Iframe等地方访问URL如下:
1.带内置参数页面访问地址:
/Report-EntryAction.do?reportId=id
2.不带内置参数页面访问地址:
/Report-ResultAction.do?reportId=id&yourParam1=1&yourParam2=2
3.带进度条不带内置参数页面访问地址:
/Report-Guage.do?reportId=id&yourParam1=1&yourParam2=2
【注意】如果在UniEAP V4单帧菜单框架中嵌入报表需要追加一个参数iframe=true。
另外,如果使用自定义的jsp页面作为报表的参数页面,需要参数页面的参数提交给报表并显示,这种情况有两种实现方法:
方法一:URL方式,将jsp页面上的参数名称以及参数值拼接到URL的后面,比如:/Report-ResultAction.do?reportId=id&yourParam1=1&yourParam2=2,但这种方式需要处理中文参数的转码,否则会出现中文乱码问题,具体的转码方法可参考《二次开发手册》中的第10章。
方法二:通过form的submit方式,将参数提交给/Report-ResultAction.do?reportId=id这个Action也可以。
更详细的介绍请参考《UniEAP Report最佳实践之——报表页面集成到业务系统页面中》
2.21 去掉报表生成的工具栏和分页栏
1.工具栏
a) 如果是选择性的去掉某些工具栏图标,可以在报表设计器中‘页面标签’属性页设置
b) 如果是希望所有报表都不显示任何工具栏图标,可以修改ClientShow.jsp,将对应的 工具栏的页面元素删除掉。
2.分页栏
a) 分页栏也可以通过报表设计器中设计去掉,在报表设计器的‘导出设置’属性页面中,有一个属性为‘每页行数’,设置为-1,那么就是不需要分页,这时就不显示分页栏了。
b) 如果希望所有页面都不显示分页栏,即使有多页报表,也只显示第一页的话,把ClientShow.jsp中的这个标签删除
2.22 报表中定义的logo图片的统一替换
报表有三种方式(DBPicture、FilePicture、本地图片上传)来嵌入图片
1.如果是‘本地图片上传’方式做的,所有报表必须重新改一遍;
2.如果是用DBPicture做的,可以直接将DB里那个图片换掉;
3.如果是用FilePicture做的,那么直接换掉对应地址那个图片就行了。
2.23 一张复杂的组合报表的定义方法
这个报表第一反应是用子布局来解决,但是尝试后发现,单纯的子布局解决不了这个问题下面将这个表按照逻辑划分成5块,从左到右,从上到下依次编号1、2、3、4、5。
当使用子布局定义2、3两块的时候发现了问题,如果报表中仅有2、3两块的时候,是没有问题的,但是当出现其他块的时候,会出现布局错乱的问题
原因为当子布局2进行横向扩展填充的时候,会发现右侧存在一个子布局单元格(即是逻辑块3),这时需要将逻辑块3向右推,也就是在2、3块之间插入行,这会造成逻辑块1被割裂
解决办法,逻辑块2、3采用一个子布局内来实现,虽然两个子布局间没有什么关系,但将两组数据分别编号,按照编号相等的方法进行关联(这里是参考了多源分片报表的思想,认为2、3逻辑块是一个多源分片报表)
2.24 带分页的列头排序功能
目前用报表函数sortTable只能实现当前页的排序,即先分页后排序。
要实现带分页的排序,可以通过扩展方式实现
扩展思路如下:
1.将sql中order by 后面的字段名称设置为一个field类型的参数(这里取名为 orderColumn,则sql语句为 select .... order by $orderColumn
2.在报表js函数体中实现一个js函数,function orderThis(orderColumn),该函数逻辑为点击该列头是,传递一个排序列名称的参数给Report-ResultAction.do并重新生成一张报表
3.在列头的单元格的左键单击事件中,定义响应orderThis('date')这样的事件
这样报表运行时,点击某设置了可以排序的列头时,会响应实现的js函数方法,重新按照参数中指定的排序字段重新生成报表,就实现了你要的排序效果。
2.25 扩展UniEAP Report中的公式
当UniEAP Report内臵的公式不能满足您的需求时,UniEAP Report允许对公式扩展。增加自定义公式只要实现FormulaExecuter接口, 并在report-formula.xml中添加函数的声明。 接口的定义如下:
package com.neusoft.report.engine.formula; import com.neusoft.report.engine.util.DataValue;
public interface FormulaExecuter
{ public DataValue compute(Calculater calculater, DataValue[] parameters); }
FormulaExecuter接口中只包含一个compute方法,该方法有两个参数:
其中Calculater是执行函数的句柄,是为了支持在某个函数中需要执行其它函数而设计的;第二个参数是使用公式时传入参数的数组,是DataValue类型,DataValue是UniEAP Report对支持的数据类型的包装,可以是基本数据类型,也可以是复杂的数据结构类型。
扩展公式的步骤如下:
1.编写公式实现类用来进行自定义的计算
2.配置report-formula.xml文件
【注意】为了系统升级的方便,建议不要更改UniEAP Report提供的标准函数的函数
详细内容可参考《UniEAP Report二次开发手册》
2.26 FilePicture公式说明
FilePicture公式在报表3.3和之前的版本中只支持一个参数,也就是图片的URL地址,当该URL地址的图片不存在时报表就会抛出FileNotFoundException,当图片不存在时整个报表就都不能查看了,这样的设计非常不友好.因此在报表3.4版本上我们对FilePicture公式进行了修改,增加了一个默认图片Url参数,当第一个参数对应的图片不存在或者有错误时使用默认图片URL来加载图片.
公式格式:
FilePicture(pictureUrl,defaultUrl,codeType)
目前支持有效的URL包括HTTP、HTTPS;服务器端绝对路径;服务器端相对于web服务器的相对路径。
参数说明:
- pictureUrl: 文件位置,可以是有效的URL,服务器端绝对路径,服务器端相对于web服务器的相对路径。需要说明的时对于相对路径,如果服务器是windows路径名以\\开头,如果是Unix,以//开头。
- defaultUrl: 默认图片位置,格式与pictureUrl相同,当pictureUrl图片不存在时,返回defaultUrl所对应的图片。
- codeType:类型为0代表二进制图片数据,类型为1代表base64编码。
2.27 提示信息随数据变化的悬浮窗功能
经过一些二次开发可以达到这样的效果,但需要一些js以及ajax相关基础。
建议实现方法:
打开unieap/pages/report/js/report.js 文件,看showTitle(text, event, width) 这个方法,将这个方法进行修改即可。
text即为报表设计器中设置的提示内容,为了取值方便,可以设置为自己取值时需要的参数。
在这个方法中,可以将你自己配置的text作为参数向后台发送一个ajax请求,将你要的数据提取出来,显示在页面上。
更进一步,为了避免由于修改report产品源码而导致升级兼容性问题,可以通过在clientShow.jsp中最后引入js同名函数showTitle的方法来覆盖原来方法的方式来做。
2.28 报表SQL类型数据集中包含<非必填参数>时,报表执行报错的解决办法
参数经常要用到SQL数据集中,在SQL语句中充当条件,甚至充当查询列名。有些参数允许用户不添,为非必添参数,有些参数要求用户必须填写,为必添参数,当存在非必添参数时,使用方法略有不同:
存在非必添参数
SQL语句中使用非必添参数的方法为{# 参数表达式 #}、{@参数@},例如:select * from employee where {# $a=1 #} and {# birthday < to_date($b,’yyyy-MM-dd’) #} {@group by {@ $employeeId,@} {@$name@}@}。
简单来说,参数为空时{#... #}在实际运行中被替换为“1=1”,{@...@}在实现运行中被替换为“”。使用时,可以根据此原则来写SQL语句。
2.29 使用的UniEAP Report版本license过期的解决方法
请您通过邮件联系report@neusoft.com,以索取《UniEAP Report许可证申请表》,请将填写完整的《UniEAP Report许可证申请表》提交给report@neusoft.com,会有专人协助您申请符合贵项目使用需求的UniEAP Report license。
2.30 通过浏览器浏览报表结果时,会提示找不到数据源,而在报表设计器定义数据集时无错误,并可以解析出数据集字段。
请检查报表设计器所连接的应用服务器地址与浏览器端访问的应用服务器地址是否一致。
2.31 新建数据集时,数据源下拉列表中没有在数据库中新增的业务数据源
需要在报表引擎应用\WEB-INF\conf\unieap\unidataset目录下的datasource.xml文件中添加 对应的数据源配置信息。
更详细内容参考《UniEAP Report最佳实践之——配置数据源》
2.32 报表支撑数据库为DB2,发布报表错误
在报表设计器中上传报表时,提示如下图save4信息,然后提示上传成功,通过浏览器访问UniEAP Report时也能看到该报表节点,但是在浏览该报表时出错。
请将报表支撑数据库中 unieap-report-define表中的blob字段的大小调大到4M或以上。
2.33 在linux操作系统中浏览报表结果,出现乱码问题
在linux操作系统中浏览报表结果的时候,表头表尾的汉字显示为乱码,在数据库里面从blob中看显示的是汉字。
linux系统字符集编码问题,将其设置为GBK。
2.34 将在数据库中取出为空的数据显示为0
使用UniEAP Report提供的nvl公式,例如单元格中的值属性中写=nvl(get(‘ds1’, ‘aaa’), ‘ 0’),则是对aaa字段的数据进行处理,如果为空,则显示为0。
2.35 单元格值属性定义中使用DBPicture或者FilePicture函数,但是显示为一堆乱码的问题
UniEAP Report支持jpg、png、gif、bmp等常见类型图片,此外对于数据库图片可以定义为blob类型,或者字符串类型(要求Base64编码)。该问题产生的原因通常可能是定义错误,如图片公式传递参数错误或者单元格没有定义为“图片”类型等。
【注意】修改了单元格类型后,需要重新定义单元格公式。
2.36 参数的模糊查询
将参数的数据类型设置为field,比如参数aa,设置成field 数据类型,
若数据集SQL中需要作为条件比较的字段为字符串类型,如下:
select * from product where {# name like '%$aa%' #}
若数据集SQL中需要作为条件比较的字段为数值类型,如下:
select * from product where {# name like %$aa% #}
依此类推……
2.37 报表页面中显示浏览器端用户填写的参数值
当没有在浏览器端填写参数值时,报表引擎将返回 null,例如参数名称叫aa,则将报表定义中单元格的值属性中写成=decode($aa,null,'全部','aa'),并且当用户没有在浏览器端填写参数值时,报表页面中显示“全部”字样。
2.38 数据集SQL中定义日期类型的字段与datetime数据类型的参数比较,报表展现时出错
因为报表工具中所定义的datetime数据类型与数据库中的日期数据类型是不完全一致的,以访问oracle数据库取数据为例,可以将参数的数据类型定义为string,在数据集SQL语句的条件部分中进行如下比较:
select * from orders where orderdate>to_date($orderdate,'yyyy-mm-dd')。
2.39 经过UniEAP Report解析数据的小数位丢失
因为数据库中设置的字段类型为number类型,而没有指定小数位,所以经过UniEAP Report解析成了整型,没有小数位。可以手动在数据集中将该字段的数据类型修改为浮点型,或者在数据库中修改指定该number类型字段的小数位。
2.40 集成了报表插件的Eclipse,看不到刷新服务库、发布报表这样的工具栏按钮的问题
工具栏按钮只有在报表的编辑界面打开时可见,可以先建立一张空白报表即可看到并使用这些按钮。
2.41 取得数据库中参数对应字段的null值
在SQL语句中不写参数限制,在设计器group或select过滤条件中写{case(isnull($param),isnull(&get('SQL','a')),&get('SQL','a')=$param)},这样,参数不写的话,取的是数据库中的null值。
2.42 自定义参数界面提示界面布局错误
在自定义参数界面用到的js中,若写入alert提示信息时有中文,则导致提示报表参数界面布局错误。
需要对该段中文进行base64转码。
2.43 使用checkbox类型参数传值
a)传值时格式为show=1:;2:;3,使用:;分隔;
b)传参时候,多值必须都在所定义值范围内;
c)$show取得的集合形式为(1,2,3);
d)两个checkbox互相传参时候,=openreport('reportid',box,replace(tostring
(&box),',',':;');
2.44 实现单元格扩展出的数据全部为空时,该列不显示,否则显示
列属性中使用公式=decode(isnull(cell('d5')),true,false,flase)。
2.45 过滤条件“某值不在某集合中”的定义
报表制作中遇到做限制条件“不在某集合中”,可用indexof(collection,obj)<0,如:sum(select( 'ds1', 'F_RULE_VALUE7', {indexof(&list('90','03,'06','70'),&get( 'ds1', 'WORK_ACTIVITY_NAME'))<0}, 'F_RULE_VALUE7 asc'));遇到“在某集合中”时除indexof公式外还可以使用in(cooleaction,obj)公式。
2.47 为报表授权之后,业务操作员查看报表,页面出错:不具有执行权限
超级管理员可以正常查看报表,报表发布正常,但业务操作员登陆业务系统后查看报表时,报以下错误:(1005)不具有执行权限。
发生这种情况的原因是:UniReport有自己的权限接口,而业务系统没有实现它,而是自己处理了报表模板的查看权限。
解决办法有两个:
一是实现报表的权限接口,具体可参见《二次开发手册》第4章报表权限类接口;
二是将是否使用报表默认权限更改为false。
文件位置: WEB-INF/conf/unieap/report/report-engine-config.properties,将com.neusoft.report.engine.security.used值修改为false。
2.48 用设计器连接集成后的应用程序的时候,提示连接不成功,后台报错
应用程序后台会抛出如下错误:
org.apache.catalina.core.ApplicationContext.log(ApplicationContext.java:676) >> StandardWrapper.Throwable
java.lang.NoClassDefFoundError: javax/xml/rpc/encoding/SerializationContext
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1853)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:875)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1330)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1209)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at org.apache.axis.configuration.FileProvider.configureEngine(FileProvider.java:171)
at org.apache.axis.AxisEngine.init(AxisEngine.java:155)
at org.apache.axis.AxisEngine.<init>(AxisEngine.java:139)
at org.apache.axis.server.AxisServer.<init>(AxisServer.java:87)
at org.apache.axis.server.DefaultAxisServerFactory.createServer(DefaultAxisServerFactory.java:109)
at org.apache.axis.server.DefaultAxisServerFactory.getServer(DefaultAxisServerFactory.java:73)
at org.apache.axis.server.AxisServer.getServer(AxisServer.java:72)
at org.apache.axis.transport.http.AxisServletBase.getEngine(AxisServletBase.java:183)
at org.apache.axis.transport.http.AxisServletBase.getEngine(AxisServletBase.java:149)
at org.apache.axis.transport.http.AxisServlet.initQueryStringHandlers(AxisServlet.java:954)
at org.apache.axis.transport.http.AxisServlet.init(AxisServlet.java:169)
at javax.servlet.GenericServlet.init(GenericServlet.java:212)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1139)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:791)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:127)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
原因是lib中少了jaxrpc.jar。
2.49 用发布报表失败,提示oracle.SQL.blob.incompatible with oracle.SQL.blob
因支撑数据库的表空间不足引起,需要扩大表空间大小。
2.50 在浏览器端点击打印按钮后弹出另存为页面,名字默认为UniEAP Report Printing.mdi
因为客户端机器上安装了虚拟打印机,而且电脑系统默认指定为这个虚拟打印机了。
2.51 UniEAP Report 是否支持Oracle的RAC
目前有2台数据库服务器 10.50.5.1 实例名:lems1 服务名:lems 10.50.5.2 实例名:lems1 服务名:lems 。程序连接RAC的JDBC字符串如下: jdbc:Oracle:thin:@(DESCRIPTION=((ADDRESS=(PROTOCOL=TCP)(HOST=10.50.5.1)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=10.50.5.2)(PORT=1521)) (FAILOVER=yes)(LOAD_BALANCE=yes)(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=lems)))
方法一:配置connection-config.xml文件,使用c3p0连接池,在url中使用上面的字符串。
方法二:将应用服务器数据源配置使用RAC,然后让connection-config.xml通过JNDI的方式使用应用服务器数据源。
数据源配置方法可参考《UniEAP Report最佳实践之——配置数据源》
2.52 根据情况在报表中显示对号或者checkbox
可以通过case函数来实现,如:=case(mod(cell('b9',null,''),2)=1,'□','√')。
2.53 单元格数据值很长时,页面显示效果问题
将数量列的格式设置为显示4位小数,但报表展现时单元格被拉得很大。经过排查为数据本身很长,而又无法先通过SQL截断,并且小计和合计是通过报表自己运算的,这种情况如何解决?
对单元格的值通过公式来进行格式化,如:NumRound,toString等,而不需要在格式页设置,然后再设置"文字适应边框"。
2.54 UniEAP Report如何支持电子印章
请参考《UniEAP Report V4.4 图章功能使用手册》
2.55 报表的单元格如何链接到某个jsp页面或某个action
单元格超链接中的地址写unieap/pages/report/Main.jsp(或Report-Main.do)。
2.56 Web页面显示的总页数不准确
Web页面显示的页数当出现分页干扰因素[隐藏行、图片、图表、分页符(格上分页、格下分页)、分栏]时,为了提高报表展现速度,实质上显示的总页数仅是一个估算值,在向后翻页的过程中,会对这个页数不断的修正。如果需要严格保证总页数的正确,则可以在制作报表时,在报表属性中将‘预计算总页数’设置为‘是’。如果对总页数要求不严格,建议不选中此项,因为这会影响到报表的展现速度。
【注意】无分页干扰的报表不存在这个问题。
2.57 如何解决报表展现时出现错误:StackOverflowError
错误信息为:
javax.servlet.ServletException: Servlet execution threw an exception
com.neusoft.report.sample.SetUidFilter.doFilter(Unknown Source)
com.neusoft.report.sample.AccountFilter.doFilter(Unknown Source)
root cause
java.lang.StackOverflowError
java.util.HashMap$ValueIterator.<init>(HashMap.java:869)
java.util.HashMap$ValueIterator.<init>(HashMap.java:869)
java.util.HashMap.newValueIterator(HashMap.java:892)
java.util.HashMap$Values.iterator(HashMap.java:955)
com.neusoft.report.engine.runtime.layout.InstanceCell.<init>(Unknown Source)
com.neusoft.report.engine.runtime.RuntimeEntityManager.newInstanceCell(Unknown Source)
com.neusoft.report.engine.runtime.util.Define2Instance.a(Unknown Source)
原因:一般情况下,是报表制作的有问题,有单元格自己依赖自己,或者循环依赖的地方,导致堆栈溢出。
2.58 如何在报表公式中拼接单引号“’”
解决方案:单引号作为报表公式中String类型参数的声明标识,必须成对存在,如果直接在参数中拼接,会导致Antlr解析失败。可采取以下方案进行规避:
1.声明一个字段、隐藏类型的参数SINGLE_QUOTES,并设置默认值为“’”:
2.在公式中对于需要单引号的参数使用Concat公式进行拼接,比如:=Concat(‘Test(’, $SINGLE_QUOTES, ‘DS1’, $SINGLE_QUOTES),实际上在替换后=Test(‘DS1’)。
2.59 系统设置单点登陆时,调用打印出现异常http.strictPostRedirect
问题现象:报表打印时报java.security.AccessControlException: access denied (java.util.PropertyPermission http.strictPostRedirect read)
解决方案:(Report3.3最新版本中不存在该问题)
1.修改PrintApplet中获取系统路径后自行拼接,避免因单点登陆,Url被重定向到其他路径;
2.java.policy中加入 permission java.util.PropertyPermission "http.strictPostRedirect", "read";
有可能单点登陆/代理等场景下,报表在Applet中拼接Url,导致Cookie信息丢失,在拼接时使用jaws.jar,获取当前的Cookie信息拼接到Url中。
2.60 调用打印时异常 java.net.SocketPermission
问题现象:报表打印时,异常:java.net.SocketPermission: XX(IP) connect, resolve等
解决方案:在相应的JRE中(java.policy)配置connect、resolve权限,比如:permission java.net.SocketPermission ":","accept,connect,resolve";或者配置permission java.security.AllPermission。
【注意】经验证,不同的JRE版本,对一些安全的限制会有一些差异,有些JRE不需要设置也不会有问题。
2.61 报表启动时调度模块报错:找不到名为“UNIEAP”的数据源
这里”UNIEAP”为调度配置的数据源,在unieap-scheduler.properties中配置,可能为其它名称
解决方案:
首先检查一下connection-config.xml中有没有配置相应的数据源,如果没有请添加,如果没有可以查看web.xml中关于调度的配置,configScheduler这个Servlet有一个参数
2.62 如何在Web页面展现时,支持鼠标悬置时高亮显示行
在文件\unieap\pages\report\jsp\show\ClientShow.jsp中,将以下CSS代码的默认注释去掉即可。
/* 排除非数据区和被冻结的单元格
div[id^='innerDiv'] tr.data:hover td {
background-color: #ecfbd4;
color: #000000;
}
*/
效果如下,当前鼠标放置在“南京”行:
2.63 sql解析不通过怎么办?
设计器解析是为了能够获取sql中查询的所有字段信息,而不是执行sql文,所以即便存在解析不通过的情况,也并不代表报表的定义有问题。
带参数的复杂SQL的处理分两种情况:
1.设计器解析出错:
字段信息是和条件无关的,在过于复杂无法解析通过时,可以将带参数的sql删除,然后解析即可成功,解析到字段后,再增加这些条件。这个过程不影响执行结果的。
比如select * from product where type = $type,解析的时候应该先把where type = $type去掉。
2.引擎解析出错:
这种情况仅发生在sql中存在参数,但是参数却为空的时候,这种情况下,请确认该参数的值是否可以为空。如果不能为空,就要确保提供参数值;如果可以为空,建议将参数所有的条件范围使用{# #}或{@ @}符号括起来,这个在《UniEAP Report最佳实践之——几种特殊参数的使用方法》中可以找到详细说明。
datetime数据类型
因为报表工具中所定义的datetime数据类型与数据库中的日期数据类型是不完全一致的,以访问oracle数据库取数据为例,可以将参数的数据类型定义为string,在数据集SQL语句的条件部分中进行如下比较:
select * from orders where orderdate>to_date($orderdate,'yyyy-mm-dd')。
2.64 在编辑报表过程中,删除或者改错的报表如何恢复?
针对报表恢复的问题,有两种解决方法:
1.从数据库导入
在报表导航器窗口中,单击右键,选择 点击,如下图:
选择所要恢复的报表在数据库中存储的位置,点击 ,如下图:
进入如下页面,文件位置根据实际情况自行选择,点击 即可。
2.从本地恢复
选择导入的目标位置,单击右键,选择 中的
点击,如下图:
在 中,根据实际情况自行选择所要恢复的报表的时间版本,点击
即可。如下图:
2.65 如何配置错误页面可以显示明细
在\WEB-INF\conf\unieap\report\report-engine-config.properties文件中,
#是否在前台页面上显示错误的详细信息,默认为不显示
show_error_msg_detail = false
将false改为true,则错误页面可以显示明细。
如下图所示,当设置为true时,会多出一个“显示信息”的按钮,单击该按钮即可显示出详细的错误信息,包含异常堆栈:
2.66 平台V4情况下,如何进行URL授权访问
在平台V4情况下,希望不事先进行登录操作,而是通过URL的方式直接打开报表。如果是要让别的系统来访问这个报表(且没有单点登陆),报表可以直接一个链接访问。
如果使用这种直接访问的方式,则要在url的后面把用户账号和密码的信息也加入其中。具体的写法如下(暂时先不考虑密码明文、密文、安全和角色切换等问题):
在URL后面拼接eap_username=admin&eap_password=1&eap_authentication=true即可。
2.67 两端对齐和分散对齐的区别及注意事项
在报表设计器中可以为文本单元格指定对齐方式,其中水平对齐方式中有“两端对齐”和“分散对齐”,为避免用户混淆,这里简单说明一下两者的区别:
分散对齐:文字会按所在单元格的宽度均匀分布,以保证单元格两端无空白。
两端对齐:当文本填满整行时相当于分散对齐,不满一行时相当于左对齐。
具体可参考Office Word中这两种对齐方式的效果。
【注意】当设置为两端对齐时,程序需要比较文本内容的实际宽度和单元格的宽度,以决定是否使用分散对齐,因为不建议对大量单元格应用两端对齐方式,否则可能会影响性能。实际上当文本只有一行时,完全可以使用左对齐或分散对齐达到想要的效果。
两端对齐的一个典型应用场景是使用SplitByLine公式时,动态扩展出的一个段落会包含多行,此时可以使用两端对齐,以使除最后一行外的所有行能够首尾对齐。
2.68 报表支持背景透明
当报表在saca dataviz图册里展示、或者集成到第三方业务系统时,为了展示效果,可能会有报表背景透明的需求,报表背景透明设置方法如下:
表格区域外设置透明
单元格设置背景透明
2.69 其它
- 利用标尺以及工具栏上的 <插入基准图片>按钮有助于提升制表的精准度;
- 利用样式管理以及模板制表功能有助于提高开发效率;
- 隐藏格的使用:对于占比,最好定义一个隐藏格sum;对于存在不符合依赖规则确有依赖需求的单元格问题,可以通过定义符合依赖规则的隐藏格来解决;
- 慎用合并单元格
- 合并单元格的最左/上的格子所在的行列不可以设置为隐藏。
- 报表引擎配置文件中设置export_decorate=1,2 可以使得 excel 和 pdf 导出的结果附带隐藏的信息(默认为用户名、访问地址及导出时间)。
- 设置每页显示行数不计入标题的行数:报表设计器中有一个属性为“标题计入行数”,可以设置为‘是’或者‘否’。
- 对于需要一页显示所有内容的报表,那么就不需要显示“当前第一页,共一页”的翻页按钮。可以通过“导出设置”的“每页显示”行数来配置,当配置为-1是,意思是不分页,那么翻页按钮就没有用,也就不显示了。
- 在报表中对某字段的值进行排序,可用报表的select公式,用法:=select( 'ds1', 'count',null, 'count desc')或=select( 'ds1', 'id',null, 'count desc')。字段为‘count’。
- 集成了UniEAP Report插件的eclipse启动出错,找不到报表资源。原因是:eclipse需使用JDK1.5或以上版本。
- 选中多个单元格合并,然后右键删除行或者列,删除的是选中的单元格所占的所有行或者列。
- 在报表属性中将“类型”属性设置为“查询”,可以使参数页面与报表结果页面显示在同一页面中
第3章 报表打印导出
3.1 打印
3.1.1 打印报表时附加打印额外的封面
打印一部分报表时,需要打印一个封面页,而这个封面页不需要在web页面查看显示。
1.在UniEAP Report中,定义一张报表作为封面页。报表显示的Action,在struts的配置文件配置为不同的,比如原来为Report-ResultAction.do,那么配置为Report-ResultAction2.do,同时这个action提交的jsp也不同为ClientShow2.jsp
2.在ClientShow2.jsp中,拷贝ClientShow.jsp的内容,将其中的打印taglib删除,自己定义打印按钮,并可以使用原来的打印按钮图片,点击这个按钮响应以下url即可。 http://127.0.0.1:8080/report/unieap/pages/report/jsp/show/Print.jsp?reportId=report1_id,report2_id&newReport=true&report1_param1=value1&report1_param2=value2&report2_param1=value3
3.提交url中的参数有2种,一种是报表必须的参数,一种是业务参数:
- 报表参数
reportId:当前报表Id,通过document.getElementById('reportId')获得;封面报表Id,想要打印的封面报表Id,当然是已知的。报表Id使用逗号分割,顺序就是打印预览时显示的顺序。 - 业务参数
多报表打印是不能从缓存中读取报表的,这种情况下,包括那张业务表也需要重现生成。这就需要将业务参数重新传进来一次。这里就要实现将业务参数传递到ClientShow2.jsp页面中保存。
建议的实现方法如下:
在ClientShow2.jsp中写一段java脚本,实现将当前报表获得到的参数名称和参数值保存成一个字符串,比如调用request.getParameterMap()方法既可获得(过滤掉报表参数)。
然后将这个字符串保存在ClientShow2.jsp的隐藏域中,比如最后通过document.getElementById('bizParams')获得该参数串,拼接在url后。【注意】如果参数中含有中文,还要注意将参数值编码)
3.1.3 直接打印功能
在页面上点击打印按钮,就直接打印,不出现打印(jsp/show/Print.jsp)页面。
3.1.4 打印时在页眉页脚中显示页数与页码
在页眉或页脚中使用&[PAGE_COUNT]、&[PAGE_NO],它们含义分别是页码总数、当前页码编号。
例如:=concat('第','&[PAGE_NO]','页') ,还可以直接写为 第&[PAGE_NO]页。
这样在打印出来的报表页眉页脚中就可以显示页码与总页数了。
在打印时,如果报表页面设置中上下边距过小,会导致页眉页脚无法显示,调整上下边距后即可将页眉页脚显示出来。
3.1.5 主从表打印问题
一个页面分成两部分,数据来自两个表,两边数据的数量不等。数量少的一面用空白表格填充。可采用定义两个子布局,通过补充空白表格,可用公式做动态判断比如=to(1,5-count(cell('a1'))),这个公式定义在A2格里,A1下面的一行。意思是如果A1扩展不够五行,就补足为五行。
3.1.6 UniEAP Report部署在WebLogic11上后打印报表异常的解决方法
项目中使用weblogic11进行部署,部署在windows2008server以及linux系统上。在打印时applet报出
java.lang.Exception: java.security.AccessControlException: access denied (java.util.PropertyPermission http.strictPostRedirect read)这个异常。
修改了客户端的jre的java.policy文件加入
permission java.util.PropertyPermission"http.strictPostRedirect","read,write";之后,applet会报出invalid stream header异常
1.invalid stream header问题解决方法:
问题的原因在applet中发给后台的请求session验证失败,被weblogic拦截,认为是未登录用户,而将登录页面作为打印数据流返回,因此报invalid stream header的异常。也就是说session丢失了。解决方法:
- 方法1: 修改代码,手动将jsessionid拼接在applet请求的url后方后问题解决。
- 方法2:weblogic中有一项配置,在weblogic.xml中加入如下配置也可解决session失效的问题:
<session-descriptor>
<cookie-http-only>false</cookie-http-only>
</session-descriptor>
2.访问被拒绝问题(access denied)解决方法
经过测试后结论是这个错误和jre的版本有关,Sun不同的jre小版本对applet资源访问的默认授权不一样,我们认为这是jre的bug。选择合适的jre版本可以避免该错误。【jre版本是(build 1.6.0_29-rc2-b32),按照该方案修改后,不修改java.policy文件,就提示重定位被阻挡错误,修改该文件,就提示流错误,把jre修改为(build 1.6.0_10-rc2-b32) 版本后,没有修改java.policy文件,再次测试通过】
3.1.7 UniEAP ReportV3.4中使用flash打印页面时提示Error#2032
经过查找资料和分析,发现在某些flash player插件下会出现这个问题,需要替换打印控件的swf文件才行,这需要和我们联系(仅限于3.4版会出现这个问题)获取补丁文件。
引起问题的原因为:
Flex在Build的时候有两种方式 , 一种是RSL ( Runtime shared library ),另一种是Merged into code. 使用RSl,两者的最大区别在于第二种方式在编译时把依赖于Flex框架相关的文件一起编译到源文件的swf中。报表现在版本中使用的是第二种方式Build,可能在3.4中使用了第一种方式,这样可能导致无法加载框架文件(.swz文件),这个跟Flash Player有关,如果没有框架文件就会报这个错。使用第二种方式Build后,就没问题了
3.1.9 奇怪的invalid stream header
环境:Windows/Tomcat5.5/Oracle 10g
在报表打印功能,遇到如下问题:(版本:UniReport3.3(2010-01-06)):
所有报表在应用工程里,“打印”和“一键打印”功能报错:java.io.StreamCorruptException:invalid Stream header。
发现是在print.jsp页面JS方法print():document.getElementById('PrintApplet').print()调用applet进入异常。
以下是问题分析过程:
第一回合:
收到这个问题,我的第一个反应是设个问题发生在weblogic11上的问题,可以通过设置weblogic.xml的cookie-http-only配置项来解决,applet请求session丢失,导致了applet获取到的不是打印文档而是一个登录页面,在object的反序列化时出现的问题,建议修改cookie-http-only方式解决。
返回结果:问题没有解决,并且在tomcat下也会出现这个问题
第二回合:
觉得有点奇怪,在tomcat下还从来没有发生过这个问题,尝试在applet的请求中手动拼接jsessionid来尝试解决,打个补丁过去。
返回结果:发给客户测试,现象依旧。
第三回合:
将applet加上了多处输出日志,打印出是否获得sessionid,以及打印url,打印出获得的对象流。
返回结果:详见下图,sessionid获取正常;url拼接正常;输出流为一些不可识别编码,可以断定,报表内容已经获取到,可为什么在反序列化时出错呢?
第四回合:
综合以上分析,在正常获取到报表打印序列化对象后,仍然出现反序列化异常,最大的可能就是数据流被篡改。因此建议用户检查自己的所有过滤器或者确认是否使用了特别的sso实现?
问题最后解决:原因是用户为了解决IE8浏览器的兼容性问题,截取了所有的html信息,在html头中加入了,而报表的打印数据流也被认为是普通的html,就这样被篡改了。
3.1.10 在某些机器上报表打印功能不好用
请检查浏览器端是否已安装jre环境,因为UniEAP Report打印报表需要jre环境。
检查浏览器端是否已安装jre环境的方法如下:
点击浏览器的菜单栏”工具”>”internet选项”,在”高级”选项卡里可以找到Java(Sun)的树节点,检查是否勾选”将JRE Versionxxx用于
3.1.11 解决大数据量列表式报表展现时的内存溢出
大数据量列表的展现可以使用按段取数据的方式,具体使用方法请阅读《UniEAP Report工具使用手册》。
3.1.12 将报表结果页面中的导出或打印按钮去掉
在报表设计器的报表属性中有“页面标签”选项卡,可以在此进行设置,如下图:
3.2 浏览器端点击打印按钮时没有反应
因为客户端机器没有配置任何打印机,所以调用本地默认指定打印机来打印时,取不到打印机。
3.3 导出
3.3.1 UniEAP Report不展现直接导出Excel或者pdf文件
在web页面上不展现出报表,而直接导出Excel或者pdf文件的方法:
1.通过提交请求给地址
http://serverurl/Report-ExcelAction.do?reportId=xxxx&newReport=true&otherParam=yy即可直接将报表导出为excel文件;
- reportId是报表id,调用相应的报表,
- param是报表中的参数名称,
newReport=true代表重新生成报表而不从缓存中读取,这个参数是必须有的。
通过提交请求给地址
http://serverurl/Report-PdfAction.do?reportId=xxxx&newReport=true&otherParam=yy即可直接将报表导出为pdf文件。
3.3.2 将分页报表中每一页导出为Excel的一个sheet
在报表设计器中“报表属性”选项卡中,Excel导出设置为“导出多工作表”,这样就可以把分页后的报表导出为多sheet的Excel了,每页导出一个sheet。
实际应用:可以实现将第个月的日报按天导出成多sheet,也就是将每天的日报导出为一个sheet页.首先按天进行分页,然后设置"导出多工作表"就可以了。
3.3.3 导出的pdf中文显示为‘口口’
pdf中出现方框,是因为在导出pdf是需要读取服务器中的字体库,如果在报表模板中的字体在服务器上没有就会出现方框。
解决方法:
- 将报表模板中的字体设置为服务器上有的字体
- 给服务器安装缺失的字体。
详情参考《UniEAP Report 部署文档》
第4章 报表集成部署
4.1 使用cas做SSO验证,设计器如何发布报表
报表的设计器是通过webservice的方式发布报表,cas的验证机制比较复杂,现在还不能直接通过cas验证,提供一个建议的解决方法:
对于cas的过滤来说,你可以自定义一下,配置一条规则,对报表的webservice地址(/services/* )不进行过滤就行了。出于安全考虑,可自己再实现一个过滤器来做报表发布的权限验证。
4.2 Eclipse集成UniEAP Report环境要求
- Eclipse版本需要V3.4;
- JDK1.5或者以上。
UniReport相关插件的ID:
com.neusoft.unieap.workshop.common、
com.neusoft.unieap.workshop.help、
com.neusoft.unieap.workshop.library、
com.neusoft.unieap.workshop.model、
com.neusoft.unieap.workshop.dataset、
com.neusoft.unieap.workshop.report.editor。
4.3 Ecelipse如何集成UniEAP Report插件
解决方案:
1.以plugin形式加载:将UniReport相关的插件拷贝到Eclipse的plugins目录下;
2.以link方式加载:在Eclipse的link目录下,创建UniReport的link文件,指定UniReport插件的路径。
【注意】:集成UniReport插件后需清空Eclipse的configuration目录下缓存,或者以-clean方式启动
4.4 如何升级UniEAP Report插件版本
解决方案:删除Eclipse中已有的报表相关插件,拷贝新版本插件,以清空configuration/-clean方式启动。
在UniEAP Reportt中,可能会遇到这种情况:用设计器修改发布的报表,在web端看到的还是没改之前。
这种情况一般为使用多个应用,连接同一个报表支撑库,使用报表设计器连接应用A上发布在库中的报表,在应用B上是不能同步看到的。在用B上如果想看到有两种方式能看到:
1.重新启动应用B
2.修改配置文件。report-engine-config.properties。 将默认配置
#definecache
com.neusoft.report.engine.rao.define.cache.DefineCacheFactory=com.neusoft.report.engine.rao.define.cache.SingleServerFactory
define_cache_size=100
修改为MultiServerFactory的配置
com.neusoft.report.engine.rao.define.cache.DefineCacheFactory=com.neusoft.report.engine.rao.define.cache.MultiServerFactory
define_cache_timeout=600
define_cache_size=100
这里默认配置不是多服务同步方式的原因是:默认配置保证报表运行最高效,每次检查服务之间的同步必然耗时又耗资源。
4.6 UniEAP Report部署后报错的处理
报表工程部署完成后,可能出现的错误及其处理方法:
1.任务调度模块报出如下错误:
java.lang.Excpetion:添加任务出错 Couldn't store job: Driver's Blob representation is of an unsupported type: oracle_sql_BLOB
这是由于在unieap-schedular.properties配置文件中有一项为org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
这个配置为quartz的任务存储驱动委托类名称,如果不是oracle数据库,或者数据库连接池使用了jndi等其它方式,都需要修改这个默认配置。视项目中的情况,修改为对应的类即可。
2.No such algorithm:RSA/NONE/OAEPWITHSHA1AndMGF1Padding
在windows tomcat 下好用,在redhat webligic 下控制台显示下列信息,页面显示“License not found”。
jar包冲突导致该问题,应该是某些包与Protection.jar、bcprovs-*.jar这两个jar冲突。建议检查lib下的jar有没有和这两个jar名称类似版本不同的jar。
如果找不到建议使用如下方法:
在eclipse中新建一个java project,然后将工程lib目录下所有jar,以及weblogic所有目录下以jar为扩展名的文件,全部拷贝到这个工程下,并加入到构建路径,然后在eclipse中使用ctrl+shift+t方式搜索以下的类:
com.jp.protection.security.BouncyCastleSecurityProvider
org.bouncycastle.jce.provider.JCERSACipher
这两个类有没有多个,冲突的jar将无处遁形了。
4.7 resin的连接池的配置
配置方法如下:
<jndi-connection name="UNIEAP">
<jndi-name>java:comp/env/UniEAPDSPool</jndi-name>
</jndi-connection>
<jndi-connection name="northwind">
<jndi-name>java:comp/env/northwindDSPool</jndi-name>
</jndi-connection>
4.8 后台报出缓存遇到并发访问
该问题不会影响任何操作。
这个问题出现的场景有两个:
场景一:
性能测试时:使用loadrunner做性能测试时,没有对缓存设置为变量,导致多次的并发访问都去读取录制脚本时的那个缓存,所以报错。
场景二:
如果使用3.3之前的版本,报表在导出文件时,没有进度条来禁用页面的所有操作。有时文件较大,短时间内文件没有返回并弹出下载页面,这时用户会再次点击导出按钮这时首次点击的那个线程就会抛出这样的异常,而保证最后一次点击可以返回。
4.9 集成后列表的执行权限
集成后只有在admin用户下能看到报表信息,其他用户显示‘不具有执行权限’,这是因为其他用户没有没有被赋予每个报表的执行权限,以下有两个解决方法:
1.关闭报表的权限校验,在report-engine-config.properties中配置,参考 《UniEAP Report集成手册》
2.项目中的用户信息与报表进行集成,使用报表提供的权限过滤机制,参考《UniEAP Report二次开发手册》
4.10 报表模板过大,发布时报错
一些复杂的报表,报表定义文件很大,最大的甚至超过了5M,当发布的时候总是报出java heap space的内存溢出错误,这是报表引擎的web service报出的,原因是由于堆内存不足,可以通过配置应用服务器的启动内存来解决。
拿tomcat来举例: 如果在eclipse中使用wtp插件来启动tomcat,则配置方法如下: run菜单->run configurations...选择运行的tomcat 项,在右侧的arguments中,添加VM arguments如下:
-Xmx1024M -Xms512M -XX:MaxPermSize=256m
重启tomcat就可以正常发布了,由于文件稍大,需要稍等一会后发布成功
【注意】VM arguments中添加的内容需要敲一个回车,重启一行,不能直接放在已有内容的后面
4.11 更换新的License后仍然提示License过期可能的原因
首先查看报表启动日志,日志中会包含下面一段信息:
************Report Engine License Information************
[Report Engine]: License Version: UniEAP Report 3.0 Professionnal Edition
[Report Engine]: License Type: Development
[Report Engine]: Validate Date: From 2012-01-09 to 2012-07-09
*********************************************************
三条信分别是License Version、类型和日期,主要看一下日期:
1.如果日期还是之前过期的时间那说明License文件没有替换成功
2.如果日期已经更新为新的License对应的日期,请先检查一下本地的系统时间是否正确。
排除上述两种情况后还有问题的话就是license文件本身的原因了,请将license文件及日志发给UniEAP Report实施人员进行解决。
4.12 “非法属性”的异常处理
这个非法属性的原因有两个:
原因一:引擎曾经升级,但是配置文件没有更新完整(report_property_V3.0.xml)
原因二:引擎和设计器版本不对应,使用的高版本的报表设计器开发的报表,在低版本的引擎中运行。
4.13 显示Oracle数据库中的clob字段
在UniEAP Report中,如果遇到数据库中有clob字段保存的字符串,直接使用get('dsname','clob_column')时,就会报错。clob字段不能像普通的字符串那样处理,在写数据集的sql时,将clob字段使用to_char函数转换为字符串即可。 比如:
select id,name,to_char(clob_column) from table_name
使用这个方法,clob内字符的长度需要在4000以内,如果长度超过这个限制,那么就需要自己实现公式了,可以参考blobText公式做实现。
4.14 使用填报功能时用多个DRM数据集将数据回填到多个表时报错
检查一下支撑数据库中drm_sys_connectpool表中maxinum值,如果数据集的个数比连接池maxinum的值大就会报出错误。
原因是每个数据集回填数据的时候都需要一个数据库连接单独运行,所以如果连接池的连接数比数据集需要的连接少就会报无法获得连接的错误.
4.15 UniEAP Report,在使用mysql数据库时,发布报表后名称为“???”
调整一下MySql中 mysql.ini中default_charset的配置,调整为utf8,修改后重启数据库服务。
4.16 SyBase15数据库存储过程数据源偶尔不可用
使用SyBase15数据库存储过程数据源,当存储过程写的比较复杂,存储过程中包含创建临时表,在临时表基础上查询数据时,就会出现不能返回数据集的情况.
通过对JDBC方式连接SyBase数据库进行验证,发现在调用存储过程的时候按下面写法:
statment.getResultSets();
返回结果为NULL.
通过下面方法调用可以返回ResultSet:
statment.executeQuery();
statment接口由SyBase驱动实现,推测该问题是数据库驱动引起的.
如果项目中需要使用SyBase15数据库的存储过程数据源(4.1.1以前版本),需要打补丁来支持.
4.17 报表最外层边框IE8下出现多余滚动条或最右侧无右边框
在V3.3以及之前版本中,报表中如果存在多个合并单元格时,就可能在IE8浏览器下报表的最外层边框出现多余的滚动条,或者最右侧无右边框,该如何解决?
解答:
这个是我们css样式的一个浏览器兼容性问题。 可在unieap/pages/report/jsp/show/ClientShow.jsp 的head中添加
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
这种方式来告知IE8浏览器通过IE7模式渲染,就可以解决这个问题。 在3.3版本之后已经通过修改CSS兼容性解决了这个问题。
4.18 报表集成后设计器连接服务器Non-serializable attribute Designer异常
在SSH框架系统中,集成3.3版本的UniEAP Report。集成后,启动服务,控制台中信息都正常,但是用设计器连接服务器时,报异常,异常信息如下:
- Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart). Attachment support is disabled.
- DesignerAgent is created.
- AxisFault:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.lang.IllegalArgumentException: setAttribute: Non-serializable attribute Designer
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:java.lang.IllegalArgumentException: setAttribute: Non-serializable attribute Designer
解决方法:
从异常上来看这个问题的原因是需要把Designer这个webservice远程调用的对象放在AxisHttpSession中,但是Designer没有实现java.io.Serializable接口。 这个比较奇怪的是以前为什么没有碰到过这个问题。 先尝试这样处理一下:
可去掉%Tomcat%\conf\context.xml下列的注释:
<!—
<Manager pathname="" />
-->
有些程序可能在上述方法修改后,还不能完全解决,需要查看项目里web.xml是否有
<distributable/>
另外,我们会在最新版本中为Desigenr实现java.io.Serializable接口,如果你的问题没有解决,我们给你提供一个实现java.io.Serializable接口的补丁
4.19 在linux+weblogic环境下报错Could not initialize class sun.awt.X11GraphicsEnvironment
详细错误如下:
java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11GraphicsEnvironment
java.lang.Class.forName0(Native Method)
java.lang.Class.forName(Class.java:169) java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:68) java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1135)
com.neusoft.report.engine.export.util.CellShapeAdjuster.<init>(Unknown Source)
com.neusoft.report.engine.export.split.SplitterHelper.getCellHeight(Unknown Source)
com.neusoft.report.engine.export.split.SplitterHelper.getScaleHeight(Unknown Source)
com.neusoft.report.engine.export.split.SplitterHelper.getRowInfo(Unknown Source)
com.neusoft.report.engine.export.split.LinageSplitter.split(Unknown Source)
com.neusoft.report.engine.export.html.HtmlExporter.makePage(Unknown Source)
com.neusoft.report.engine.export.html.HtmlExporter.buildHtml(Unknown Source)
com.neusoft.report.engine.export.html.HtmlExporter.export(Unknown Source)
com.neusoft.report.engine.core.NeuReport.exportToHtml(Unknown Source)
com.neusoft.report.server.util.ReportCreate.exportHtmlResult(Unknown Source)
com.neusoft.report.server.util.ReportCreate.generateRealTimeReport(Unknown Source)
com.neusoft.report.server.util.ReportCreate.generateReport(Unknown Source)
com.neusoft.report.server.view.ReportAction.generateReport(Unknown Source)
com.neusoft.report.server.view.EntryReportAction.execute(Unknown Source)
解决方法:
原因是由于Linux环境下图形处理都需要X Server服务,如果Linux上没有安装图形模块,则没有X Server服务;另外一方面,即使有X Server服务,在Linux系统内存不够的时候,也会出现此错误。
解决方法:使用JDK自带的图形处理服务。
具体做法如下:
编辑应用服务器启动脚本,在JAVA_OPTS中加上 -Djava.awt.headless=true即可。
4.20 UniEAP Report长时间不用导致业务数据查询失败或报表报500错误
两种错误的具体描述:
错误1:时间不使用后,再进行使用的话会报如下错误(如下),多次查询后恢复正常。
------------------------------------------------------------type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: javax.servlet.ServletException: net.sf.acegisecurity.AuthenticationServiceException:
**DrmException: DRM_R_1005 : 业务数据查询失败 :
**UDOLink OPException: I/O Error: Software caused connection abort: recv failed; nested exception is com.neusoft.unieap.service.orgnization.exception.DrmRunTimeException:
**DrmException: DRM_R_1005 : 业务数据查询失败 :
**UDOLink OPException: I/O Error: Software caused connection abort: recv failed
<c3p0-connection name="UNIEAP">
<url>jdbc:jtds:sqlserver://192.168.1.1:1433/uni</url>
<driverclass>net.sourceforge.jtds.jdbc.Driver</driverclass>
<user>sa</user>
<password>sa</password>
<min-pool-size>3</min-pool-size>
<max-pool-size>15</max-pool-size>
<checkout-timeout>0</checkout-timeout>
<max-idle-time>0</max-idle-time>
<idle-connection-test-period>0</idle-connection-test-period>
<test-connection-on-checkin>false</test-connection-on-checkin>
<test-connection-on-checkout>false</test-connection-on-checkout>
<max-statements>0</max-statements>
<max-statements-per-connection>0</max-statements-per-connection>
<acquire-increment>3</acquire-increment>
</c3p0-connection>
错误2:报表报500错误,具体错误如下:
HTTP Status 500 -
--------------------------------------------------------------------------------
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: javax.servlet.ServletException: com.neusoft.report.common.ReportException: (2003)报表描述信息操作失败;Io 异常: Connection reset
解决方法:
这个问题一般是由于数据库连接池的连接对象,在长时间不活跃,而被数据库强制回收。 这时,就会出现程序从连接池用拿到了一个无效了连接,而报出类似的错误。 这种情况一般发生在隔一段时间没有访问后,再次访问时比较容易重现。
这个问题可以通过两种方法解决:
1.修改数据库本身的配置来解决,配置连接永不超时即可,但是由于各种数据库的配置方法不同,需要查找自己使用数据库的配置方法;
2.连接池的配置来解决,修改connection-config.xml文件内容,主要为加粗部分,具体字段意义参考下面的说明:
<c3p0-connection name="XXX">
<url>jdbc:oracle:thin:@10.4.55.55:1521:unieap</url>
<driverclass>oracle.jdbc.driver.OracleDriver</driverclass>
<user>uuu</user>
<password>xxx</password>
<min-pool-size>3</min-pool-size>
<max-pool-size>15</max-pool-size>
<checkout-timeout>0</checkout-timeout>
<max-idle-time>0</max-idle-time>
<idle-connection-test-period>0</idle-connection-test-period>
<test-connection-on-checkin>false</test-connection-on-checkin>
<test-connection-on-checkout>false</test-connection-on-checkout>
<max-statements>0</max-statements>
<max-statements-per-connection>0</max-statements-per-connection>
<acquire-increment>3</acquire-increment>
</c3p0-connection>
关键值的解释如下:
checkoutTimeout:
当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。Default: 0
idleConnectionTestPeriod:
每x秒检查所有连接池中的空闲连接
maxIdleTime:
最大空闲时间,x秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0
testConnectionOnCheckout:
因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable等方法来提升连接测试的性能
testConnectionOnCheckin:
如果设为true那么在取得连接的同时将校验连接的有效性。Default: false
以下链接是相关参考资料: 连接最大空闲时间(MaxIdleTime)相关的配置,【ORALCE参考】
http://www.itpub.net/thread-14028-1-1.html
sqlserver内部的配置
http://social.msdn.microsoft.com/Forums/zh-SG/sqldatabaseengine/thread/029ad599-eaf9-4524-9773-fc62f2b85a64
http://blogs.msdn.com/b/sql_protocols/archive/2006/03/09/546852.aspx?wa=wsignin1.0
4.21 报表Log4j日志配置方法及查看引擎端的log日志
报表Log4j日志配置方法:
在Web应用的WEB-INF目录下的classes目录下创建一个log4j.xml文件,可以将以下的log4j.xml复制到该目录下,如果该文件已经存在,则需要将以下的log4j.xml合并的已有文件中. 【附件】 log4j.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "http://log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="Console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy/MM/dd-HH:mm:ss} >> %5p >> %t >> %l >> %m%n" />
</layout>
</appender>
<appender name="report"
class="org.apache.log4j.RollingFileAppender">
<param name="File" value="${reportAppRoot}/WEB-INF/log/report.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="10MB" />
<param name="MaxBackupIndex" value="10"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d >> %5p >> %t >> [UniEAP_Report] >> %l >> %m%n" />
</layout>
</appender>
<logger name="UniEAP_Report">
<level value="debug" />
<appender-ref ref="report" />
</logger>
<logger name="UniEAP_DataSet">
<level value="debug" />
<appender-ref ref="report" />
</logger>
<logger name="UniEAP_Semantic">
<level value="debug" />
<appender-ref ref="report" />
</logger>
<root>
<priority value="info" />
<appender-ref ref="Console" />
</root>
</log4j:configuration>
这里对log4j.xml中的配置进行一个简要的说明,在这个XML中主要配置两种节点,
1.报表引擎的日志配置:
<logger name="UniEAP_Report">
<level value="debug" />
<appender-ref ref="report" />
</logger>
2.数据集的日志配置:
<logger name="UniEAP_DataSet">
<level value="debug" />
<appender-ref ref="report" />
</logger>
3.语义层的日志配置:
<logger name="UniEAP_Semantic">
<level value="debug" />
<appender-ref ref="report" />
</logger>
修改logger节点下的level子节点的值可以设置不同的日志输出级别,一般在项目开发过程中我们使用debug级别的日志来打印更多的调试信息,来解决一些遇到的问题.在项目发布后一般调节为info级别。
在\WEB-INF\classes目录下的commons-logging.properties文件中指定日志实现类。
在\WEB-INF\classes目录下的log-config.properties文件中指定了${unieap.log},以变量的形式设置日志文件输出的路径。
4.22 Weblogic10部署报表数据源找不到或无法连接数据源的问题
数据源找不到错误:
2012/10/16-15:28:40 665 >> ERROR >> [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)' >> com.neusoft.unieap.connection.PoolRegistry.getPoolProperties(Unknown Source) >> [UniEAP Connection Module] Datasource 'UNIEAP' is not found in configuration file "WEB-INF/conf/unieap/connection/connection-config.xml".
[UniEAP Connection Module] Datasource 'UNIEAP' is not found in configuration file "WEB-INF/conf/unieap/connection/connection-config.xml".
2012/10/16-15:28:40 666 >> ERROR >> [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)' >> com.neusoft.unieap.action.EAPActionServlet2.process(EAPActionServlet2.java:600) >>
javax.servlet.ServletException: com.neusoft.report.common.ReportException: (2003)报表描述信息操作失败;java.sql.SQLException: 找不到名为UNIEAP的数据源;找不到名为UNIEAP的数据源
这个系统业务功能可以用,报表不可以,在tomcat下可以运行,在weblogic下报错,报表是用的jdbc方式连接
无法连接数据源错误:
java.lang.RuntimeException: 调度器未获得connection-config.xml中UNIEAP的连接池配置
解决方法:
这个是UniEAP3.3 Connection组件的一个缺陷,已经在3.5中解决,只需将connection组件升级到3.5就可以了.
升级方法只需替换附件中的jar包到工程中就可以了,注意把工程中的unieap-connection-*.jar删掉。
【附件下载地址】
http://developer.neusoft.com/modules/newbb/viewtopic.php?topic_id=5259&forum=36
4.23 Weblogic12c部署报表启动调度器出错
启动调度器出错:仅可以为插入 LONG 列的 LONG 值赋值
####<2016-5-14 下午02时25分37秒 CST> <Error> <HTTP> <admin-PC> <AdminServer> <[ACTIVE] ExecuteThread: '11' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <81958bd5-e2c7-430b-a175-314ce6280caa-00000013> <1463207137129> <[severity-value: 8] [rid: 0] [partition-id: 0] [partition-name: DOMAIN] > <BEA-101216> <Servlet: "configSchedular" failed to preload on startup in Web application: "report.war".
com.neusoft.unieap.newscheduler.NewSchedulerException: (13112)启动调度器出错:;Failure occured during job recovery.;Couldn't recover jobs: ORA-01461: 仅可以为插入 LONG 列的 LONG 值赋值
;ORA-01461: 仅可以为插入 LONG 列的 LONG 值赋值
;(13112)启动调度器出错:;Failure occured during job recovery.;Couldn't recover jobs: ORA-01461: 仅可以为插入 LONG 列的 LONG 值赋值
;ORA-01461: 仅可以为插入 LONG 列的 LONG 值赋值
at com.neusoft.unieap.newscheduler.server.ConfigSchedular.init(ConfigSchedular.java:84)
at weblogic.servlet.internal.StubSecurityHelper$ServletInitAction.run(StubSecurityHelper.java:343)
at weblogic.servlet.internal.StubSecurityHelper$ServletInitAction.run(StubSecurityHelper.java:294)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:326)
at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:196)
at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
在tomcat下可以运行,在weblogic下报错
解决方法:
这个是Weblogic自身连接Oracle驱动jar和报表的Oracle驱动jar冲突导致的,设置先加载报表工程中对应的jar,需要创建一个weblogic.xml文件,内容如下,拷贝到报表应用的WEB-INF目录下.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
<weblogic-web-app>
<container-descriptor>
<prefer-web-inf-classes>false</prefer-web-inf-classes>
<prefer-application-resources>
<resource-name>META-INF/services/javax.xml.ws.spi.Provider</resource-name>
</prefer-application-resources>
<prefer-application-packages>
<package-name>oracle.*</package-name>
</prefer-application-packages>
</container-descriptor>
</weblogic-web-app>
4.24 Weblogic 11g部署,导出excel报错
日志详细信息:
java.lang.NoClassDefFoundError: Could not initialize class org.apache.poi.openxml4j.opc.internal.marshallers.ZipPackagePropertiesMarshaller
at org.apache.poi.openxml4j.opc.OPCPackage.init(OPCPackage.java:162)
at org.apache.poi.openxml4j.opc.OPCPackage.<init>(OPCPackage.java:142)
at org.apache.poi.openxml4j.opc.Package.<init>(Package.java:37)
at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:67)
at org.apache.poi.openxml4j.opc.OPCPackage.create(OPCPackage.java:338)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.newPackage(XSSFWorkbook.java:452)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:225)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:217)
at org.apache.poi.xssf.streaming.SXSSFWorkbook.<init>(SXSSFWorkbook.java:221)
at org.apache.poi.xssf.streaming.SXSSFWorkbook.<init>(SXSSFWorkbook.java:190)
at org.apache.poi.xssf.streaming.SXSSFWorkbook.<init>(SXSSFWorkbook.java:165)
at org.apache.poi.xssf.streaming.SXSSFWorkbook.<init>(SXSSFWorkbook.java:260)
at com.bstek.ureport.export.xlsx.XlsxExporter.doExport(XlsxExporter.java:67)
解决办法:删除报表中的stax-api-1.0.1.jar
4.25 IE端浏览报表结果正常,而设计器端连接不上服务器
日志详细信息:
java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:396)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.setProperty(SAXParserImpl.java:395)
at org.apache.axis.encoding.DeserializationContextImpl.parse(DeserializationContextImpl.java:222)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:568)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:427)
at org.apache.axis.Message.getContentType(Message.java:484)
at org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:683)
请将报表引擎应用\WEB-INF\lib目录下的axis1.2版本换成1.4版本。错误原因是JDK1.5中内嵌了xerces的xml解析程序,它没有完全的向下兼容。而JES服务器在Load的时候先加载了JDK中的解析器,而不是工程下的解析器。
4.26 在windows操作系统中浏览报表结果,出现乱码问题
在windows操作系统中浏览报表结果的时候,表头表尾的汉字显示为乱码,在数据库里面从blob中看 显示的是汉字。
使用2008年1月16日及之后发布的UniEAP Report版本解析之前的报表文件时会出现此问题,有两种方式可以解决此问题。
若报表数目不是很多,可使用报表设计器将报表导入到本地,并重新发布。
若报表数目较多,可以发邮件给report@neusoft.com索取数据库报表编码转换工具。
4.27 AIX服务器上报表展现乱码的解决
主要是因为AIX服务器上的中文环境的问题。服务器通过String对象getBytes()方法获得的字符数组获得的是系统默认字符集的byte数组,如果默认的不是gbk(windows默认的字符集),那么传到windows系统的时候就会产生乱码现象。
解决方法:
1.打开图形参数:即在classpath中添加 -Djava.awt.headless=true
2.打开AIX的显示配置。即配置环境参数 export DISPLAY=127.0.0.1:0
3.登录远程服务器,使用locale -a 64查看服务器支持那些兼容GBK的字符集。
4.修改服务器的相关环境变量,例如服务器支持Zh_CN.GB18030则需要指定以下参数:
- export LC_ALL=Zh_CN.GB18030
- export LANG=Zh_CN.GB18030
- export LANGUGAE=Zh_CN.GB18030
以上几步均可以在startWebLogic.sh中修改。
4.28 集成后的应用在tomcat下运行正常,部署到SunOne上提示 OP_SYS_PATH 找不到
原因是UniEAP Report引擎应用WEB-INF根目录下的struts-config.xml 里的
请在SunOne服务器用到的jre的\lib\security\java.policy文件中增加permission.java.util.PropertyPermission "OP_SYS_PATH", "write"。
4.29 报表结果中的数据量比数据库中取出的数据量小
原因有两个:
1.在数据集定义时限制了记录数。
2.如果使用的是DRM数据源,请修改UniEAP Report引擎应用\WEB-INF\conf\unieap\udolink\conf目录下的OP.properties文件中RESULTSET_LIMITATION的值,设置成比数据值要大的数值。
4.30 在UniEAP Report报表设计器点刷新服务库连接按钮时,有时成功,有时失败
数据库连接数满了,请重启数据库。
4.31 关闭任务调度模块
在UniEAP Report报表引擎应用WEB-INF根目录下的web.xml文件中删除configSchedular以及schedular-exchange的servlet以及mapping。
4.32 在浏览器端浏览报表结果时出现错误invalid lock constraint
错误信息如下日志:
com.neusoft.report.common.Log4jLogger.error(Unknown Source) >> invalid lock constraint.
com.neusoft.report.common.ReportException: invalid lock constraint.
at com.neusoft.report.engine.rao.RAOMgr.getDefineRAO(Unknown Source)
at com.neusoft.report.engine.core.NeuReportEngine.getDefine(Unknown Source)
at com.neusoft.report.engine.core.NeuReportEngine.getParameters(Unknown Source)
at com.neusoft.report.server.view.EntryReportAction.execute(Unknown Source)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
原因为该项目中申请的是“部署”版License,是已经绑定了ip地址的,请将UniEAP Report引擎布置在合法ip地址所在的服务器上。
4.33 在报表设计器中点击<刷新服务库连接>按钮时,第一次连接不成功,再次点击提示连接成功
请点击UniEAP Report菜单栏上的窗口>首选项,在弹出的窗口中增大Report tab页属性中的’连接报表服务超时延迟’属性值。
4.34 使用DB2数据库,jcc驱动,浏览报表结果时出错
原因是DB2的jcc驱动不支持大字段的自动滚动。请打开UniEAP Report引擎应用\WEB-INF\conf\unieap\udolink\conf目录下的OP.properties文件,将其中的USE_SCROLLABLE_RESULTSET设置为true。
4.35 通过浏览器浏览报表结果时出现taglib错误
错误信息如下:
No tag "BackFillReport" defined in tag library imported with prefix "unieap-report"
或者是
org.apache.jasper.JasperException: 未找到文件 "/WEB-INF/taglib/ unieap-report.tld
解答:原因是在UniEAP Report版本比较旧或者是因为有些应用服务器不支持将taglib放到jar包中。
解决办法:
将unieap-report-manage.jar中\META-INF\目录下的unieap-report.tld拿出来,放到应用的web-inf/taglib目录下。
4.36 license替换后服务器启动异常
如下异常 Exception inthread "Evictor" java.lang.Number FormatException: For input string: "3.0"。
license生成引起的问题,发送邮件到report@neusoft.com申请替换license。
4.37 在操作系统为linux的DELL 2850服务器上部署永久版license无法生效
可以发邮件到report@neusoft.com索取licence测试类Test.class。执行Test.class文件后,相关异常信息为:
[root@tcoeServer ~]# java Test
java.net.UnknownHostException: tcoeServer: tcoeServer
at java.net.InetAddress.getLocalHost(InetAddress.java:1308)
at Test.main(Test.java:14)
说明:系统etc/sysconfig/network文件,其中记录的hostname就是tcoeServer。
原因:
该问题是因为系统配置原因导致java应用不能通过主机名找到其IP。
错误提示主机名为tcoeServer,而hosts文件中仅有对dell02的配置。
需要修改hosts文件增加对于tcoeServer的配置。
在hosts文件中追加一行配置,如下:
192.168.1.50 tcoeServer tcoe.neusoft.com
永久版的license即会生效。
4.38 报表不展现,直接调用报表的导出和打印服务
请参考《UniEAP Report 打印功能使用手册》
4.39 weblogic下报表任务无法保存
需要将quartz-weblogic.jar放在工程的lib目录下。
4.40 tomcat下jndi连接方式,启动时出现调度器初始化异常
删掉工程的lib目录下的ojdbc14.jar,tomcat已自带。Conncetion-config.xml的配置如下:
<jndi-connection name="SCHEDULER">
<jndi-name>java:comp/env/REPORT</jndi-name>
</jndi-connection>
如果报表的数据源也使用tomcat的jndi,另外增加如下配置:
<jndi-connection name="REPORT">
<jndi-name>REPORT</jndi-name>
</jndi-connection>
说明:报表数据源和调度的区别在于是否有java:comp/env/前辍。
4.41 使用SQL SERVER2000数据库做报表填报时money类型字段无法回填小数
现象描述:
使用SQL SERVER2000数据库做报表填报时,money类型字段无法回填小数,提出回填失败。
解决方案:
该现象是由于使用的微软官方的JDBC驱动,该驱动存在一些缺陷。建议更换为开源的jtds驱动,即可解决这一问题。
4.42 Tomcat5.0.X版本下,使用报表设计器发布报表不好用
现象描述:
在使用Tomcat5.0.X版本做应用服务器时,报表设计器发布报表时,提示‘无法连接报表服务’的错误。
解决方案:
该现象是由于tomcat5.0如下目录中tomcat5.0.X\common\endorsed包含xercesImpl.jar、xml-apis.jar两个包,这两个包与应用中的jar存在版本冲突,删除这两个jar后即可排除故障。
4.43 服务库信息配置
UniEAP Report独立版本(插件/RCP)的服务库信息在Eclipse的首选项中配置;
WorkShop中在相应工程的属性中配置。
4.44 刷新服务库,出现“no protocol: /services/Designer”
解决方案:典型的服务库属性没有配置的问题,请检查“服务库”属性的配置。
4.45 为什么刷新服务库,报“Connection refused: connect”
解决方案:“服务库”属性中配置的Url对应的应用没有启动,启动应用后,再次刷新即可。
4.46 如何配置报表的WebService服务
解决方案:
1.在web.xml中增加AxisServlet配置:
<servlet>
<servlet-name>AxisServlet</servlet-name>
<display-name>Apache-Axis Servlet</display-name>
<servlet-class>
org.apache.axis.transport.http.AxisServlet
</servlet-class>
</servlet>
对应的mapping部分:
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
2.将UniEAP Report引擎应用WEB-INF目录下的server-config.wsdd文件拷贝到应用系统对应目录下,如果原系统中已包含该文件,则只需要在原系统文件中加入以下部分:
<service name="Designer" provider="java:RPC">
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Request"/>
<parameter name="className" value="com.neusoft.report.designerfacade.DesignerAgent"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns1:InputStream" serializer="org.apache.axis.encoding.ser.BeanSerializerFactory" type="java:java.io.InputStream" xmlns:ns1="http://io.java"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.ArrayDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns2:ArrayOffString" serializer="org.apache.axis.encoding.ser.ArraySerializerFactory" type="java:java.lang.String[]" xmlns:ns2="null"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.ArrayDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns3:ArrayOffbyte" serializer="org.apache.axis.encoding.ser.ArraySerializerFactory" type="java:byte[]" xmlns:ns3="null"/>
</service>
<service name="DataSet" provider="java:RPC">
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Session"/>
<parameter name="className" value="com.neusoft.unieap.dataset.DataSetService"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns1:InputStream" serializer="org.apache.axis.encoding.ser.BeanSerializerFactory" type="java:java.io.InputStream" xmlns:ns1="http://io.java"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.ArrayDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns2:ArrayOffString" serializer="org.apache.axis.encoding.ser.ArraySerializerFactory" type="java:java.lang.String[]" xmlns:ns2="null"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.ArrayDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns3:ArrayOffbyte" serializer="org.apache.axis.encoding.ser.ArraySerializerFactory" type="java:byte[]" xmlns:ns3="null"/>
</service>
<service name="MetaReader" provider="java:RPC">
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Session"/>
<parameter name="className" value="com.neusoft.meta.webservices.MetaServiceImp"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns1:InputStream" serializer="org.apache.axis.encoding.ser.BeanSerializerFactory" type="java:java.io.InputStream" xmlns:ns1="http://io.java"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.ArrayDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns2:ArrayOffString" serializer="org.apache.axis.encoding.ser.ArraySerializerFactory" type="java:java.lang.String[]" xmlns:ns2="null"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.ArrayDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns3:ArrayOffbyte" serializer="org.apache.axis.encoding.ser.ArraySerializerFactory" type="java:byte[]" xmlns:ns3="null"/>
</service>
<service name="ManageService" provider="java:RPC">
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Session"/>
<parameter name="className" value="com.neusoft.meta.webservices.ManageServiceImp"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns1:InputStream" serializer="org.apache.axis.encoding.ser.BeanSerializerFactory" type="java:java.io.InputStream" xmlns:ns1="http://io.java"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.ArrayDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns2:ArrayOffString" serializer="org.apache.axis.encoding.ser.ArraySerializerFactory" type="java:java.lang.String[]" xmlns:ns2="null"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.ArrayDeserializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" qname="ns3:ArrayOffbyte" serializer="org.apache.axis.encoding.ser.ArraySerializerFactory" type="java:byte[]" xmlns:ns3="null"/>
</service>
【注意】:以上为使用axis1.4时的示例,如果集成环境使用axis2,请根据其规范修改。
4.47 如何查看报表的WebService服务是否发布成功?
解决方案:启动系统应用,在浏览器中输入:http://*:*/services/Designer?wsdl,如果出现下面的页面,说明WebService发布成功。
4.48 为什么刷新服务库,出现“Not Found”
解决方案:
1.检查服务器Url是否正确配置;
2.检查是否配置报表的WebService服务;
3.是否配置了多个Servlet,url-pattern配置为/services/*。
<servlet-mapping>
<servlet-name>**</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
4.49 启用Linux/Unix系统图形环境出错
问题现象可能是以下情况之一:
java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable;
通常的异常是NoClassDefFoundError,执行代码是涉及到BufferredImage、Graphics2D的位置,比如JFreechart、CellShapeAdjuster等,异常如下:
java.lang.NoClassDefFoundError: sun/awt/X11GraphicsEnvironment
java.lang.NoClassDefFoundError: java/awt/BufferredImage
java.lang.NoClassDefFoundError: CellShapeAdjuster
java.lang.NoClassDefFoundError: JFreeChartFactory
解决方案:在JVM参数中添加配置-Djava.awt.headless=true 其中Tomcat为JAVA_OPTS,Weblogic等为JAVA_OPTIONS;前提条件是Linux系统中安装并启动了X-Windows图形界面,且系统内存足够,如果内存不足,也可能出现上面的NoClassDefFoundError异常
4.50 安装X-Windows和libXp组件
问题现象:Linux下执行报表报libXp相关的异常
java.lang.UnsatisfiedLinkError:
/opt/bea/jdk142_11/jre/lib/i386/libawt.so: libXp.so.6
解决方案:启用X-Windows图形界面,安装libXp组件。
4.51 报表乱码问题
保证EncodingFilter的字符集与report-engine-config.properties中的report_application_encode指定的报表应用的编码方式一致;
中文传参是一个普遍的问题:使用encode=true,和encodeto64()方法对中文参数进行编码
4.52 填报类型报表在导出、打印时,中文乱码
问题现象:报表集成到其他应用中,系统设置EncodingFilter,填报类型报表在导出、打印时,中文乱码
解决方案:通常情况下,该问题是EncodingFilter的字符集与报表引擎配置文件report-engine-config.properties中的report_application_encode指定的应用编码方式保持一致
4.53 填报报表展现时,填报单元格不能编辑,页面报“dojo未定义”等错误
问题现象:系统编码为GBK,集成报表后,展现填报报表,报JS相关错误:JS格式、dojo未定义等。通过调试,发现JS乱码。Unieap相关的JS基本都是Utf-8格式编码,而页面在引用JS时没有指定JS解码格式,导致系统编码为GBK时,中文、特殊符号等乱码,造成JS解析错误。
解决方案:在引用JS时,在Script标签中添加charset属性,强制指定JS的解码格式,。
4.54 License文件不存在
问题现象:Exception in thread "Evictor" com.neusoft.report.common.ReportException: (1007)没有使用报表产品的许可权限
登陆界面显示“License not found”
解决方案:将申请的License文件拷贝到WEB-INF\conf\unieap\license\目录下,重启应用。
4.55 License信息与应用版本信息不符
问题现象:Exception in thread "Evictor" java.lang.NumberFormatException: For input string: "3.0"。
解决方案:根据系统应用中Unieap相关产品信息,重新申请对应的License进行替换。
4.56 License级别过低,导致功能限用(该版本此功能限用)
问题现象:
Caused by: com.neusoft.report.common.ReportException: (1006)该版本此功能限用
at com.neusoft.report.common.Trace.error(Trace.java:356)
at com.neusoft.report.common.Trace.error(Trace.java:378)
at com.neusoft.report.engine.security.licence.ProtectionManager.checkEdition(Unknown Source)
解决方案:UniEAP Report产品分三个级别:标准版、专业版、企业版,系统中某些功能需要根据系统应用中Unieap相关产品信息,填写License申请表,申请符合项目信息的License。
4.57 如何实现集群环境下,报表的同步
(即两个报表服务连接相同的数据库,报表定义被更新时,两个服务都能看到更新后的报表,目前只有报表设计器连接的那个服务才能看到最新的报表,另一个服务需要重启才能看到。)
修改\WEB-INF\conf\unieap\report目录下的report-engine-config.properties文件中的配置:
将下面配置
com.neusoft.report.engine.rao.define.cache.DefineCacheFactory=com.neusoft.report.engine.rao.define.cache.SingleServerFactory
define_cache_size=100
替换为:
com.neusoft.report.engine.rao.define.cache.DefineCacheFactory=com.neusoft.report.engine.rao.define.cache.MultiServerFactory
define_cache_timeout=600
define_cache_size=100
【注意】只有多服务集群时这样修改,否则会影响性能。
4.58 使用MySQL5.6数据库报出OPTION SQL_SELECT _LIMIT=DEFAULT不支持
使用MySQL数据库5.6版时,报出数据库不支持OPTION SQL_SELECT_LIMIT=DEFAULT的异常,原因为使用的MySQL的数据库JDBC驱动比较老,与MySQL新版本不匹配,将MySQL的数据库驱动升级为mysql-connector-java-5.1.32-bin.jar即可解决。
4.59 在Weblogic 10.3.5及以上版本中,报com.bluecast.xml.Piccolo cannot be cast to org.xml.sax.XMLReader错误
关键异常信息如下:
java.lang.ExceptionInInitializerError
at com.neusoft.report.engine.core.NeuReportEngine.<clinit>(Unknown Source)
at com.neusoft.report.engine.ReportManager.create(Unknown Source)
at com.neusoft.report.server.util.ReportCreate.generateReport(Unknown Source)
at com.neusoft.report.server.view.ReportAction.generateReport(Unknown Source)
at com.neusoft.report.server.view.ResultAction.execute(Unknown Source)
Truncated. see log file for complete stacktrace
Caused By: java.lang.RuntimeException: com.bluecast.xml.Piccolo cannot be cast to org.xml.sax.XMLReader
问题产生的原因是XML解析的jar包冲突。Weblogic下会执行xmlbean中的代码Class.forName(“com.bluecast.xmlPiccolo”)加载XML解析包,从而在转换成org.xml.sax.XMLReader类型时发生异常,而在tomcat和websphere等应用服务器下加载不到此类,所以不会出错。
解决办法:在WEB-INF/weblogic.xml中增加如下代码即可
<package-name>com.bluecase.xml.*</pachage-name>
第5章 报表二次开发
5.1 直接访问UniEAP Report管理界面
访问管理界面的url是http://ip地址:端口号/应用名/Report-Manager.do。
5.2 通过不同应用访问报表时,有时出现参数查询页面,有时不出现的原因
要出现报表的参数页面请链接Report-EntryAction.do而不是Report-ResultAction.do。
5.3 把UniEAP Report的权限控制与业务应用程序的权限控制统一
UniEAP Report针对权限提供了一组接口,只要实现这些接口即可。更详细的内容可以参考《UniEAP Report二次开发手册》。
5.4 不使用UniEAP Report默认生成的参数界面,而使用自己编写的jsp页面
若不使用UniEAP Report默认生成的参数界面,而使用自己编写的jsp页面,可按如下步骤进行操作:
1.按照需求在UniEAP Report报表设计器中完成参数定义。
2.编写自定义参数页面的jsp文件。
3.在自定义参数页面的jsp文件中将参数提交到Report-ResultAction.do,对Report-ResultAction.do的介绍详见《 UniEAP Report集成手册》。
【注意】参数页面jsp文件中控件的名称要与设计器中参数的名称保持一致,这样提交到Report-ResultAction.do后,才能进行参数的替换。
以下为自定义参数页面jsp文件的例子,以供参考:
<%@ page contentType="text/html;charset=GBK" pageEncoding="GBK"%>
<%
request.setCharacterEncoding("utf-8");
%>
<html>
<head>
<title>报表展现结果</title>
<script language="javascript">
function isOk() {
document.myForm.action="Report-ResultAction.do?reportId=d74df10e-1340 -4539-a8db-f4b76500a314&ctye=1";
document.myForm.submit();
}
</script>
</head>
<body>
<form name="myForm" method="post">
<input type="text" name="param">
<input type="button” name="btn" value="提交" onclick="isOk()">
</form>
</body>
</html>
jsp页面中要包含该参数页面所关联的报表ID信息,除了在action的参数中传递报表ID外,也可以在页面中加入如下的标签来传递报表ID:
<input type="hidden" name="reportId" value="d74df10e-1340-4539-a8db-f4b76500a314">
将自定义参数页面的jsp文件,放到报表引擎应用中,例如根目录下。
在数据集面板中,右键点击参数节点,选择“自定义界面”,如下图所示
在报表设计器的自定义参数窗口中可以直接写html代码,但只能是html代码,不能带有jsp代码;也可以在弹出的“自定义参数界面”窗口中写入自定义参数页面的jsp文件的url地址,url要符合以下规则:
返回的URL可以为一个完整的URL,如http://www.neusoft.com/myparam.jsp
也可以是一个绝对路径的URL,必须从Web应用名称开始写起,必须以//打头,如Web应用名为report,则写成为//report/myparam.jsp,
不可以是相对路径的URL,如myparam.jsp或report/myparam.jsp
写入URL后如下图所示:
详细内容请参考《UniEAP Report最佳实践之——参数页面实现方法详述》。
5.5 通过webService的方式获取数据作为UniEAP Report的数据源
需要扩展UniEAP Report现有的数据数据源类型,增加一个webservice数据数据源类型。在这个数据数据源的实现中,通过java调用远程webservice,得到数据结果,然后包装成数据集对象。报表引擎使用这个数据数据源对象生成报表。
5.6 UniEAP Report参数界面输入中文时,报表展示乱码的解决方法
如果没有用UniEAP Report的登陆过滤。在进入UniEAP Report应用时设置编码:req.setCharacterEncoding(ProjectConfigHelper.PROJECT_CODINGKIND);
5.7 自定义参数界面传递中文乱码
自定义参数界面引用js时加入编码
5.8 UniEAP Report如何支持国际化的数据以及界面的显示,怎样定义呢?
报表数据的国际化可以通过自定义公式实现,并添加系统变量,通过变量控制展现时应用的语言。