存档

‘BIRT’ 分类的存档

BIRT 中定时刷新报表

2009年2月13日 没有评论

HTML 中如果我们要定时刷新某一个部分, 可以使用DOM api window对象的settimeout方法, BIRT 中当然可以直接使用html 的script , 当然主要是看刷新之后报表还是跟原来一样,参数都正确处理了.

所以在报表中加入一个text 元素, 然后选html 类型, 在其onPrepare() 方法里面加上下列代码就可以在查看报表的时候按照执行的时间进行刷新或者你也可以手工点 “refresh” 按钮进行刷新

//Build a string that contains all the parameters and their values
var paramsString = “”;
var paramDefs = reportContext.getDesignHandle().getAllParameters();
for (i = 0; i < paramDefs.size(); i++ ) {
var paramDef = paramDefs.get(i);
if (paramDef.getClass().toString() == “class org.eclipse.birt.report.model.api.ScalarParameterHandle”) {
var paramVal = reportContext.getParameterValue(paramDef.getName())
if (paramVal == null || paramVal == “null”) {
paramVal = “”;
} else if (paramVal.length > 0) {
var paramValTmp = “”;
for (j = 0; j < paramVal.length; j++) {
if (paramVal[j] != null && paramVal[j] != “null”) {
if (j > 0)
paramValTmp += “|”;
paramValTmp += encodeURIComponent(paramVal[j]);
}
}
paramVal = paramValTmp;
} else {
paramVal = encodeURIComponent(paramVal);
}
paramsString += “&” + paramDef.getName() + “=” + paramVal;
}
}

this.content=”<form name=’input’ onSubmit=’return reloadPage();’>”
+”<input type=’submit’ value=’refresh report’ onclick=’reloadPage()’>refresh manual</input></form>”
+”<script type=text/javascript’>”
+”function reloadPage() {”
//alert( targetURL );
+”    var targeturl = window.location+’”+paramsString+”‘;”
+”    location.replace(targeturl);”
+”    return false;”
+”}”
+”timer=setTimeout(‘reloadPage()’, 20000);”
+”</script>”

第一部分主要是取得当前报表的参数, 并把参数变成 &param1=value1 这种形式,因为这种形式的URL 可以被直接使用, 如果是一个参数可以接受多个值的话, 中间就是 |  来连接, 比如 1|2|3 , 最后拼接成一个总的paramsString .

第二部分主要是html 的部分, location.replace(url) ; 就是提交当前的url , 也就是刷新了.

然后使用DOM 的window.setTimeout() 方法, 其中间隔是20 秒, 不过其中也有个按钮可以手工刷新,调用的同样也是reloadPage() 这个html script .

附上报表:  .reload_test

参考资料:

http://www.birt-exchange.com/devshare/designing-birt-reports/714-reusable-library-for-reloading-a-report/#description

这个有个自动刷新的library , 不过代码只适合iportal .

http://www.w3school.com.cn/htmldom/dom_obj_location.asp

http://www.w3school.com.cn/js/jsref_encodeURIComponent.asp

w3school 的几个dom api . 中文的. 这个站点的资源一项不错,google 才知道搞了个中文站点.

BIRT 新ODA驱动 Hibernate Data Source

2009年1月3日 没有评论

jboss tools 在新的3.0 版本中推出了一个更好的跟TPTP 和 BIRT 集成的计划, 下面主要介绍它添加的新的birt 功能

 

1. 新的oda 驱动, hibernate data source.

    在你安装完了birt all in one + jboss tools 之后,如果你创建报表,你会发现多了一个hibernate data source 可以作为数据源了.

HbDataSource1

 

HbDataSource2

如果你不是用JNDI 控制数据源,就不用填JNDI URL. 注意其中的Configuration 是选的Hibernate Console Configuration. 你要先创建hibernate console configuration. 它真正的参数也就是在hibernate.cfg.xml 里面读取的.

 

2. Hibernate Data Set.

    有了hibernate data source 当然有配套的hibernate data set了.  只不过这次选的不是table 和sql 了. 而是你程序里面的对象和HQL .

HbDataSet

 

如果你喜欢jboss 的seam 框架, 它也有一个新的seam 标签包装了birt .不知道是不是全部属性都包括了, 大家可以去看看.

 

参考资料:

http://docs.jboss.org/tools/whatsnew/birt/birt-news-1.0.0.Alpha1.html

jboss tools 3.0 的一部分新功能

 

http://docs.jboss.org/tools/movies/

告诉你怎么样使用jboss tools 的flash demo, 里面有教你怎么生成代码和创建console configuration的.

分类: BIRT 标签:

BIRT 一些基础问题解答

2008年12月29日 5 条评论

本来跑去birt-exchange.com 去下一个关于birt 用store procedure 作dataset 的文档, 看到有个中文版,就跑去actuatechina.com 下, 结果还要注册(我讨厌下东西的时候注册,我特别懒,最讨厌注册这种事) , 后来就注了个册,然后随便看了几个帖子,发现都是一些基础问题,因为很多时候BIRT的文档不可能集中在一个地方, 所以的确给很多喜欢BIRT 的朋友学习造成了一些麻烦,也有朋友抱怨说BIRT文档不好, 其实不是BIRT 文档不好,而是有很多问题都是实际的应用一个一个去解决,不可能有一份文档告诉你所有BIRT问题该怎么解决, 这就像我给你一份Java 的api 文档,你不可能知道所有java 代码该怎么写一样,还是要一个一个具体问题对应的解决, 最重要的是有示例 , 一个例子顶千言,这就是为什么需要BIRT的newsgroup , birt-exchange.com , actuatechina.com 这些资源去回答问题的, 所以没有什么必要抱怨什么没有文档, 我给你一份oracle 的参考大全,你就能成为最牛的DBA吗? 肯定不可能呀 .

下面列出一些常见的问题.

1. 作者: wc188996

希望能够在 BIRT CHART 的 category Series 上也能够实现钻取功能。有点时候在很多工程里category Series会包含很多内容,但是图片上的信息也不能完全显示,需要在category Series 上实现带参数的钻取功能。category Series可以很轻松的包含十几个甚至几十个项目,所以这点还是很实用的。
例如:在我的附件中饼图的这些个乱码上的位置,能否添加钻取功能。客户需要,郁闷啊。

birtchartdrill

答: BIRT的交互功能和script 一向是我最喜欢的, 图表的交互功能我个人认为可能是报表中最强的,(有希望打败它的可能只能在flash 图表里面找,它商业版里也有支持flash 对象的).   在一个chart 的y series 里面点击interactivity , 里面列出所有事件,选启动的mouse click 或mouse double click .Action 选Hyperlink, 然后连接你的另一个报表. 我前一个在BIRT里面高亮行的例子中http://www.gemini5201314.net/?p=151 ,那个图表就是选的Action –>Invoke Script.   如果你不是点饼图,而是点旁边的数值,就选Legend里面的interactivity , 注意Legend 还有一个Behavior 属性, 反正你都点着试一下就知道了.

 

作者: mjianguo

在birt2.3中,我用JDBC连数据库,创建数据集,创建参数(注:我用的是list box,Dynamic,此时没有选Allow Multiple Values),然后edit数据集,在Query中加入?,
在Paremeters中加入参数,Preview results ,没有问题。
此时我将一个参数中的Allow Multiple Values选中,Preview results时报表中就没有值了?
查看原因:edit数据集,点击Parmeters进入查看参数时,在上面显示此行错误:The report parameter ‘ipadd’ allows multiple values, which can not be used to link with data set parameter.
请问我该如何使用Allow Mulitple Values此选项?在SQL中要做什么变化吗?
不知说清楚了没有,请各位大侠指点迷经。。。先谢谢了

答: Query中的参数不支持link到allow multiple value的parameter 其中有个bug 跟它相关(2.3.1 以修正),

https://bugs.eclipse.org/bugs/show_bug.cgi?id=235252

这个bug 修正的是UI上要提示dataset 里面不能用parameter link 上UI要有提示的.

你的query 里面不能link multiple values 是因为java.sql.PreparedStatement 里面不可能setParameter(position,String[] params) 接受数组这种参数, 如果你要接受多个参数值可以:
1. dataset 的filter 里面加 xxx in params["allow multiple values"]
2. 或者在property binding 里面写 this.query.text="手工把params["multiple"]拼起来的sql"

 

作者: sanegod

我有这样一个需求,如附件need.jpg所示:
表格里有嵌套表!每个表绑定不同的数据集;
我有5个数据集,数据集1绑定在外层表,其他是4数据集绑定在内部的嵌套表上
z_in,z_out,z_in_cz,z_out_cz;
每个表格都一个结果,现在我想要实现:
z_in-z_out-z_in_cz-z_out_cz他们想减的结果放在aihaochazhi那个表里;
由于是四个数据集,不知道怎么实现!请大家帮忙!
把是个数据集的语句弄到一个数据这个办法考虑过,实现不了我的需求,我一定要用到4个数据集的!谢谢大家了!

答: 使用joint data set 把四个dataset 连起来,
你虽然知道每个结果肯定只有一个值,但是dataset 不可能知道呀,要是一dataset 有3个值,一个dataset 有5个值,你说最后的表格怎么画出来的.
只要你的四个dataset 使用的是同一个数据源,肯定可以用一个sql 跑出来, joint data set 一般用在不同的数据源直接dataset 连接

 

作者: iskytek

。。。。。。。。。。。。。。 交叉报表怎么没有分页选项

答 : 在crosstab 的row area 和column area 里面都有page break 选项呀, 分别是竖直分页和水平分页

 

1,birt导出PDF,如果内容是字母或数字过长,就会被截掉,怎么解决??
2,birt的WEB预览页面跟导出的PDF或打印出的样子不一样,那预览还有什么用?

答 1. 你在advanced tab 里面指定它的width 属性.
    2. 它的WEB 预览是html 的呀, 你pdf 当然是不一样的.

 

作者: qxyang007

目前我用的MVC框架,现在要用spring在后台调用birt,请问一下,该如何调用?网上说要重载一个方法renderMergedOutputModel,但,又没有实例,请教高手,能说明一下吗?急啊!谢谢了!

答 : 可以参考一下springside 的方法.
http://www.springside.org.cn/docs/reference/Birt.htm

 

我在googlecode 上建的一个收集report 示例的项目. 目前主要是birt-exchange.com 上的

http://code.google.com/p/birtdemo/

 

参考资料

http://www.birt-exchange.com/devshare/designing-birt-reports/588-create-data-source-on-stored-procedure-in-birt/#description    使用store procedure 做dataset.

http://www.actuatechina.com/thread838.html#post4250    四dataset

http://www.actuatechina.com/thread40.html    交叉报表

http://www.actuatechina.com/thread782.html     link multile values

http://www.actuatechina.com/thread852.html

分类: BIRT, Report 标签:

BIRT 报表高亮选中行

2008年12月28日 没有评论

在HTML中,要高亮选中一行非常简单,在<tr> 标签上加上onmouseover 事件和onmouseout , 然后使用this.style.backgroundColor=xxx 来表示 , 比如如下代码

<table border="1">
<tr onmouseover="this.style.backgroundColor=’red’;" onmouseout="this.style.background=’white’">
<td>hello world   hello world</td>

<td>hello world   hello world</td>

<td>hello world   hello world</td>
<td>hello world   hello world</td>
</tr>
</table>

 

BIRT 报表中当然也是可以嵌入HTML 和javascript 的, 通过在 "Text" 元素中选择 "HTML" 和 Formatting 格式.

birt-exchange 上有一个例子演示了如何在html 中鼠标移动的时候高亮选中一行,里面同时也演示了在对应的图表上怎么样鼠标移动时对应的表格里面的行也被高亮选中.通过在 chart 上的y轴添加一个onmouseover 事件.

另外一个需要注意的就是里面的<tr> 元素的id 是通过 bookmark 属性确定的. 这个例子中,bookmark 的值就是row["Country"] . 其余也不用多说.仔细看例子就知道了. 里面用来一点javascript . 可以学学怎么样取得table 的id 的.

 

 

参考资料

http://www.birt-exchange.com/devshare/designing-birt-reports/571-mouseover-highlight-for-tables-and-charts

分类: BIRT 标签:

BIRT Connection Pool 连接池

2008年12月24日 没有评论

在新的birt 2.3.1 版本中,提供了一种新的使用应用程序已有connection 的方式.通过:

task.getAppContext().put("OdaJDBCDriverPassInConnection", this.getConnection());

 

下面贴出最简单的代码示例, 我使用的项目环境是appfuse 的一个basic module(没web 项目的).

在你创建了basic module 之后, 在你的project 里面加上你下载的birt runtime 下面的ReportEngine / lib 目录下的所有jar.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.appbirt.report;
 
import org.eclipse.birt.core.framework.Platform;
import org.eclipse.birt.report.engine.api.EngineConfig;
import org.eclipse.birt.report.engine.api.EngineException;
import org.eclipse.birt.report.engine.api.HTMLRenderOption;
import org.eclipse.birt.report.engine.api.IReportEngine;
import org.eclipse.birt.report.engine.api.IReportEngineFactory;
import org.eclipse.birt.report.engine.api.IReportRunnable;
import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
 
public class RunReport extends HibernateDaoSupport {	
	public static void main(String[] args) {
		try {
			runReport();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
 
 
	static void runReport() throws EngineException {
		ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {"applicationContext-dao.xml","applicationContext-resources.xml"});
		RunReport runreport = (RunReport)appContext.getBean("runReport");
		IReportEngine engine = null;
		EngineConfig config = null;
 
		try {
			config = new EngineConfig();
			config.setBIRTHome("D:/download/birt-runtime-2_3_1/ReportEngine");
			config.setLogConfig("E:/logs", java.util.logging.Level.ALL);
			Platform.startup(config);
			IReportEngineFactory factory = (IReportEngineFactory) Platform
					.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
			engine = factory.createReportEngine(config);
 
			IReportRunnable design = null;
			// Open the report design
			design = engine
					.openReportDesign("/appbirt/src/main/java/com/appbirt/report/connectiondemo.rptdesign");
			IRunAndRenderTask task = engine.createRunAndRenderTask(design);
			HTMLRenderOption options = new HTMLRenderOption();
			options.setOutputFileName("E:/passinconnobj.html");
			options.setOutputFormat("HTML");
			task.setRenderOption(options);
			task.getAppContext().put("OdaJDBCDriverPassInConnection",
					runreport.getSession().connection());
			task.run();
			task.close();
			engine.destroy();
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			Platform.shutdown();
		}
	}
}
1
 

 

然后在spring 的配置文件里面配置runReport

<bean id=”runReport” class=”com.appbirt.report.RunReport”>
    <property name=”sessionFactory” ref=”sessionFactory”/>
</bean>

 

记得把上面的环境变量都配置正确,BIRTHOEM ,报表文件的路径,spring 配置文件的路径.

最后应该在 E盘 生成 passinconnobj.html 文件, 这个文件就是你的报表的html 版本. 至于报表文件着随便连一个数据库的都可以. 你的BIRTHOME 里面不需要在 org.eclipse.birt.report.data.oda.jdbc_2.3.1.v20080827 下面添加mysql jdbc driver , 只要你的项目里面有就够了.

下面附上一个最简单的报表文件, 用来可以运行上面的代码的.

 

<?xml version=”1.0″ encoding=”UTF-8″?>
<report xmlns=”http://www.eclipse.org/birt/2005/design” version=”3.2.17″ id=”1″>
    <property name=”createdBy”>Eclipse BIRT Designer Version 2.3.1.v20080911 Build &lt;2.3.1.v20080922-1151></property>
    <property name=”units”>in</property>
    <property name=”iconFile”>/templates/blank_report.gif</property>
    <property name=”bidiLayoutOrientation”>ltr</property>
     <data-sources>
        <oda-data-source extensionID=”org.eclipse.birt.report.data.oda.jdbc” name=”Data Source” id=”6″>
            <!–
            <text-property name=”displayName”></text-property>
            <property name=”odaDriverClass”>com.mysql.jdbc.Driver</property>
            <property name=”odaURL”>jdbc:mysql://localhost:3306/appbirt</property>
            <property name=”odaUser”>root</property>
            <encrypted-property name=”odaPassword” encryptionID=”base64″>MTIzNA==</encrypted-property>
            –>
        </oda-data-source>  
    </data-sources>   
    <data-sets>
        <oda-data-set extensionID=”org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet” name=”Data Set” id=”7″>
            <structure name=”cachedMetaData”>
                <list-property name=”resultSet”>
                    <structure>
                        <property name=”position”>1</property>
                        <property name=”name”>id</property>
                        <property name=”dataType”>decimal</property>
                    </structure>
                    <structure>
                        <property name=”position”>2</property>
                        <property name=”name”>account_expired</property>
                        <property name=”dataType”>integer</property>
                    </structure>
                    <structure>
                        <property name=”position”>3</property>
                        <property name=”name”>account_locked</property>
                        <property name=”dataType”>integer</property>
                    </structure>
                    <structure>
                        <property name=”position”>4</property>
                        <property name=”name”>address</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>5</property>
                        <property name=”name”>city</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>6</property>
                        <property name=”name”>country</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>7</property>
                        <property name=”name”>postal_code</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>8</property>
                        <property name=”name”>province</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>9</property>
                        <property name=”name”>credentials_expired</property>
                        <property name=”dataType”>integer</property>
                    </structure>
                    <structure>
                        <property name=”position”>10</property>
                        <property name=”name”>email</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>11</property>
                        <property name=”name”>account_enabled</property>
                        <property name=”dataType”>integer</property>
                    </structure>
                    <structure>
                        <property name=”position”>12</property>
                        <property name=”name”>first_name</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>13</property>
                        <property name=”name”>last_name</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>14</property>
                        <property name=”name”>password</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>15</property>
                        <property name=”name”>password_hint</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>16</property>
                        <property name=”name”>phone_number</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>17</property>
                        <property name=”name”>username</property>
                        <property name=”dataType”>string</property>
                    </structure>
                    <structure>
                        <property name=”position”>18</property>
                        <property name=”name”>version</property>
                        <property name=”dataType”>integer</property>
                    </structure>
                    <structure>
                        <property name=”position”>19</property>
                        <property name=”name”>website</property>
                        <property name=”dataType”>string</property>
                    </structure>
                </list-property>
            </structure>
            <property name=”dataSource”>Data Source</property>
            <list-property name=”resultSet”>
                <structure>
                    <property name=”position”>1</property>
                    <property name=”name”>id</property>
                    <property name=”nativeName”>id</property>
                    <property name=”dataType”>decimal</property>
                </structure>
                <structure>
                    <property name=”position”>2</property>
                    <property name=”name”>account_expired</property>
                    <property name=”nativeName”>account_expired</property>
                    <property name=”dataType”>integer</property>
                </structure>
                <structure>
                    <property name=”position”>3</property>
                    <property name=”name”>account_locked</property>
                    <property name=”nativeName”>account_locked</property>
                    <property name=”dataType”>integer</property>
                </structure>
                <structure>
                    <property name=”position”>4</property>
                    <property name=”name”>address</property>
                    <property name=”nativeName”>address</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>5</property>
                    <property name=”name”>city</property>
                    <property name=”nativeName”>city</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>6</property>
                    <property name=”name”>country</property>
                    <property name=”nativeName”>country</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>7</property>
                    <property name=”name”>postal_code</property>
                    <property name=”nativeName”>postal_code</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>8</property>
                    <property name=”name”>province</property>
                    <property name=”nativeName”>province</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>9</property>
                    <property name=”name”>credentials_expired</property>
                    <property name=”nativeName”>credentials_expired</property>
                    <property name=”dataType”>integer</property>
                </structure>
                <structure>
                    <property name=”position”>10</property>
                    <property name=”name”>email</property>
                    <property name=”nativeName”>email</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>11</property>
                    <property name=”name”>account_enabled</property>
                    <property name=”nativeName”>account_enabled</property>
                    <property name=”dataType”>integer</property>
                </structure>
                <structure>
                    <property name=”position”>12</property>
                    <property name=”name”>first_name</property>
                    <property name=”nativeName”>first_name</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>13</property>
                    <property name=”name”>last_name</property>
                    <property name=”nativeName”>last_name</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>14</property>
                    <property name=”name”>password</property>
                    <property name=”nativeName”>password</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>15</property>
                    <property name=”name”>password_hint</property>
                    <property name=”nativeName”>password_hint</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>16</property>
                    <property name=”name”>phone_number</property>
                    <property name=”nativeName”>phone_number</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>17</property>
                    <property name=”name”>username</property>
                    <property name=”nativeName”>username</property>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”position”>18</property>
                    <property name=”name”>version</property>
                    <property name=”nativeName”>version</property>
                    <property name=”dataType”>integer</property>
                </structure>
                <structure>
                    <property name=”position”>19</property>
                    <property name=”name”>website</property>
                    <property name=”nativeName”>website</property>
                    <property name=”dataType”>string</property>
                </structure>
            </list-property>
            <property name=”queryText”>select *
from app_user</property>
            <xml-property name=”designerValues”><![CDATA[]]></xml-property>
        </oda-data-set>
    </data-sets>
    <styles>
        <style name=”crosstab-cell” id=”4″>
            <property name=”borderBottomColor”>#CCCCCC</property>
            <property name=”borderBottomStyle”>solid</property>
            <property name=”borderBottomWidth”>1pt</property>
            <property name=”borderLeftColor”>#CCCCCC</property>
            <property name=”borderLeftStyle”>solid</property>
            <property name=”borderLeftWidth”>1pt</property>
            <property name=”borderRightColor”>#CCCCCC</property>
            <property name=”borderRightStyle”>solid</property>
            <property name=”borderRightWidth”>1pt</property>
            <property name=”borderTopColor”>#CCCCCC</property>
            <property name=”borderTopStyle”>solid</property>
            <property name=”borderTopWidth”>1pt</property>
        </style>
        <style name=”crosstab” id=”5″>
            <property name=”borderBottomColor”>#CCCCCC</property>
            <property name=”borderBottomStyle”>solid</property>
            <property name=”borderBottomWidth”>1pt</property>
            <property name=”borderLeftColor”>#CCCCCC</property>
            <property name=”borderLeftStyle”>solid</property>
            <property name=”borderLeftWidth”>1pt</property>
            <property name=”borderRightColor”>#CCCCCC</property>
            <property name=”borderRightStyle”>solid</property>
            <property name=”borderRightWidth”>1pt</property>
            <property name=”borderTopColor”>#CCCCCC</property>
            <property name=”borderTopStyle”>solid</property>
            <property name=”borderTopWidth”>1pt</property>
        </style>
    </styles>
    <page-setup>
        <simple-master-page name=”Simple MasterPage” id=”2″>
            <page-footer>
                <text id=”3″>
                    <property name=”contentType”>html</property>
                    <text-property name=”content”><![CDATA[<value-of>new Date()</value-of>]]></text-property>
                </text>
            </page-footer>
        </simple-master-page>
    </page-setup>
    <body>
        <table id=”8″>
            <property name=”width”>100%</property>
            <property name=”dataSet”>Data Set</property>
            <list-property name=”boundDataColumns”>
                <structure>
                    <property name=”name”>id</property>
                    <property name=”displayName”>id</property>
                    <expression name=”expression”>dataSetRow["id"]</expression>
                    <property name=”dataType”>decimal</property>
                </structure>
                <structure>
                    <property name=”name”>account_expired</property>
                    <property name=”displayName”>account_expired</property>
                    <expression name=”expression”>dataSetRow["account_expired"]</expression>
                    <property name=”dataType”>integer</property>
                </structure>
                <structure>
                    <property name=”name”>account_locked</property>
                    <property name=”displayName”>account_locked</property>
                    <expression name=”expression”>dataSetRow["account_locked"]</expression>
                    <property name=”dataType”>integer</property>
                </structure>
                <structure>
                    <property name=”name”>address</property>
                    <property name=”displayName”>address</property>
                    <expression name=”expression”>dataSetRow["address"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>city</property>
                    <property name=”displayName”>city</property>
                    <expression name=”expression”>dataSetRow["city"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>country</property>
                    <property name=”displayName”>country</property>
                    <expression name=”expression”>dataSetRow["country"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>postal_code</property>
                    <property name=”displayName”>postal_code</property>
                    <expression name=”expression”>dataSetRow["postal_code"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>province</property>
                    <property name=”displayName”>province</property>
                    <expression name=”expression”>dataSetRow["province"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>credentials_expired</property>
                    <property name=”displayName”>credentials_expired</property>
                    <expression name=”expression”>dataSetRow["credentials_expired"]</expression>
                    <property name=”dataType”>integer</property>
                </structure>
                <structure>
                    <property name=”name”>email</property>
                    <property name=”displayName”>email</property>
                    <expression name=”expression”>dataSetRow["email"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>account_enabled</property>
                    <property name=”displayName”>account_enabled</property>
                    <expression name=”expression”>dataSetRow["account_enabled"]</expression>
                    <property name=”dataType”>integer</property>
                </structure>
                <structure>
                    <property name=”name”>first_name</property>
                    <property name=”displayName”>first_name</property>
                    <expression name=”expression”>dataSetRow["first_name"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>last_name</property>
                    <property name=”displayName”>last_name</property>
                    <expression name=”expression”>dataSetRow["last_name"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>password</property>
                    <property name=”displayName”>password</property>
                    <expression name=”expression”>dataSetRow["password"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>password_hint</property>
                    <property name=”displayName”>password_hint</property>
                    <expression name=”expression”>dataSetRow["password_hint"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>phone_number</property>
                    <property name=”displayName”>phone_number</property>
                    <expression name=”expression”>dataSetRow["phone_number"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>username</property>
                    <property name=”displayName”>username</property>
                    <expression name=”expression”>dataSetRow["username"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
                <structure>
                    <property name=”name”>version</property>
                    <property name=”displayName”>version</property>
                    <expression name=”expression”>dataSetRow["version"]</expression>
                    <property name=”dataType”>integer</property>
                </structure>
                <structure>
                    <property name=”name”>website</property>
                    <property name=”displayName”>website</property>
                    <expression name=”expression”>dataSetRow["website"]</expression>
                    <property name=”dataType”>string</property>
                </structure>
            </list-property>
            <column id=”107″/>
            <column id=”108″/>
            <column id=”109″/>
            <column id=”110″/>
            <column id=”111″/>
            <column id=”112″/>
            <header>
                <row id=”9″>
                    <cell id=”10″>
                        <label id=”11″>
                            <text-property name=”text”>id</text-property>
                        </label>
                    </cell>
                    <cell id=”12″>
                        <label id=”13″>
                            <text-property name=”text”>account_expired</text-property>
                        </label>
                    </cell>
                    <cell id=”14″>
                        <label id=”15″>
                            <text-property name=”text”>account_locked</text-property>
                        </label>
                    </cell>
                    <cell id=”16″>
                        <label id=”17″>
                            <text-property name=”text”>address</text-property>
                        </label>
                    </cell>
                    <cell id=”18″>
                        <label id=”19″>
                            <text-property name=”text”>city</text-property>
                        </label>
                    </cell>
                    <cell id=”20″>
                        <label id=”21″>
                            <text-property name=”text”>country</text-property>
                        </label>
                    </cell>
                </row>
            </header>
            <detail>
                <row id=”48″>
                    <cell id=”49″>
                        <data id=”50″>
                            <property name=”resultSetColumn”>id</property>
                        </data>
                    </cell>
                    <cell id=”51″>
                        <data id=”52″>
                            <property name=”resultSetColumn”>account_expired</property>
                        </data>
                    </cell>
                    <cell id=”53″>
                        <data id=”54″>
                            <property name=”resultSetColumn”>account_locked</property>
                        </data>
                    </cell>
                    <cell id=”55″>
                        <data id=”56″>
                            <property name=”resultSetColumn”>address</property>
                        </data>
                    </cell>
                    <cell id=”57″>
                        <data id=”58″>
                            <property name=”resultSetColumn”>city</property>
                        </data>
                    </cell>
                    <cell id=”59″>
                        <data id=”60″>
                            <property name=”resultSetColumn”>country</property>
                        </data>
                    </cell>
                </row>
            </detail>
            <footer>
                <row id=”87″>
                    <cell id=”88″/>
                    <cell id=”89″/>
                    <cell id=”90″/>
                    <cell id=”91″/>
                    <cell id=”92″/>
                    <cell id=”93″/>
                </row>
            </footer>
        </table>
    </body>
</report>

 

注意我在上面的报表中故意将数据库连接的参数注释掉了

这种方式可以直接使用应用程序的数据库连接池了.

现在BIRT已经支持如下这些方式的数据库连接:

1-Property binding
2-JNDI
3-Script data set
4-DataSource.beforeOpen() event.
5–driverBridge extension
6-Application Context Ojbect  (上面演示的)

 

参考资料

http://birtworld.blogspot.com/2008/11/birt-connection-pooling-continued-again.html

分类: BIRT 标签:

eclipse top committer 提名

2008年12月24日 没有评论

最近eclipse 开始提名top committer , 你认为谁对社区做出的贡献值得肯定.我个人提名BIRT 的主开发者Jason Weathersby ,尤其他对BIRT 的贡献的确很大,如果你也喜欢BIRT 的话,请一起提名, 地址如下:

https://bugs.eclipse.org/bugs/process_bug.cgi

 

我提名很简单:

+ 1 for Jason Weathersby ,  he deserves it , fighting!!!
不知道是不是受到<<情书>>的影响,反正上去闹一下眼子.
fighting!!!
分类: BIRT 标签:

在团队中用 BIRT 进行报表开发

2008年7月28日 没有评论

转载自http://www.ibm.com/developerworks/cn/opensource/os-cn-eclipse-birtinteam/index.html

杨 震 (zhenyang@cn.ibm.com), 软件工程师, IBM

2008 年 7 月 16 日

本文主要介绍如何在 BIRT 中创建,使用库( Library )和模板,及如何在报表中使用用户自定义的 JS 文件。

前言

BIRT 是一个基于 Eclipse 的开源报表插件,特别适用于给 J2EE 的 WEB 应用程序创建报表。随着 BIRT 的不断完善,采用 BIRT 进行报表设计的人也越来越多。而随着 BIRT 应用的深入,很多人都碰到了这样一些问题:

  • 在一个团队中,不同的设计者设计报表的时候,如何能够保证报表风格的统一?
  • 如何能够使得您的设计得到重用,从而提高工作效率?
  • 如何能够集中定义一些常用的资源,从而避免一处资源的变动,所有报表都要修改的情况发生?

由于BIRT的官方文档还不是很完善,很多问题都还不能在官方文档找到详细的说明。本文将会试图通过实际的例子,帮助读者解决以上一些问题。

BIRT 的主要组件分为两部分: BIRT 报表设计器和 BIRT 运行引擎。本文将主要介绍 BIRT报表设计器中的一些功能。作为 BIRT 的进阶教程,本文将不会涉及到如何用 BIRT 创建简单报表的内容,需要读者对 BIRT 有一些初步的认识,并且掌握 BIRT 报表的基本设计方法。


 

示例项目及相关设置介绍

为了方便读者理解,在开始介绍正式内容之前,先简单介绍一下本文中将会用到的 BIRT 示例项目和相关设置。

本文中用到的项目名称为 BirtIntroduction ,项目结构如下图:

图 1:示例项目层次结构
示例项目层次结构

其中:

  • JavaScripts 文件夹用于存放用户自定义的 JavaScript 文件。
  • lib 文件夹用于存放用户建立的库( Library )文件。
  • pic 文件夹用于存放所有报表中会用到的图片。
  • template 文件夹用于存放用户建立的模板文件。
  • 所有的报表文件都会建立在 BirtIntroduction 下面。

在开始使用这些资源之前,还需要在Eclipse里面设置资源所在的位置。具体设置方法如下:

在Eclipse中选择 Window -> Preference ,打开 Eclipse 设置窗口,选择 Report Design -> Resource 设置资源文件夹为当前项目所在位置,如下图:

图 2:设置资源位置根目录
设置资源位置根目录

“ D:/BIRTReport/BirtIntroduction/ ” 是这个项目的绝对路径。 相关设置做好后,就可以开始我们的正式内容了。


在报表中使用用户自定义的 JavaScript 文件

BIRT 给设计者提供了强大的数据控制功能,它不仅提供了一些常用的函数,而且还允许设计者在报表中自定义JavaScript方法,并利用这些函数对报表输出样式,数值等因素进行修改,计算。但是,在大型项目中,如果很多功能相同的 JavaScript 方法的定义分布在各个报表中,对设计者来说,修改报表中的 JavaScript 将会成为噩梦一样的事情。那么 BIRT 能不能把这些功能相同的函数集中定义在一个 JS 文件中,并在 BIRT 中得以应用呢?答案是肯定的。

由于 BIRT 并没有给使用者提供 GUI 的方式为报表添加用户自定义的 JS 文件。所以我们只能通过修改 .rptdesign 文件的源文件进行 JS 文件的添加,删除工作。请看下面的详细步骤:

首先,我们要先创建自己的 JavaScript 文件。如下图:

图 3:创建 JavaScript 文件
创建 JavaScript 文件

创建的 JavaScript 文件名为 demo_scripts.js 。接下来,在新建的 JavaScript 文件中写入自定义的方法。下面是将在本文中用到的一个简单的方法,主要目的是把传入的两个数字参数通过下划线连接在一起,并且返回。

清单 1. 自定义的 JavaScript 方法

function combine(num1, num2) {
	var str = num1 + '_' + num2;
	return str;
}

JavaScript 文件定义好了以后,就可以在报表中使用了,具体使用方法是:

打开报表定义文件,并且在主编辑区切换到” XML Source ”标签,然后在报表定义文件中加入如下语句。

清单 2. 把用户自定义的 JavaScript 文件加入到报表中

<list-property name="includeScripts">
        <property>JavaScripts/demo_scripts.js</property>
</list-property>

如下图:

图 4:在报表中使用 JavaScript 文件

在报表中使用 JavaScript 文件

由于在文章开始的地方已经设置好了资源根目录,所以” JavaScripts/demo_scripts.js ”这个相对路径映射的绝对路径就是“ D:/BIRTReport/BirtIntroduction/JavaScripts/demo_scripts.js ”。

到这里就可以在报表中使用 demo_scripts.js 中定义的所有方法了。使用方法请看下面的简单例子。

在报表中用鼠标双击 Number 列,打开数据编辑窗口,输入名称为 CombineNum ,如下图

图 5:打开数据编辑窗口

打开数据编辑窗口

单击 fx 按钮,打开表达式编辑窗口,输入如下内容:

清单 3. 使用 JS 文件中的方法

combine(row["CUSTOMERNUMBER"],row["ORDERNUMBER"])

如下图

图 6:使用 JS 文件中的方法-1

使用 JS 文件中的方法-1

选择 OK 按钮,确认输入,回到报表设计页面中。如图 7

图 7:使用 JS 文件中的方法-2

使用 JS 文件中的方法-2

下面让我们来预览一下这个报表,如图 8:

图 8:预览报表

预览报表

在图8中,我们发现 NUMBER 列中的数据是合并以后的。这说明我们的方法起到了作用。是不是很简单?

不过,这里要特别指出的一点是,BIRT还是一个发展中的工具,有些地方还不是很完善。所以用户自定义的JS文件在报表的有些地方还不能够使用。比如,在图表( Chart )中的 Script 中,如果想在 Event Function 使用JS文件中的方法,在当前版本中(2.2.2)是不行的。据 BIRT 的开发者说,这是因为图表( Chart )的渲染引擎是一个独立的部分。当然,暇不掩玉,相信 BIRT 会很快修正这些问题的!!

 

BIRT 中库( Library )的创建与应用

库( Library )是一组用户自定义的报表元素的集合,比如数据源,常用的数据集,通用的报表参数定义等等。通过库的应用,设计者可以集中定义常用资源,重用功能设计。

下面将会详细介绍库在BIRT中的创建与应用:

创建库( Library

在lib文件夹上单击鼠标右键,并在弹出菜单中选择 New -> Library , 如下图 9 所示:

图 9:创建库

创建库

在接下来的窗口中输入这个库的名字,如图10

图 10:输入库的名字

输入库的名字

库是以 .rptlibrary 为扩展名的文件。例子中的库名为 demo_library.rptlibrary 。

打开新建的库,你会发现基本所有能在报表中定义的元素都可以在这里定义。开发者可以从项目中汲取可被重用的资源,集中定义到库中来。比如数据源定义,常用的数据集定义等等。

在下面的例子中,以一个数据源的定义说明了如何在库中添加新的项目。

和在报表中定义数据源一样,在 Data Explorer -> Data Sources 上右键单击鼠标,在弹出菜单中选择 New Data Source 。

图 11:在库中创建数据源

在库中创建数据源

选择数据源类型,并且输入数据源名称,并选择下一步( Next ),本例中,数据源名称为 Demo_Data_Source 。如图 12 所示:

图 12:输入数据源的名称及类型

输入数据源的名称及类型

在下面的数据源定义窗口中输入数据源的信息

图 13:输入数据源的信息

输入数据源的信息

单击确定( OK )按钮,完成数据源的创建。到此,我们就为库中创建了一个数据源。

库创建好了,如何在我们的报表中使用库中的资源呢?下面将会讲解库的使用。

在报表中使用库 Library

首先,打开您的报表文件,在 Library Explore 中选择要用到的库,在这个例子中为 lib -> demo_library.rptlbrary 。在库上单击鼠标右键,然后选择 Use Library 选项。如图14所示

图 14:使用库

使用库

继续打开您的报表设计页面,并选中 Outline 视图,把定义在库中的报表元素用鼠标从 Library Explore 视图中拖到 Outline 中相应的位置。本例中为把数据源 Demo_Data_Source 添加到 DemoReport.rptdesign 中去,如图 15 所示:

图 15:使用库中定义的元素

使用库中定义的元素

这时,当创建数据集时,您会发现已经可以用到这个数据源了,如图 16 所示:

图 16:使用库中的数据源创建数据集

使用库中的数据源创建数据集

在进行报表设计的时候,当您库中的数据源或其他库中信息更新后,您需要刷新一下您的报表,从而使更新后的库中的元素起到作用。方法是,打开您的报表,在 Outline -> 您的报表上单击鼠标右键,然后选择 Refresh Library 选项来更新报表,如图 17 所示:

图 17:更新库中的信息

更新库中的信息

如果您的项目规模很大,库的使用好坏与否,将在很大程度上决定项目后期维护上的难度。想象一下,您的项目中有上百个报表,但并没有用到库,如果您的报表的数据源发生了改变,那么上百个报表,每个报表的数据源都要重新修改一下,这将是一件很麻烦的事情。所以,在报表设计之前,先将常用资源定义在库中会是一个很好的开发习惯。

使用模板( Template )定制统一的报表风格

一个团队中,每个人的审美观都是不完全一致的,如果没有一个集中的控制,不同的队员设计出不同风格的报表会使得一个项目变得像很多项目的集合。在一个项目中,维护报表风格的统一至关重要。BIRT为开发者提供了模板的概念,通过使用相同的模板,可以保证团队中不同设计者设计出来的报表风格统一。

BIRT 的模板中定义了报表的版面设置,字体大小,配色方案等一系列设置, 下面将详细讲解BIRT 模板的创建与使用方法。

创建模板 Template

在 Eclipse 中选择 File -> New –> Template ,如图 18 所示:

图 18:创建新的模板

创建新的模板

在接下来的窗口中,为新模板输入一个名字,并且写上一些注释。这些注释对不熟悉这个模板的使用者来说,将会有很大的帮助,如图 19 所示:

图 19:输入模板信息

输入模板信息

选择结束( Finish )创建新的模板。

接下来,打开新的模板,您可以像定义普通报表一样在模板中添加必要的元素,例如字体的大小,页眉页脚的设置等等,下面的例子在模板中定义了一个数据集,一个图( Chart )和一些页面设置,如图 20,21,22 所示:

图 20:模板中用到的数据集

模板中用到的数据集

图 21:模板中定义的主要内容

模板中定义的主要内容

图 22:模板中定义的 Master Page

模板中定义的 Master Page

让我们来预览一下这个模板的样子,如图 23:

图 23:预览模板

预览模板

模板创建好了之后,需要发布出去才能使用,方法是:鼠标右键点击创建的模板,选择 Register Template with New Report Wizard 如图 24 所示:

图 24:发布模板

在接下来的窗口中为模板输入名称和描述,在这个例子中,模板的名字叫 DemoTemplate ,如图 25 所示

图 25:发布模板-输入名称和描述

发布模板-输入名称和描述

这样一个模板就可以被使用了。

使用模板 Template 创建报表

下面我们将用一个例子来说明如何用刚刚创建的模板建造新的报表。

在 Eclipse 中选择 File -> New -> Report , 如图 26 所示:

图 26:创建新的报表

创建新的报表

在接下来的窗口中输入报表的名称及所在文件夹,本例中报表名称为 demo_report_from_template..rptdesign , 如图 27 所示:

图 27:输入报表名称

输入报表名称

在接下来的窗口中,可以看到刚刚发布的模板 DemoTemplate ,选择这个模板,如图 28 所示:

图 28:选择模板

选择模板

单击结束( Finish )按钮,报表就生成好了,我们来看看新生成的报表,如图 29:

图 29:从模板中生成的报表

从模板中生成的报表

在预览一下新建的报表,如图 30 所示:

图 30:预览新的报表

预览新的报表

是不是和刚刚建立的模板完全一致?这时,报表设计者只需要修改相应的数据集,参数等与其他报表不同的地方,并保留模板自带的风格,就可以做出风格统一,但用处不一样的报表来了。

 

结束语

虽然 BIRT 还存在着这样那样的一些小问题,但是在报表领域,它已经成长成为一股不可被忽视的力量。相信随着 BIRT 的不断完善,我们会拥有一个完美的报表工具。

 

下载

样例代码        BirtIntroduction.rar      16KB     

http://www.ibm.com/developerworks/cn/opensource/os-cn-eclipse-birtinteam/BirtIntroduction.rar

分类: BIRT 标签:

Eclipse商业智能与报表工具2.3新功能介绍

2008年7月25日 没有评论

摘要:Eclipse的商业智能和报表工具(BIRT)项目是一个基于当今流行的Eclipse IDE的开源项目,用于在Java或者J2EE环境下构建和部署报表。这次eclipse BIRT2.3版随着eclipse 3.4的发行版Ganymede一同发行, 本文将以实例的方式介绍这次BIRT 的新功能,我们讲重点介绍其中部分大家最关心的特性包括Crosstab增强,脚本和图表. 如果你想了解完整的BIRT 2.3新功能,你可以查看它的发行说明:

http://www.eclipse.org/birt/phoenix/project/notable2.3.php

 

1. Crosstab增强

Crosstab 是最适合用来展示行和列不固定的表样,一个Crosstab 一般都是由度量和维组成,BIRT 2.2的时候Crosstab 还只能展示基本的信息,这次BIRT 2.3一次为我们带来了很多增强功能.

1 Crosstab 可以有Crosstab 头部标签.

clip_image002

图1 . Crosstab 的头部标签(左上角红色部分)

2 Crosstab 度量过滤

在之前的版本,Crosstab 只能在维上过滤,这次2.3 版同样支持在度量上过滤了.

图1 中所示就是在度量上过滤掉销售额小于50,000的结果.

clip_image004

图2 , Crosstab 度量过滤

3. Crosstab / 配置

Crosstab现在支持当数据不存在的时候单元格的显示. 你可以制定任意文本.

clip_image006

图3 配置Crosstab 当有空行或列时的显示

4. 图形显示度量

一般的Crosstab都是输出数字度量,现在BIRT 2.3 同时还支持图表显示数据. clip_image008

图4 : 图表显示Crosstab 的数据

5. 独立的图表输出

在使用图表输出的时候,你同样可以使用图表向导来分别显示度量按照垂直维的聚合或者水平维的聚合.

如果你按水平维聚合就会像下面第一个图表一样,图形是横向的,如果你按照垂直维聚合,就会像第二个图表一样图表是水平的.

clip_image010

图5 Crosstab的水平或垂直显示图表

6. 派生维

当你想在Crosstab里面使用某种自定义计算的时候,你可以使用派生维, 它跟一般的Data Binding是一样的,你可以使用所有在Crosstab 里面的数据. 并且它还有一个菜单项帮你创建派生维.

clip_image012

图6 派生维

7. 事件支持

Crosstab现在同样支持onPrepare() , onCreate() 和 onRender() 方法.下面的例子演示了Crosstab 的事件和脚本支持.新的Script编辑器同样会显示当前事件是onPrepareCell 还是onPrepareCrosstab .

clip_image014

图7 : Crosstab 支持的onPrepare() , onCreate() , onRender() 事件

clip_image016

图8 Crosstab 的脚本输出

clip_image018

图9 Script 编辑器提示

8. Crosstab图表的beforeDrawMarker , afterDrawMarker 事件支持.

新的Crosstab 图表增加了Marker Handler 用来处理beforeDrawMarker() 和 afterDrawMarker() 事件.

clip_image020

图10 : Crosstab 新图表事件beforeDrawMarker() 和 afterDrawMarker()

2. 图表增强.

1 多视图项目(Multi-View Items

BIRT现在支持把数据绑定到表格,Crosstab , 图表,同样的,数据也可以从表格,Crosstab ,图表里面取出. 现在BIRT支持报表元素有多试图,这些视图都可以共享同样的数据,过滤条件和聚合条件。这些数据视图可以决定它们如何被显示并且和另一个报表元素共享绑定的数据和同一个图表空间. 目前只有表格和Crosstab 支持这个特性,并且第二个视图必须是图表.你可以通过点击表格或Crosstab 然后选择 Create Chart View 菜单.

2 聚合和排序增强.

新的图表现在支持按照分类和Y轴的任意聚合条件进行排序. 同时还加入了一些新的聚合单元类型, 包括时间类型的季度,

3 图表数据源可以是cube元素

新的嵌入式图表可以使用报表的cube数据 , 也就是你在Crosstab 里面看到的图表.

clip_image022

图11: 图表的Data Cube 数据源

4 Cube 图表也可以添加过滤条件

使用Cube 数据源创建的图表同样可以在上面添加过滤条件,你可以过滤选择的值,分类或者Y 轴的聚合数据.

5 饼图可以任意角度旋转.

BIRT 2.3 可以将饼图的第一个切片用任意角度摆放,你可以使用图表编辑向导的饼图旋转滑块来设置.

clip_image024

图12 设置饼图的角度

6 长轴标签增强

现在BIRT 支持当轴的标签文字很长的时候用省略号省略一部分文字.

7 更多图表示例

现在在图表示例试图里面添加了一些新的示例报表用来展示新的图表增强功能.

3. 脚本增强

新的BIRT 2.3 在脚本功能上也有不少新功能,比如前面已经介绍的Crosstab 里面的事件增强功能. 图表里面增加的beforeDrawMarker() 和afterDrawMarker() 事件. 同时它还包括下面一下新的功能.

1. BIRT JavaScript 调试器

BIRT 的事件可以在报表生成或者展现的时候用来处理自定义问题,你可以使用 Java 或者JavaScript 来编写,这些事件处理程序可以用外部代码修改报表内容或在报表引擎处理报表的时候改变它们的行为. 在之前的版本中,如果你想调试用Java 写的事件处理程序,你可以像调试普通Java 程序那样在eclipse 里面编辑. 但是对于JavaScript 事件处理程序却没有提供类似的功能. 新的BIRT 2.3 版本现在支持JavaScript 的调试器, 这个调试器可以和报表调试启动配置一起工作.

clip_image026

图13 报表调试启动配置窗口

当触发事件后,你可以一步一步的执行,或者设置断点.

clip_image028

图14 JavaScript 设置断点

2. JavaScript 编辑器的增强

新的 JavaScript 编辑器编辑页面可以列出一个报表元素所有的事件方法,而不是一次只列出一个方法, 编辑器同样也支持代码折叠,设置断点.

clip_image030

图15 增强的JavaScript 编辑器

3. Script 自动验证

新的JavaScript 编辑器可以帮助开发者更好的验证代码,包括在编译前验证或者调试的时候发现错误的代码. clip_image032

图16 调试的时候发现错误

clip_image034

图17 编译之前自动验证

4 更友好的出错信息提示

在提供脚本验证之外,BIRT 同样也提高了错误信息的描述.以便于我们更好的发现问题

clip_image036

图18 更好的出错信息

本文作者: gemini5201314 (gemini5201314@gmail.com)

4. 其他一些增强功能

1 更好的外部样式表支持

BIRT 可以把元素的样式放在报表元素里面,创建一个新样式(同样也是储存在报表里),或者从一个外部样式文件导入(就像CSS 那样),或者连接到外部的样式表 , 之前的版本中连接样式表文件必须放在resource 文件夹里面, BIRT 2.3 现在支持报表可以在查看的时候连接外部样式表. 它可以引用一个完整或者相对的URL.

比如你可以使用resource/style/ LinksPasteBlue.css 文件, 它的相对URL是根据你的应用程序位置而设定.

clip_image038

图19 相对或绝对URL 链接 ,只在HTML 输出使用样式表.

2. 水平分页支持

当开发一个包含很多列的报表时,如何合理的控制页面宽度就变成了一个问题,BIRT 2.3 新增加的水平分页功能能同时支持表格和Crosstab , 你可以通过点击你想要分割的那一列然后在Page Break 的After 里面设置Always 属性. Crosstab 同样可以通过点击Column Area 的Page Break 来水平分页.

clip_image040

图20 水平分页

3 Library 改变

原来的Library Explorer 试图现在改名叫作Resource Explorer ,它包括多项改进包括使用特定的resource folder 可以导航所有的资源包括图片,脚本,jars 和libraries , 在UI上也有许多的改变,包括在resource folder添加或创建内容,另外你可以使用菜单添加任何一个报表的元素到library.

clip_image042

图21 新的Library

4 多结果集储存过程支持

BIRT 现在支持通过JDBC Driver 来调用储存过程. BIRT 2.3现在的编辑器提供一个新的选项让开发者来选择执行的储存过程的名字和数量. Oracle 的储存过程也可以有输出参数.

clip_image044

图22 多结果集储存过程

5 粘贴复制样式表格式

BIRT 支持连接或者导入样式表给报表元素,这可以让报表元素之间共享一些属性,BIRT 2.3 现在可以从一个报表元素上面复制样式到另外一个元素上面, 当然,你也可以使用Ctrl+C 加上Ctrl+ V

clip_image046

图23 复制粘贴样式

6 项目特定设置

Eclipse 在3.4版本中支持了每一个项目可以单独使用一个特定的项目设定,BIRT 现在同样可以一个项目使用一个或多个设定,这些设定就是你在preference 页面可以看到的BIRT 的项目设定,包括预览的行数,crosstab 的设定,元素的名称,resource 和 template 文件夹的位置等. 现在你可以将这些设定导出或储存起来, 从而可以提供多个项目使用, 或一个项目在开发或部署的时候使用不同的项目设定.

clip_image048

图24 项目特定设定

7. 添加JavaScript文件UI 支持

如果你要调用一段脚本多次的话,你可能更愿意将这些脚本写进一个JavaScript 文件里,这样,每次你调用的时候就不用重复函数体了,并且当你修改的时候也只用修改一处. 你可以把创建这些函数的过程放在beforeGeneration 事件之前并储存进reportContext 以便全局调用. BIRT 现在也提供一个GUI 菜单让你把resource folder 里面的JavaScript 文件添加进报表,这样,当JavaScript 文件添加进去以后,你就可以在BIRT 的脚本表达式或事件实现里面调用这些函数. 这个按钮被添加在了报表的general properties 里面的resources tab 下面. 你也可以把这个应用在library 里面. 之前的版本也支持这个功能,只是没有GUI,你可以在报表开头添加

<list-property name=”includeScripts”>

<property>myjsfile.js</property>

</list-property>

clip_image050

图25 添加JavaScript GUI支持

8. Connection Profile 向导

当创建一个数据源时,开发者可以使用connection profile 来取得数据源的属性, 这个connection profile 是被DTP Data Explorer 试图创建的,它包括用户名和密码,在之前的版本中,你必须先创建connection profile ,然后才能在创建report 的时候使用它,现在BIRT 2.3 提供一个新的向导让你在data source 编辑器里面就可以创建connection profile.

9 SQL Query Builder 原型

BIRT 2.3提供一个来自DTP SQL Query Builder (SQB)的功能并使用了DTP的Database Connectivity framework. 这个集成的SQB功能同时提供一个图形化的构建器和一个文本编辑器来创建SQL Query , 用户无论是使用文本编辑器或图形编辑器都可以自动反映到另外一个. 它使用了一个内建的SQL 分析器,目前这一功能还只是一个原型,并且不提供任何向后支持.

clip_image052

图26 新的Query Build

10 预览扩展点

BIRT 现在使用应用程序上下文对象来储存引擎的配置信息,比如图像的位置, 生成超链接时的URL配置, 图表生成的时候图片的格式 ,这些应用程序上下文在报表生成和展现的时候都可用,你可以使用Report Engine API 或者session 变量. 在你运行BIRT 之前,你可以把这些定制化的信息储存在应用程序上下文中,然后使用BIRT 表达式或者脚本来取得这些属性,这对于开发的时候测试或调试报表的时候尤其有用. 现在BIRT 提供一个预览扩展点,这个扩展点提供一个插件让程序在运行报表之前改变应用程序上下文.

应用程序扩展点提供两个函数,getName()和getAppContext() ,getName() 用来命名你实现扩展点的名字,getAppContext() 用来从你的插件取得应用程序上下文.

clip_image054

图27 预览的扩展点

11 边框样式

现在BIRT 2.3 提供了四种新的边框样式: Groove, Ridge, Inset, and Outset .

clip_image056

图28 新的边框样式

12 新的聚合函数CONCATENATE

BIRT 2.3 提供一个新的聚合函数CONCATENATE 用来吧字符串连接在一起,你可以指定中间用什么符号隔开比如逗号或分号.

clip_image058

图29 新的CONCATENATE 函数

13 生成report Document

新的report run 菜单里面有一个新选项可以让你选中的report 生成report Document.

clip_image060

图30 生成report Document 菜单

另外还有一些新功能或增强,下面一次性列出:

双向报表的支持,主要用来支持阿拉伯语言的报表

新的数据装载API 用来取得和装载数据集,主要用来输出像是CSV 这样的格式.

Pdf 和postscript 的模板优化,减少了这些模板的体积

新的应用程序上下文可以在报表运行的时候设定JDBC Driver的classpath. 你可以在应用程序上下文里面使用(“OdaJDBCDriverClassPath”) 把属性传给报表查看器.

另外新的ROM (Report Object Model) 从eclipse help 的文档菜单移除了,在之前的版本,你都可以在eclipse 的help 菜单中看到BIRT 的ROM的,新版本中由于很多BIRT 报表引擎,设计引擎和图表引擎的API上的改变, 所以将ROM 从eclipse help 菜单中移除,如果你想查看新的ROM ,你可以从eclipse 的站点下载它的birt-source 包,里面还是包括了ROM ,不过上面的文档不一定是最新的,随时可能因为API的改变而改变.

在新的BIRT 2.3版本中我们看到了强大的开源报表工具框架BIRT 不仅添加了很多激动人心的新功能,同时还做了许许多多易用性上的改进.作为一款免费并且开源的产品,相信更多人会选择BIRT 作为他们报表开发的第一选择.

 

如果你对BIRT 有兴趣的话,你可以在以下站点找到更多BIRT资源,包括很多文章,报表示例,代码等.

http://www.eclipse.org/birt/phoenix/ birt 官方站点,提供下载,教程,代码等各种资源.

http://www.birt-exchange.com/ Actuate 建立的用来宣传birt 的社区,你可以在上面找到很多报表示例,你也可以在上面提问, 会有很多Actuate 回答你的问题

http://www.actuatechina.com/ Actuate 的中文社区,你在上面可以用中文提问,安迅的工程师会第一时间为你做出解答.

分类: BIRT 标签: