BIRT报表不多说了,java的,Free的,顺便说下,网上很多BIRT帖子的下面评论很多某某司的水军回复,鄙视下,别人都是开源免费的,还攻击,真的是很汗颜,有本事你也开源,有本事去攻击Cognos之类的啊。算了,不说了,我们的特色,你懂的。
下面来说说BIRT中可能遇到的一些常见几个问题,网上的都是版本比较旧的,我用的版本是BIRT 4.5。
1.排序
排序的方法有几种,网上的很多例子是旧版的,对birt 4.5来说操作不了,导致绕了不少弯路,后来找到一个帖子http://developer.actuate.com/community/forum/index.php?/files/file/1021-dynamic-column-sorting/ ,这里还是把注意的步骤说下。
1. 创建“SortKey” & “SortDir” report parameter.(Deselect “Is Required” & select “hidden”)
2. 选择设计视图上的表(右下边有个格子出现), Properties - General - Name 给表取个名字, testtable
3. 点击底部空白,点击Script,在beforeFactory下面输入:
table = reportContext.getDesignHandle().findElement("testtable");
if (params["SortDir"].value == "Desc"){
table.getListProperty("sort").get(0).setProperty("direction","desc");
}else{
table.getListProperty("sort").get(0).setProperty("direction","asc");
}
4.点击你要排序的列头
->Property Editor ->Properties - > hyperlink-> click Edit “Link To”.
Select Drill-through.
Select Report Design to current report by browsing.
In report parameters Click on add – Select “SortDir” past Value
if (params["SortKey"].value == "column") { if (params["SortDir "].value == "Asc") { "Desc"; }else{ "Asc"; } }else{ "Asc"; }SortKey参数里面输入 "column" 包括引号
添加其他所有参数(除了__htmlPagination)
再选择表,In property Editor -> Sorting -> add – Update Key to
if ( params["SortKey"].value == "colnumn"){
row["column"];
}
保存,看看效果怎么样,其他的排序,重复做下。
这种排序还是有点复杂的,可否利用jquery的插件来给表排序呢?可以试试,我在设计视图最底下,添加了一个Dynamic Text,输入动态html文本
<script>
head.load("http://code.jquery.com/jquery-latest.min.js","//cdn.datatables.net/1.10.10/css/jquery.dataTables.min.css","//cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js",function(){
console.log("DataTables framework loaded...");
console.log($("#myTableID").html());
format=$("#myTableID").DataTable();
console.log("Interactive table is ready!");
});
</script>
用datatable来自动排序,这样其实是可以的,不过悲剧就是其他的打印、导出之类的工具就用不了,查了文档jquery和birt的prototype有冲突,有兴趣的可以试试解决下。
2.授权认证
有几种方法,我们先配置一个SSO的,将BIRT运行时单独作为一个应用,部署在tomcat中,使用cas作为登陆检查。过程其实很简单,需要在web.xml中添加一下cas的配置
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CASFilter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>http://192.168.0.2:8443/sso/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://192.168.0.12:8080</param-value> <!--这里容易错,试试加app name和不要的差别-->
</init-param>
</filter>
<filter-mapping>
<filter-name>CASFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>
org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>http://192.168.0.2:8443/sso</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://192.168.0.14:8080</param-value> <!---同上-->
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>
org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
当然要把相关的jar包(我用的是cas-client-core-3.2.1.jar)copy到应用里面。 关于CAS的配置这些配置项需要注意,不然有很多坑。
CAS其实也没有那么难,可是了解下原理,做个验证(http://blog.youkuaiyun.com/small_love/article/details/6664831)。
keytool -genkey -alias smalllove -keyalg RSA -keystore G:/temp/smallkey
keytool -export -file G:/temp/small.crt -alias smalllove -keystore G:/temp/smallkey
keytool -import -keystore D:\Tools\Java\jdk7\jre\lib\security\cacerts -file G:/temp/small.crt -alias smalllove
修改tomcat 配置,还是可以搞定的。
还有一种方式就是网上说的比较多的,修改org.eclipse.birt.report.servlet.BirtEngineServlet.java (编译之后放到viewservlets.jar)
protected boolean __authenticate(HttpServletRequest request, HttpServletResponse response) {
if (request.getSession().getAttribute("userinfo") == null) {
return false;
}
return true;
}
如果作为独立的应用没有登陆是拿不到session的,因为登陆在其他的应用里面,所以我试了多应用共享session, 修改tomcat server.xml crossContext="true"
session是取到了,但是页面显示总是不正确,所以放弃了这条路
3. 工具条和分页显示在一行
BIRT上面的工具条和分页操作目前是在两行显示的,看起来有点不爽,占位太多,能不能在一行里面显示呢?显然是可以的,有jsp给我们当然可以修改,不过还是要注意些东西的,BIRT的工具条设计不是很好,导致开始修改的时候遇到些困难。下面说说我的方法:
在BIRT的web目录找到webcontent\birt\pages\control
修改ToolbarFragment.jsp 将<TR>...</TR>的内容全部去掉
修改NavigationbarFragment.jsp文件,主要是将DIV改成SPAN,改成下面这个样子:
<TR
<%
String imagesPath = "birt/images/";
if( attributeBean.isShowNavigationbar( ) )
{
%>
HEIGHT="25px"
<%
}
else
{
%>
style="display:none"
<%
}
%>
>
<TD><span ID="toolbar" style="width:70%;float:left;display:inline-block;<% if(! attributeBean.isShowToolbar( ) ) out.println("display:none;"); %>">
<TABLE CELLSPACING="1px" CELLPADDING="1px" WIDTH="100%" CLASS="birtviewer_toolbar" style="border:0;">
<TR><TD></TD></TR>
<TR>
<TD WIDTH="6px"/>
<TD WIDTH="15px">
<INPUT TYPE="image" NAME='toc' SRC="birt/images/Toc.gif"
TITLE="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.toc" )%>"
ALT="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.toc" )%>" CLASS="birtviewer_clickable">
</TD>
<TD WIDTH="6px"/>
<TD WIDTH="15px">
<INPUT TYPE="image" NAME='parameter' SRC="birt/images/Report_parameters.gif"
TITLE="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.parameter" )%>"
ALT="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.parameter" )%>" CLASS="birtviewer_clickable">
</TD>
<TD WIDTH="6px"/>
<TD WIDTH="15px">
<INPUT TYPE="image" NAME='export' SRC="birt/images/Export.gif"
TITLE="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.export" )%>"
ALT="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.export" )%>" CLASS="birtviewer_clickable">
</TD>
<TD WIDTH="6px"/>
<TD WIDTH="15px">
<INPUT TYPE="image" NAME='exportReport' SRC="birt/images/ExportReport.gif"
TITLE="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.exportreport" )%>"
ALT="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.exportreport" )%>" CLASS="birtviewer_clickable">
</TD>
<TD WIDTH="6px"/>
<TD WIDTH="15px">
<INPUT TYPE="image" NAME='print' SRC="birt/images/Print.gif"
TITLE="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.print" )%>"
ALT="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.print" )%>" CLASS="birtviewer_clickable">
</TD>
<%
if( ParameterAccessor.isSupportedPrintOnServer )
{
%>
<TD WIDTH="6px"/>
<TD WIDTH="15px">
<INPUT TYPE="image" NAME='printServer' SRC="birt/images/PrintServer.gif"
TITLE="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.printserver" )%>"
ALT="<%= BirtResources.getHtmlMessage( "birt.viewer.toolbar.printserver" )%>" CLASS="birtviewer_clickable">
</TD>
<%
}
%>
<TD ALIGN='right'>
</TD>
<TD WIDTH="6px"/>
</TR>
</TABLE>
</span>
<span id="navigationBar" style="display:inline-block;float:right;">
<TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%" HEIGHT="25px" CLASS="birtviewer_navbar">
<TR><TD></TD></TR>
<TR>
<TD WIDTH="6px"> </TD>
<TD WIDTH="100%" NOWRAP>
<B>
<%
if ( attributeBean.getBookmark( ) != null )
{
%>
<%=
BirtResources.getMessage( "birt.viewer.navbar.prompt.one" )
%>
<SPAN ID='pageNumber'></SPAN>
<%= BirtResources.getMessage( "birt.viewer.navbar.prompt.two" )%>
<SPAN ID='totalPage'></SPAN>
<%
}
else
{
%>
<%= BirtResources.getMessage( "birt.viewer.navbar.prompt.one" )%>
<SPAN ID='pageNumber'><%= ""+attributeBean.getReportPage( ) %></SPAN>
<%= BirtResources.getMessage( "birt.viewer.navbar.prompt.two" )%>
<SPAN ID='totalPage'></SPAN>
<%
}
%>
</B>
</TD>
<TD WIDTH="15px">
<INPUT TYPE="image" SRC="<%= imagesPath + (attributeBean.isRtl()?"LastPage":"FirstPage") + "_disabled.gif" %>" NAME='first'
ALT="<%= BirtResources.getHtmlMessage( "birt.viewer.navbar.first" )%>"
TITLE="<%= BirtResources.getHtmlMessage( "birt.viewer.navbar.first" )%>" CLASS="birtviewer_clickable">
</TD>
<TD WIDTH="2px"> </TD>
<TD WIDTH="15px">
<INPUT TYPE="image" SRC="<%= imagesPath + (attributeBean.isRtl()?"NextPage":"PreviousPage") + "_disabled.gif" %>" NAME='previous'
ALT="<%= BirtResources.getHtmlMessage( "birt.viewer.navbar.previous" )%>"
TITLE="<%= BirtResources.getHtmlMessage( "birt.viewer.navbar.previous" )%>" CLASS="birtviewer_clickable">
</TD>
<TD WIDTH="2px"> </TD>
<TD WIDTH="15px">
<INPUT TYPE="image" SRC="<%= imagesPath + (attributeBean.isRtl()?"PreviousPage":"NextPage") + "_disabled.gif" %>" NAME='next'
ALT="<%= BirtResources.getHtmlMessage( "birt.viewer.navbar.next" )%>"
TITLE="<%= BirtResources.getHtmlMessage( "birt.viewer.navbar.next" )%>" CLASS="birtviewer_clickable">
</TD>
<TD WIDTH="2px"> </TD>
<TD WIDTH="15px">
<INPUT TYPE="image" SRC="<%= imagesPath + (attributeBean.isRtl()?"FirstPage":"LastPage") + "_disabled.gif" %>" NAME='last'
ALT="<%= BirtResources.getHtmlMessage( "birt.viewer.navbar.last" )%>"
TITLE="<%= BirtResources.getHtmlMessage( "birt.viewer.navbar.last" )%>" CLASS="birtviewer_clickable">
</TD>
<TD WIDTH="8px"> </TD>
<TD ALIGN="right" NOWRAP><LABEL for="gotoPage"><b><%= BirtResources.getMessage( "birt.viewer.navbar.lable.goto" )%></b></LABEL></TD>
<TD WIDTH="2px"> </TD>
<TD ALIGN="right" WIDTH="50px">
<INPUT ID='gotoPage' TYPE='text' VALUE='' MAXLENGTH="8" SIZE='5' CLASS="birtviewer_navbar_input">
</TD>
<TD WIDTH="4px"> </TD>
<TD ALIGN="right" WIDTH="10px">
<INPUT TYPE="image" SRC="<%= imagesPath + (attributeBean.isRtl()?"Go_rtl.gif":"Go.gif") %>" NAME='goto'
ALT="<%= BirtResources.getHtmlMessage( "birt.viewer.navbar.goto" )%>"
TITLE="<%= BirtResources.getHtmlMessage( "birt.viewer.navbar.goto" )%>" CLASS="birtviewer_clickable">
</TD>
<TD WIDTH="6px"> </TD>
</TR>
</TABLE>
</span>
</TD>
</TR>
效果像这个样子:
哈哈,不好看?你还可以再改改。