Birt开发遇到的问题

原文:http://xulianglly.blog.163.com/blog/static/4361742220111020642884/

非常实用


2011-11-02 00:06:42| 分类: 技术 |字号 订阅
这是我自己在学birt的时候做的记录,版本是birt2.5.2,文字功底有限,表达的很不严谨,在这里仅供大家参孝学习:
如果在这里找到有用的信息,请留下您的痕迹,如果对相同的问题有更好的解决方法,欢迎留言提示!


>>1.说明,访问数据列有三种方式,如上面的row.id,或者可以使用row["id"],或者可以使用row[1],得到的都是数据列id.
>>2.在标题title,x轴,y轴上相应位置上设置字体为:Simsun(Founder Extended)(Simsun即为宋体),乱码问题便可得到解决。
>>3.分组chart乱码,解决方法:
Advanced->Font->Font family->"Arail Unicode MS"
如果没有选择项,可直接写上去
>>4.要得到多系列的柱形图主要在于数据,要这样的数据才能形成多系列的柱形图:
name-数目-年份:
A 23 2007
A 22 2006
B 15 2007
B 19 2006
C 30 2007
C 41 2006
这样x轴设置成name,y轴设置成数目,分组设置成年份
>>5.怎样在柱形图上显示数字?怎样使数字显示在柱形图的顶端?
方法:在Format Chart选项下,选中Series->Value(Y)Series->把下方的Show Series Labels选项按钮选中即可
要想使数字显示在柱形图的顶端,则还要点击同一页面的Labels按钮,然后在Position下拉框下选择Outside就行了

>>6.why not 说明:
为什么没有使用 birt report viewer
BIRT Report Viewer 貌似做得很周到,提供如浏览,打印,export to CSV ,过滤参数的传入等一系列的快速操作.
然而细心思考过,这个viewer还是存在不少问题:
如不适用的报表传入参数方式(无输入验证,无日期控件);代码复杂,可扩展性差......
发现不少功能形同虚设,所以决心抛弃.
为什么不在.rptdesign里写sql
往往实际项目的业务总是复杂的,不希望将复杂的逻辑通过几个简单的参数传入拼凑sql来实现,再说这样调试sql也是一件麻烦的事情,也不利于SQL管理
所以我们提倡 将查询的商业逻辑放回java Manager类,然后designer负责设计数据如何排列。这样子更适合实际项目.
>>7.运行报表
我理解为编译报表文件。BIRT在渲染报表之前,要将报表编译为.rptdocument,再根据这个文件将报表渲染为HTML格式或PDF格式。
>>8.如何把java代码中参数传递给报表?在报表中又怎样获取这个参数?
答:通过这种方式给报表传参:
HashMap paramMap = new HashMap();
paramMap.put("birtparam1", 1);
paramMap.put("birtparam2", 5);
task.setParameterValues(paramMap);
设置报表参数与传递的参数同名,这样就关联起来了
数据集参数与报表参数绑定
sql语句中的“?”号对应数据集参数
>>9.做交互时在js中获取点击对象的属性值:
Action选择Invoke Script,添写下面的Script代码时,对象的属性要这样查找,不能直接写:
点击fx表达式->在Category里面点击Chart Variables->然后在Sub-Category里面点击Data Points->最后在Double Click to insert里面选择对象的属性,双击它就可以加到上面的表达式中
alert("服务名:" + categoryData + " 值:" + valueData)

>>10.第一次查询时速度特别慢
>>11.关于查询某一时间段的服务的处理试例:
private String getPageSQL(String startDate, String endDate, String serviceName) {
String queryString = " from TaskLog taskLog where taskLog.serviceInstance = " + serviceName;
if((!StringUtil.isEmpty(startDate))&&(!StringUtil.isEmpty(endDate))){
queryString +=" and ((taskLog.startTime>'" +
startDate + "' and taskLog.startTime<'" +
endDate + "') or (taskLog.endTime>'" +
startDate + "' and taskLog.endTime<'" +
endDate + "')) " ;
}else if(!StringUtil.isEmpty(startDate)){
queryString += " and taskLog.startTime>'"+ startDate +"'";
}else if(!StringUtil.isEmpty(endDate)){
queryString += " and taskLog.endTime<'"+ endDate +"'";
}
queryString += " order by taskLog.taskId desc ";
return queryString;
}
>>12.在beforeopen方法中故意拼错某一查询语句,它会在页面上把该查询语句打印出来,自己故意写的错误自己知道,此外还可以看一下其他的错误,不失为一种调试的方法。
>>13.执行成功的时间参数案例:
在data set的beforeopen方法中写下如下代码(注意SQL的拼接):
var startTime = params["startTime"];
var endTime = params["endTime"];
this.queryText += " where testbirt.startTime>='" + startTime + "' and testbirt.startTime<='" + endTime + "'";
数据集中的参数设置成datatime格式,不设默认值
报表参数设置成String格式,默认值为空,非必需
然后把数据集中参数跟报表参数绑定,注意这地方数据类型不匹配,但却能正常运行,这个问题还有待研究。
>>14.Birt的JavaScript脚本简单调试
博客分类: birt
脚本JavaScriptTomcatJava应用服务器
Birt的JavaScript脚本简单调试

Birt中的js脚本不能用alert直接弹出提示,也没法用断点跟踪(至少我没发现)。用一个简单方法可以打印,在脚本里写上(有脚本的地方就可以加上这条语句,比方说dataset的beforeopen方法中)
importPackage(Packages.java.lang);
System.out.println("test===");
就可以再控制台里打印出来,进行简单的调试了。
需要注意的是,必须要把报表部署在tomcat下才能打印,用Preview预览模式不能打印。
调试样例:
importPackage(Packages.java.lang);
System.out.println("test===*********************************");

var startTime = params["startTime"];
var endTime = params["endTime"];
System.out.println("startTime: " + startTime);
System.out.println("endTime: " + endTime);
if(startTime != null && (!"".equals(startTime)) && endTime != null && (!"".equals(endTime))) {
this.queryText += " where tasklog_2011_8.startTime>='" + startTime + "' and tasklog_2011_8.startTime<='" + endTime + "' or tasklog_2011_8.endTime>='" + startTime + "' and tasklog_2011_8.endTime<='" + endTime + "' group by serviceInstance,status";
} else if(startTime != null && (!"".equals(startTime))) {
this.queryText += " where tasklog_2011_8.startTime>='" + startTime + "' group by serviceInstance,status";
} else if(endTime != null && (!"".equals(endTime))) {
this.queryText += " where tasklog_2011_8.endTime<='" + endTime + "' group by serviceInstance,status";
} else {
this.queryText += " group by serviceInstance,status";
}
System.out.println(this.queryText);
注意Packages
java.*
在应用服务器下运行

最新调试方法:
新建一个报表,并加入一个元素,在其onPrepare中写如下代码

importPackage ( Packages.java.io);
importPackage(Packages.java.lang);
System.setOut(new PrintStream(new java.io.FileOutputStream("c:\\logFile3.txt")));
System.out.print("1");
>>15.设置数据集参数时,有时候默认值老是出错,这时候可以不设默认值,如果还有问题就把报表参数改成非必须的。
>>16.把数据库中的true和false通过计算列的形式转化成:成功和失败
在数据集中新增计算列,表达式写法:
row["status"].equals("true")?"成功":"失败";
也可以这样写:
var temp = row["status"];
var result = "";
if(temp.equals("true")) {
result = "成功";
}else {
result = "失败";
}
注意最后不要有return result;这条语句,否则会报错
>>17.Birt中使用计算列获得星期几的方法
2008-04-24 23:06
var day=row["DiaryDate"].getDay();
var day1="";
switch(day){
case 1:day1="<星期一>"; break;
case 2:day1="<星期二>"; break;
case 3:day1="<星期三>"; break;
case 4:day1="<星期四>"; break;
case 5:day1="<星期五>"; break;
case 6:day1="<星期六>"; break;
default 7: day1="<星期日>";
}
内部机制自动会把day1返回给对应变量,不用专门写return语句
>>18.实现交互的时候可以用Invoke Script
里面直接写这样的代码就可以实现给jsp页面上对应的id赋值
document.getElementById("idName").value=Category Data
而且在这里面可以直接调用jsp页面里面定义的js方法,以此来实现交互。

>>19.birt中如果自己接接sql的话,不需要再在dataset里面设置参数了,在动态拼接sql里面可以直接取到,唉,这个知识点很重要啊,解决了我的大问题。
>>20.数据源,数据集,参数,在不同的报表之间都是可以复制的
>>21.报表不显示和报表只显示一部分:
报表不显示是因为生成图片格式不能设置成SVG格式的,改成BMP或JPG都行
报表只显示一部分,根据打印outstream,可知是报表本身属性的设置问题,一步一步深入,最后得到结论:
Properties->Report Design->Layout preference->设置成Auto Layout,之前不能完全显示就是因为这个值设置成了Fixed Layout
注意这个属性是加载报表的面板的属性,也就是通常的面板布局,要点击报表以外的部分才能选中这个面板,然后就可以修改属性值了。
注意,在birt2.5中,新建面板时,Layout属性默认为Fixed,要把它改为Auto
>>22.怎样设置时间格式为:yyyy-MM-dd hh:mm:ss
注意custom是自定义的意思
>>23.
最近在研究Birt报表时遇到内存溢出的问题,PermGen Space区域的溢出,最后通过百度和谷歌两位大哥的帮助,把问题算是解决了,但是却引发了在项目中使用Birt的性能问题。
众所周知,PermGen Space区溢出是系统加载的class和meta信息过多引起的,经常发生在jsp编译的时候,因为PermGen Space大小固定,且GC不在系统运行期间回收垃圾,所以PermGen Space设置再大,也有用完的一天,唯有换JDK才能彻底根治。
但是合理的设计,是可以减少对PermGen Space的占用的,所以想听听高手们在使用Birt的时候,哪些注意事项或方法可以提高Birt的性能、减少其对内存的侵占,毕竟要换JDK也是要付出一定代价的。
>>24.乱码问题:
1 服务器配置
2 加过滤器
3 页面jsp配置utf_8
>>25.关于Birt报表中文传值乱码的处理[转]
通过url传参遇到中文出现乱码的解决办法
前提:
1.使用eclipse提供的runtime viewer.
2.使用超链方式查看报表.
3.使用tomcat.
具体解决办法:
修改tomcat的server.xml文件,在Connector元素中增加属性useBodyEncodingForURI="true"
并且,url中的中文参数必须事先转码.
eg:
String param=java.net.URLEncoder.encode("公用信息表","UTF-8");
<a href="../birt/frameset?__report=privilegerpt.rptdesign¶m=<%=param%>">查看</a>
即ok.
>>26.两次请求同一个方法要注意缓存问题,比方说上次发送的请求获得的serviceInstance和status,它们的值会放到session中,在下次再次请求时本来serviceInstance和status都应该为空的,由于上次的请求,它们的值还在session中放着,所以导致这次它们仍不为空,这就存在潜在的问题。
>>27.两个困扰我很久的问题:
第一个问题是:
怎样把时间格式定义成这样:
2011-09-22 16:32:15
我用自定义的形式定义的,后面总要带着上午或下午,怎么能把上午、下午去掉,显示24小时制的时间格式
第二个问题是:
表头和表里面的数据中文乱码
预览的时候正常,但在展示的时候显示乱码,这到底是怎么回事?
解答:第一个问题可以说是不影响程序的问题,只是显示的一种形式,跟查询没有关系,因为查询条件是从jsp页面传进去的(24小时时间制),数据库中也是24小时时间制,报表上的形式只是一种显示形式,无关紧要。
想解决也简单:
自定义格式:yyyy-MM-dd HH:mm:ss
注意HH是大写,大写表示24小时制,小写表示12小时制

第二个问题,是因为得到的outstream编码格式不对,只要对它编码就行了,调用ByteArrayOutPutStream的toString("UTF-8")方法,然后把返回的值放到html框架里面就不会乱码了。

>>28.birt运行时报出警告
警告: handle type: org.eclipse.birt.report.model.api.OdaDataSetHandle
2011-5-18 20:58:44 org.eclipse.birt.report.data.adapter.impl.ModelAdapter adaptDataSet
警告: handle type: org.eclipse.birt.report.model.api.OdaDataSetHandle
2011-5-18 20:58:44 org.eclipse.birt.report.data.adapter.impl.ModelAdapter adaptDataSet
警告: handle type: org.eclipse.birt.report.model.api.OdaDataSetHandle

在birt运行时后台总是报出警告 但是页面显示正常,不知大家有没有遇到过这种情况
把birt 的日志级别改高一些,在示例工程的web.xml里有配置。
在web.xml中将BIRT_VIEWER_LOG_LEVEL级别调成 SEVERE后 后台就没有了
上面是birt viewer的方式,若是birt api的方式只要在birtengin里加一句代码就可以了:
config.setLogConfig(sc.getRealPath("/logs"), Level.SEVERE);
>>29.//保存信息到Session中
private void saveSessionInfo(HttpServletRequest request, HttpServletResponse response, List<String> timearray) {
CacheManager cacheManager = CacheManager.getInstance();
if (cacheManager.cacheExists("activeLists")) {
Cache cache = cacheManager.getCache("activeLists");
cache.put(new Element(request.getSession().getId(), timearray));
}
request.getSession().setAttribute("timearray", timearray);
}
>>30.迭代器的使用:
List<String> timearray = new ArrayList<String>();
System.out.println(timearray);
//输出ArrayList中的数据
Iterator<String> it = timearray.iterator();
for(;it.hasNext();) {
Object objstr = it.next();
System.out.println("****" + objstr);
}
>>31.[birt2.5]如何利用日志和控制台调试报表
1)输出文件的方式
l 在报表的initialize脚本方法中,添加如下代码:
importPackage( Packages.java.io );
fos = new java.io.FileOutputStream( "c:\\logFile123.txt" );
printWriter = new java.io.PrintWriter( fos );
l 在afterRender脚本方法中,添加如下代码:
printWriter.println( "afterRender:");
printWriter.close( );
l 在其它脚本方法中,通过调用printWriter来记录日志。
printWriter.println("helloworld");
2)打印控制台信息
Packages.java.lang.System.out.println("print"+record.get("NAME"));
>>32.要把生成的图片定期删掉,可以把图片专门放在一个目录下,然后在程序中控制让它每隔一段时间清理掉图片目录下的所有文件
>>33.应用程序中导出图片的路径必须这样写:
<img src=\"http://localhost:8081/webmonitor/custom1b4108a132906eaa8e1.bmp\"/>
用localhost:8081模式
>>34.应用程序即main类型程序,用文件系统FileOutputStream
web程序用ServletOutputStream
>>35.遇到版本不兼容的问题,一般是遇到高版本的报表文件,可以把高版本的头信息改成当前版本的,
低版本的报表文件可以直接打开(修改后重新保存才能生效)
>>36.可以调整报表的宽度和高度以适应导出pdf文件的要求,也可以设整单元格的宽度以实现显示全部内容
>>37.birt中的居中显示:
选中整个表格或某个单元格->然后选择中间下方的Properties选项卡->依次展开:Table->Text->Text alignment(左右居中)->打开下拉框,选择Center即可。
Vertical alignment(上下居中)原理相同
>>38.隐藏与显示报表工具栏,导航栏
webcontent\birt\pages\layout\FramesetFragment.jsp里找到下面这句:
Mask.setBaseElements( new Array( birtToolbar.__instance, navigationBar.__instance, birtReportDocument.__instance) );
birtToolbar.__instance报表工具栏,就是上面有打印,导出图片按钮的那行。
navigationBar.__instance导航栏,就是有下一页,多少页什么的。
在里只要new Array去除相应的就行了。
如果只是要去掉导出按钮和打印按钮,直接在url后面加参数__toolbar=false就可以了
http://localhost:8081/birtserver2.5/frameset?__report=pagebreak.rptdesign&__toolbar=false 

你可能感兴趣的:(birt)