Java开源报表JasperReport、iReport4.5.1使用详解(二)

上一节,我们介绍了JasperReport、iReport4.5.1这两款开源软件,本节来个例子,实战下。

一.数据源设计

101723132.jpg

图1-1

打开上图中红色部分所示:进行当前报表的数据源的设计,我们本节写的是Sql语句

102016769.jpg

图1-2

选择OK 之后,此语句涉及的字段都会显示在Fields下面:


102254213.jpg

图1-3

二.报表的结构介绍


103046344.jpg

图1-4

报表的结构包括如下部分:Title、Page Header、Column Header、Detail、Column Footer、Page Footer、Summary.下面一一的介绍各个部分。

Title:为报表的标题部分,如果报表有多页,则只显示在第一页。

Page Header :为报表每页的一个头部名称,如果报表有多页,则每页都会显示。

Column Header:可以理解成表头,如果报表有多页,则每页都会显示。

Detail:详细记录,迭代列出所有的查询结果,有多少数据都会显示出来(分页)。

Column Footer:相当于表尾,如果报表有多页,则每页都会显示。

Page Footer:与Page Header对应,每页都会显示。

Summary:报表的一些统计信息。比如共有多少页,当前是第几页等信息。

三、接下来,我们试着制作一份报表出来。

改报表的要求是:列出所有用户的信息,(查询语句决定。)

我们从组件面板中,拖出一个 Static Text 组件来,放置在报表的Title部分,输入“用户账户清单”。


在Page Header 也同样拖入一个 Static Text 组件,输入“管理员”

展开左侧的 Report Inspector,展开Fields子项,将图1-3所示的字段,拖入Detail项中,此时会发现,Column Header项中自动填充了Static Text的表头,也可以对表头进行编辑,重命名等操作。可以调整各组件的位置、大小等信息。

如图所示:


105555413.jpg

图3-1

预览,选择Preview (图3-1红色框部分)即可。

结果如下图所示:


105912918.jpg

图4-1

生成的文档信息如下:

 
  
  1.  Compiling to file... G:\Jaspersoft\iReport-4.1.1\ireport\fonts\report1.jasper  

  2. Compilation running time: 297!  

  3.  Filling report...  

  4.  Locale: 中文 (中国)  

  5.  Time zone: Default  

  6. Report fill running time: 203! (pages generated: 2)  

  7.  Exporting PDF (using iText) to file... G:\Jaspersoft\iReport-4.1.1\ireport\fonts\report1.pdf!  

  8. Export running time: 94!  

  9. Executing: "E:\Adobe\Reader 10.0\Reader\AcroRd32.exe" "G:\Jaspersoft\iReport-4.1.1\ireport\fonts\report1.pdf"

与此同时,会自动弹出一个report1.pdf的文档,注意,这里可能有些同学会出现中文显示不了的情况,这里需强调一下的是,要想显示中文,需要需要进行一些配置

在iReport的classpath里面导入包含了中文的字符的jar文件,还有供Pdf使用的字符jar包。

工具-->选项-->font

如果没有,则需加入到classpath中

110812115.jpg

图4-1-1

也可以添加自己所需要的字体。

iTextAsian.jar的最新的jar包可以到下面的地址下载。

http://sourceforge.net/projects/itext/files/extrajars/

包含在 extrajars-2.2.zip 中

111111352.jpg

图4-1-2

文本框默认的是:SansSerif字体,需要改成我们中文的字体


111238757.jpg

图4-1-3

关于字体的安装,后面的部分会介绍到。

本节我们将介绍,导出成Html、Excel、Pdf、以及从Scriptlet获取数据。

一、导出成Html方式

①首先建立一个 web project


155252643.png

图1.1.1

②导入相应的jar包到工程里面

jasperreports-4.5.1\dist 下面所有jar包,共4个

jasperreports-4.5.1.jar

jasperreports-applet-4.5.1.jar

jasperreports-fonts-4.5.1.jar

jasperreports-javaflow-4.5.1.jar

然后是jasperreports-4.5.1-project\jasperreports-4.5.1\lib 下面 com开头的所有jar包

commons-beanutils-1.8.0.jar

commons-collections-2.1.1.jar

commons-digester-2.1.jar

commons-javaflow-20060411.jar

commons-logging-1.1.1.jar

③将我们第二节中生成的jasper 文件复制进我们的web目录下面

ireport\fonts\report1.jasper

④编写jsp测试页面:


 
  
  1. <%@ page contentType="text/html;charset=utf-8"%>

  2. <%@ page import="net.sf.jasperreports.engine.*"%>

  3. <%@ page import="java.util.*"%>

  4. <%@ page import="java.io.*" %>

  5. <%@ page import="java.sql.*" %>

  6. <%  

  7. String ctxpath = request.getContextPath();  

  8. Class.forName("net.sourceforge.jtds.jdbc.Driver");  

  9. String url="jdbc:jtds:sqlserver://server:1433/pcbsyn";  

  10. String user="sa";  

  11. String password="711";  

  12. Connection conn= DriverManager.getConnection(url,user,password);  

  13. //ireport生成的.jasper文件的存放位置,这里为了方便放置在根目录下面  

  14. File reportFile = new

  15. File(this.getServletContext().getRealPath("/report1.jasper"));  

  16. Map parameters = new HashMap();  

  17. try {  

  18. //执行报表程序  

  19. JasperRunManager.runReportToHtmlFile(reportFile.getPath(),parameters, conn);  

  20. response.sendRedirect(ctxpath+"/report1.html");

  21. }  

  22. catch (Exception e) {  

  23. System.out.println( e.getMessage() );  

  24. }  

  25. finally {  

  26. try {  

  27. conn.close();  

  28. }  

  29. catch (Exception ex) {  

  30. System.out.println( ex.getMessage() );  

  31. }  

  32. }  

  33. %>

图1.4.1

页面报错:

java.lang.NoClassDefFoundError: org/codehaus/groovy/control/CompilationFailedException

解决办法:导入lib下面的groovy-all-1.7.5.jar 包即可解决问题。

这个是html的页面。


160045353.png

二、导出成Pdf方式。

①建立generatePdf.jsp文件


 
  
  1. <%@ page contentType="text/html;charset=utf-8"%>

  2. <%@ page import="net.sf.jasperreports.engine.*"%>

  3. <%@ page import="java.util.*"%>

  4. <%@ page import="java.io.*" %>

  5. <%@ page import="java.sql.*" %>

  6. <%  

  7. //报表编译之后生成的.jasper文件的存放位置  

  8. File reportFile = new

  9. File(this.getServletContext().getRealPath("report1.jasper"));  

  10. String url="jdbc:jtds:sqlserver://server:1433/pcbsyn";  

  11. Class.forName("net.sourceforge.jtds.jdbc.Driver");  

  12. Map parameters = new HashMap();  

  13. Connection conn = DriverManager.getConnection(url, "sa",  

  14. "711");  

  15. byte[]  

  16. bytes=JasperRunManager.runReportToPdf(reportFile.getPath(),parameters  

  17. ,conn);  

  18. response.setContentType("application/pdf");  

  19. response.setContentLength(bytes.length);  

  20. ServletOutputStream outStream = response.getOutputStream();  

  21. outStream.write(bytes,0,bytes.length);  

  22. outStream.flush();  

  23. outStream.close();  

  24. out.clear();  

  25. out = pageContext.pushBody();  

  26. %>


运行

http://localhost:8080/IreportTest/generatePdf.jsp

之后报错:

 
  
  1. org.apache.jasper.JasperException: net.sf.jasperreports.engine.JRRuntimeException: Could not load the following font :  

  2. pdfFontName   : Helvetica  

  3. pdfEncoding   : UniGB-UCS2-H  

  4. isPdfEmbedded : true  

  5.    org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:491)  

  6.    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:419)  

  7.    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)  

  8.    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)  

  9.    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)  


出现这个错误主要是因为:没有导入iTextAsian.jar、iTextAsianCmaps.jar

解决办法:

1.导入iTextAsian.jar、iTextAsianCmaps.jar 包

2.设置字体属性如下图所示:

111739411.jpg

图2.1

注意:如果使用的是自定义的字体,也就是自己安装的字体,则需要导入相应字体的jar包 本人使用的是simfang.jar。



160210469.png

图2.2

三、导出成Excel格式:

测试代码如下:

 
  
  1. import java.io.File;  

  2. import java.io.FileOutputStream;  

  3. import java.sql.Connection;  

  4. import java.sql.DriverManager;  

  5. import java.util.HashMap;  

  6. import java.util.Map;  

  7. import net.sf.jasperreports.engine.JRAbstractExporter;  

  8. import net.sf.jasperreports.engine.JRExporterParameter;  

  9. import net.sf.jasperreports.engine.JasperFillManager;  

  10. import net.sf.jasperreports.engine.JasperPrint;  

  11. import net.sf.jasperreports.engine.export.JExcelApiExporter;  

  12. publicclass TestExcel {  

  13. publicstaticvoid main(String[] args) {  

  14.        File reportFile = new File(  

  15. "WebRoot\\report1.jasper");  

  16.        Map parameters = new HashMap();  

  17.        Connection conn = null;  

  18.        FileOutputStream output = null;  

  19. try {  

  20.            String driver = "net.sourceforge.jtds.jdbc.Driver";  

  21.            String url = "jdbc:jtds:sqlserver://server:1433/pcbsyn";  

  22.            Class.forName(driver);  

  23.            conn = DriverManager.getConnection(url, "sa", "711");  

  24.            Map parameter = new HashMap();  

  25.            JasperPrint report = null;  

  26.            report = JasperFillManager.fillReport(reportFile.getPath(),  

  27.                    parameter, conn);  

  28.            JRAbstractExporter exporter = new JExcelApiExporter();  

  29.            output = new FileOutputStream("D:\\excel.xls");  

  30.            exporter.setParameter(JRExporterParameter.JASPER_PRINT, report);  

  31.            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, output);  

  32.            exporter.exportReport();  

  33.        } catch (Exception e) {  

  34.            e.printStackTrace();  

  35.        } finally {  

  36. try {  

  37.                output.close();  

  38.            } catch (Exception e) {  

  39.                e.printStackTrace();  

  40.            }  

  41. try {  

  42.                conn.close();  

  43.            } catch (Exception e) {  

  44.                e.printStackTrace();  

  45.            }  

  46.        }  

  47.    }  

  48. }


运行的时候报错:


 
  
  1. java.lang.NullPointerException  

  2.    at com.yaxing.excel.TestExcel.main(TestExcel.java:41)  

  3. Exception in thread "main" java.lang.NoClassDefFoundError: jxl/write/biff/RowsExceededException  

  4.    at com.yaxing.excel.TestExcel.main(TestExcel.java:32)  

  5. Caused by: java.lang.ClassNotFoundException: jxl.write.biff.RowsExceededException  

  6.    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)  

  7.    at java.security.AccessController.doPrivileged(Native Method)  

  8.    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)  

  9.    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)  

  10.    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)  

  11.    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)  

  12.    ... 1 more  

这是因为没有导入所需要的jxl.jar包,这个包是用来处理Excel文件的。

同样可以在lib目录下面查找。再运行一次,可以发现,已经生成了我们所需要的excel文件。

最后生成的excel文件如图:


160408728.png

图3.1

四、使用使用Scriptlet来填充报表。

①编写Scriptlet类,需要继承自JRDefaultScriptlet(net.sf.jasperreports.engine.JRDefaultScriptlet),

 
  
  1. import java.util.Date;  

  2. import net.sf.jasperreports.engine.JRDefaultScriptlet;  

  3. import net.sf.jasperreports.engine.JRScriptletException;  

  4. publicclass ScriptLetDemo extends JRDefaultScriptlet{  

  5. long pageinitTime = 0;  

  6. public String getResult(){  

  7. return"Hello,Scriptlet";  

  8.    }  

  9. @Override

  10. publicvoid beforePageInit() throws JRScriptletException {  

  11. // TODO Auto-generated method stub

  12.        pageinitTime = new Date().getTime();  

  13.    }  

  14. }

我们要制作的报表是,报表有个Text Field的值,是这个ScriptletDemo 里面返回的值。

②将此ScriptLetDemo 导出成jar文件

myeclipse的导出方式很简单,选择这个ScriptLetDemo.java

File-->Export-->Java-->Java\Jar file 选择保存路径即可。

为什么要导出成jar文件呢,因为我们的iReport需要这个jar文件。

③从iReport的组件面板中拖拉一个Text Field放入Detail中,

这个Text Filed 是表达式是:

((com.yaxing.excel.ScriptLetDemo)$P{REPORT_SCRIPTLET}).getResult()

前面括弧里面是ScriptletDemo 的路径,后面的REPORT 是默认的Scriptname,

如果我们的报表中有多个Script,则名字的规则是

<scriptlet name>_SCRIPTLET (.for example, scritplet1_SCRIPTLET)

预览下,即可:如图所示:Static Text 下面的值,即是我们程序中的值!


154847937.png

图4.1

文中有些代码不理解没关系,后文会有详细的介绍,只是先,我们熟悉下这个报表的使用方式、开发流程。

整个项目使用的jar如图:



160744281.png