BIRT是一个Eclipse-based开放源代码报表系统。它主要是用在基于Java与J2EE的Web应用程序上。BIRT主要由两部分组成:一个是基于Eclipse的报表设计和一个可以加到你应用服务的运行期组件。BIRT同时也提供一个图形报表制作引擎。
Birt Home : http://www.eclipse.org/birt/phoenix/
Birt环境及下载:[url]http://download.eclipse.org/birt/downloads [/url]
Birt教程:http://www.eclipse.org/birt/phoenix/tutorial/
eclipse技术论坛:[url]http://www.eclipseworld.org/bbs/ [/url]
Birt例子演示:[url]http://www.eclipse.org/birt/phoenix/examples/ [/url]
[url]http://download3.eclipse.org/birt/downloads/examples/misc/BIRT/BIRT_demo_Camv3.html [/url]
[url]http://download3.eclipse.org/birt/downloads/demos/MyFirstReport.html [/url]
Birt使用小结
Ide: birt-report-designer-all-in-one-2.1.2 (建议初学者下载,下载后是一个ECLIPSE,BIRT已经装好了,方便)
Runtime:birt-runtime-2.1.2
Jdk: jdk1.5.0_02
和现有项目有两种结合方式。
其一:直接使用birt_runtime_2.1.2中的WebViewerExample。
1. 将其发布到C:\jakarta-tomcat-5.0.28\webapps目录下,并将其更改名称为birtApp。
2. 在birtApp \WEB-INF\platform\plugins\com.lowagie.itext目录下新建文件夹lib,并将itext-1.3.jar和iTextAsian.jar拷入其中。
3. 将已完成的报表,比如test.rptdesign放到birtApp的根目录下,即可通过
http://localhost:8080/birt/frameset?__report=test.rptdesign(相对路径)
或者
http://localhost:8080/birt/frameset?__report=C:/jakarta-tomcat-5.0.28/webapps/birt/test.rptdesign(绝对路径)
来访问。
若报表设置以后参数,则只需在上述url后拼接参数及值即可。
Eg: http://localhost:8080/birt/frameset?__report=test.rptdesign&sample=my+parameter
其二:在我们的程序中使用birt提供的Report Engine Api来调用报表并展现报表。
1. 新建web项目webrpt。
2. 在webrpt的web模块下的WEB-INF目录中新建文件夹lib,并将birt-runtime-2_1_2\ReportEngine\lib下的所有文件拷入其中。
3. 如上,同样在WEB-INF目录中新建文件夹platform,并将birt-runtime-2_1_2\ReportEngine下的plugins和configuration拷入其中。
4. 将itext-1.3.jar和iTextAsian.jar拷入platform\plugins\com.lowagie.itext文件夹的lib目录中(此处如果没有该目录,新建之),亦或者将所述jar包拷入WEB-INF\lib目录下也可。
5. 在webrpt的web模块的根目录下新建images和reports文件夹。其中reports文件夹中放
已开发完成的报表文件。
6. 当然所使用的数据库驱动也要放在lib文件夹下。
7. 使用report engine api开发调用及展示报表的相关程序。代码如下:
WebReport.java
package com.lisa; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.birt.report.engine.api.EngineConstants; import org.eclipse.birt.report.engine.api.HTMLRenderContext; import org.eclipse.birt.report.engine.api.HTMLRenderOption; import org.eclipse.birt.report.engine.api.IReportRunnable; import org.eclipse.birt.report.engine.api.IRunAndRenderTask; import org.eclipse.birt.report.engine.api.IReportEngine; public class WebReport extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; /** * Constructor of the object. */ private IReportEngine birtReportEngine = null; protected static Logger logger = Logger.getLogger( "org.eclipse.birt" ); public WebReport() { super(); } /** * Destruction of the servlet. */ public void destroy() { super.destroy(); BirtEngine.destroyBirtEngine(); } /** * The doGet method of the servlet. * */ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet................"); //get report name and launch the engine //resp.setContentType("text/html"); resp.setContentType( "application/pdf" ); resp.setHeader ("Content-Disposition","inline; filename=test.pdf"); String reportName = req.getParameter("ReportName"); System.out.println("reportName:::"+reportName); ServletContext sc = req.getSession().getServletContext(); this.birtReportEngine = BirtEngine.getBirtEngine(sc); //setup image directory HTMLRenderContext renderContext = new HTMLRenderContext(); renderContext.setBaseImageURL(req.getContextPath()+"/images"); renderContext.setImageDirectory(sc.getRealPath("/images")); logger.log( Level.FINE, "image directory " + sc.getRealPath("/images")); System.out.println("stdout image directory " + sc.getRealPath("/images")); HashMap contextMap = new HashMap(); contextMap.put( EngineConstants.APPCONTEXT_HTML_RENDER_CONTEXT, renderContext ); IReportRunnable design; try { //Open report design design = birtReportEngine.openReportDesign( sc.getRealPath("/Reports")+"/"+reportName ); //create task to run and render report IRunAndRenderTask task = birtReportEngine.createRunAndRenderTask( design ); task.setAppContext( contextMap ); HashMap paramMap=new HashMap(); paramMap.put("param","%"); paramMap.put("sample", "lisa ok"); task.setParameterValues(paramMap); //set output options HTMLRenderOption options = new HTMLRenderOption(); //options.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_HTML); options.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_PDF); options.setOutputStream(resp.getOutputStream()); task.setRenderOption(options); //run report task.run(); task.close(); }catch (Exception e){ e.printStackTrace(); throw new ServletException( e ); } } /** * The doPost method of the servlet. * */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.println(" Post does nothing"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } /** * Initialization of the servlet. * * @throws ServletException if an error occure */ public void init() throws ServletException { System.out.println("init..................."); BirtEngine.initBirtConfig(); } }
BirtEngine.java
package com.lisa; import java.io.InputStream; import java.io.IOException; import java.util.Properties; import java.util.logging.Level; import org.eclipse.birt.report.engine.api.EngineConfig; import org.eclipse.birt.report.engine.api.IReportEngine; import javax.servlet.*; import org.eclipse.birt.core.framework.PlatformServletContext; import org.eclipse.birt.core.framework.IPlatformContext; import org.eclipse.birt.core.framework.Platform; import org.eclipse.birt.core.exception.BirtException; import org.eclipse.birt.report.engine.api.IReportEngineFactory; public class BirtEngine { private static IReportEngine birtEngine = null; private static Properties configProps = new Properties(); private final static String configFile = "com/lisa/BirtConfig.properties"; public static synchronized void initBirtConfig() { loadEngineProps(); } public static synchronized IReportEngine getBirtEngine(ServletContext sc) { if (birtEngine == null) { EngineConfig config = new EngineConfig(); if( configProps != null){ String logLevel = configProps.getProperty("logLevel"); Level level = Level.OFF; if ("SEVERE".equalsIgnoreCase(logLevel)) { level = Level.SEVERE; } else if ("WARNING".equalsIgnoreCase(logLevel)) { level = Level.WARNING; } else if ("INFO".equalsIgnoreCase(logLevel)) { level = Level.INFO; } else if ("CONFIG".equalsIgnoreCase(logLevel)) { level = Level.CONFIG; } else if ("FINE".equalsIgnoreCase(logLevel)) { level = Level.FINE; } else if ("FINER".equalsIgnoreCase(logLevel)) { level = Level.FINER; } else if ("FINEST".equalsIgnoreCase(logLevel)) { level = Level.FINEST; } else if ("OFF".equalsIgnoreCase(logLevel)) { level = Level.OFF; } config.setLogConfig(configProps.getProperty("logDirectory"), level); } config.setEngineHome(""); IPlatformContext context = new PlatformServletContext( sc ); config.setPlatformContext( context ); try { Platform.startup( config ); } catch ( BirtException e ) { e.printStackTrace( ); } IReportEngineFactory factory = (IReportEngineFactory) Platform .createFactoryObject( IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY ); birtEngine = factory.createReportEngine( config ); } return birtEngine; } public static synchronized void destroyBirtEngine() { if (birtEngine == null) { return; } birtEngine.shutdown(); Platform.shutdown(); birtEngine = null; } public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } private static void loadEngineProps() { System.out.println("loadEngineProps....................."); try { //Config File must be in classpath ClassLoader cl = Thread.currentThread ().getContextClassLoader(); InputStream in = null; in = cl.getResourceAsStream (configFile); configProps.load(in); in.close(); } catch (IOException e) { e.printStackTrace(); } } }
BirtConfig.properties logDirectory=c:/temp logLevel=FINEST
8. 通过web页面输入要访问的报表名称,并提交到处理请求的相关servlet.
Test.jsp
<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%> <html> <head> </head> <body> <form name="myform" action="./webReport" method="get"> <table> <tr> <td>报表名称(带后缀名)</td> <td><input name="ReportName" type="text"></td> <td><button type="submit">查看</button></td> </tr> </table> </form> </body> </html>
9. 修改web.xml文件如下
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>WebReport</servlet-name> <servlet-class>com.lisa.WebReport</servlet-class> </servlet> <servlet-mapping> <servlet-name>WebReport</servlet-name> <url-pattern>/webReport</url-pattern> </servlet-mapping> </web-app>
参看Servlet Example.
另:一些在论坛里学到得很实用的小技巧,谢谢提供的作者们:)
分页(vii779):
2.1以后,只能按照分组分页,想要按每页固定记录数来分页比较困难。
论坛中已经介绍过通过分组的方式,加一个分页字段来实现分页功能。
但该方式操作起来稍显繁琐 。
通过Script方式,可以实现更简单的分页方式。
首先加一个表格,选中表格中的明细行,切换到Script标签页。
在onRender事件中加入以下代码
rowNum = Number(this.getRowData().getExpressionValue('row["0"]'))+1; if(rowNum % 20 ==0){ this.getStyle().pageBreakAfter="always"; }else{ this.getStyle().pageBreakAfter=null; }
这样就实现了按每页20条记录的分页功能。
需要注意的是,在run方式下,看不到分页效果,打印预览时才能看到分页。
在framest(ctrl+shift+B)方式下,可以看到完整的分页效果。
纸张(paddycq):
主页--->常规 中设置方向、类型
Pdf中文乱码(mmwy):
放了itext-1.3.jar、iTextAsian.jar两个jar包在\plugins\com.lowagie.itext\lib目录下,一切ok,从来没有出现过中文问题。就连部署到linux下也是如此。
URL乱码问题.mht
两种解决方法:
一. java.net.URLDecoder.decode(java.net.URLEncoder.encode("中文"));
二.如果使用tomcat做web应用服务器,则修改server.xml文件,在connector元素中增加属性uriencoding.
Eg:
<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="gb2312"/>
前提:
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.