在企业应用系统中,经常要输出各种格式的数据报表。

著名的开源项目<JasperReports可以很好的解决这个问题。

使用JasperReports可以在预先设定好格式的报表基础上进行数据的填充并可导出各种格式的报表。

下图说明了JasperReports报表生成的基本步骤:

1. 扩展名为.jrxml的文件为标准的xml文件,该文件定义了报表的格式和数据构成。可以通过jasperReports的“黄金搭档”iReport以可视化的方式生成并编辑这个文件。

2. jrxml文件经过JasperReports API 编译后将生成扩展名为.jasper的二进制文件。

3. 可以调用JasperReports API针对jasper文件进行数据和参数的填充,生成扩展名为.jrprint的文件。

4. 调用JasperReports API可以将jrprint文件最终导出成PDF、Excel、Html等各种格式的文件。

下面将采用iReport + JasperReports 生成如下图的PDF格式报表,表格中的数据来源于数据库,是在固定格式报表基础上,由JasperReport填充得到的。

整个报表的生成过程需要两个步骤:

1. 使用iReport生成规定报表格式和数据构成的jrxml文件。

2. 调用JasperReports API 编译、填充并导出固定格式的报表。

一、用iReport生成报表文件(.jrxml)

开源工具iReport用于定义报表的格式,可以从其官方网站下载

http://ireport.sourceforge.net/cap3.html

本应用所使用的是iReport-1.2.2-windows-installer.exe 安装程序,启动后,按照向导即可安装(要确认系统中装有1.4版本以上JDK)。

下面的操作大致分为12个步骤:

步骤1:安装成功后启动该程序,将显示如下画面,选择菜单“File->New Document”新建报表文档,可在弹出的对话框选择报表的大小、版式等。

步骤2:按照默认版式创建报表,选择菜单“Data->Connections/Datasources”

指定数据库连接或数据源,在弹出的对话框中单击“New”,并在弹出的对话框中指定数据库的连接参数(驱动类、URL、用户名和密码等)

iReport通过JDBC连接数据库,要确认相应数据库的驱动类置于iReport安装路径的lib文件夹下。

步骤3:选择菜单“Data->Report Query”

在弹出的对话框中输入SQL语句:

select id, name, salary from emp,

选中所有查询的字段后,单击“OK”。

该SQL语句查询的数据为将来报表中要显示的数据,除了用SQL语句,这里还支持HQL(Hibernate Query Language)等其他多种查询方式。

这样的操作将在报表的xml文件中生成如下定义:

<queryString><![CDATA[select id, name, salary from emp]]></queryString>

<field name="id" class="java.lang.Integer"/>

<field name="name" class="java.lang.String"/>

<field name="salary" class="java.lang.Double"/>

其中元素定义了用于获取数据的查询语句,将来JasperReports将通过这样的方式查询数据。

元素定义了对应于查询结果的字段名称和类型,将来报表中可以使用$F{字段名称}获取并显示查询得到的数据。

步骤4:选择菜单“Format->Styles”用于指定报表元素将使用的样式,

这里的Style类似于HTML中CSS样式,一个样式规定了字体、前景色、背景色等显示特征,样式创建后,可以将其施加于特定的报表元素。

为了便于维护,样式之间可以实现继承关系,子样式将拥有父样式的一切特征。

在弹出的对话框中单击“New”指定一个名为default的样式(通过Style name指定样式名称),指定其字体、颜色等特征。

步骤5:继续指定一些其他的样式,如用于表头字体的“灰底白字”的样式header,将这些样式的Parent style值指定为刚刚创建的default样式,

即指定default是所有样式的父样式,这样可以通过编辑default样式指定一些所有样式共同的特征。

步骤5:继续指定一些其他的样式,如用于表头字体的“灰底白字”的样式header,将这些样式的Parent style值指定为刚刚创建的default样式,

即指定default是所有样式的父样式,这样可以通过编辑default样式指定一些所有样式共同的特征。

步骤6:单击“Edit->Insert element...->Static Text”或使用工具栏的按钮,

在报表页面中添加静态文本框,将这些文本框置于合适的位置并填入文字,作为表头,

通过右边的Element properties 视图将这些文本框的Style(样式)置为方才创建的header。

步骤7:打开右边Library视图的Fields图标,可以看到id,name,salary三个标识,这三个标识对应在“步骤3”中创建的“查询字段”,

用鼠标直接拖动这些字段到报表页面的适当位置,这样的操作将在报表xml文本中产生形如:

<textFieldExpression class="java.lang.Integer"><![CDATA[$F{字段名称}]]></textFieldExpression>

的文本。其中$F{字段名称}表示该字段的查询值。

步骤8:在Library视图中单击右键,在弹出的快捷菜单中选择“Add...->Parameter”,用于创建参数,在弹出的对话框中指定参数的名称和数据类型。

步骤9:在Library视图的Parameter下可以看到刚刚建立的名为“Title”的参数,用鼠标拖到其到指定位置,并适用在步骤5中创建的title样式,此处为报表的标题。

这样的操作将在xml文件中产生如下内容:

<textFieldExpression class="java.lang.String"><![CDATA[$P{Title}]]></textFieldExpression>

其中的$P{Title}对应Title参数的值,将来将通过JasperReports API 对“Title”参数赋值。

步骤10:选择菜单“File->Save”保存生成的xml文件,注意,文件的扩展名一般为jrxml,该文件定义的报表的格式及其数据构成。

步骤11:可以通过iReport的编译工具对生成的报表文件进行测试,

单击工具栏的按钮编译报表文件,

如果无误可单击工具栏的按钮将显示报表生成的样式,

如果单击工具栏的按钮,iReport将会查询数据显示填充数据后的报表,

注意:这里的报表的标题显示null是因为没有对报表的“Title”赋值,这里仅仅是通过iReport工具对生成的报表进行测试,

下面将通过JasperReports API以编程的方式编译、填充并导出报表。

步骤12:为了是将来导出的PDF格式报表支持中文显示,可以手工的编辑iReport生成的xml文件,

在定义default样式的位置加入支持中文的PDF字体和编码设置:

<style   name="default"   isDefault="true"   mode="Opaque"   pdfFontName="STSong-Light"   pdfEncoding="UniGB-UCS2-H"  />

由于其他样式继承了该样式,从而自动拥有的支持中文的设置。

二、用JasperReports编译、填充,并导出报表 可以从JasperReports的官方网站下

http://www.jasperforge.org/jaspersoft/opensource/business_intelligence/jasperreports/

载JasperReports的发行包,本应用使用的版本是jasperreports-1.2.3,将其发行包中dist目录下的:

jasperreports-1.2.3.jar

以及lib目录下的如下jar文件:

poi-2.0-final-20040126.jar

jdt-compiler-3.1.1.jar

itext-1.3.1.jar

commons-beanutils-1.5.jar

commons-collections-2.1.jar

commons-digester-1.7.jar

commons-javaflow-20060411.jar

commons-loggin-1.0.2.jar

复制到应用的类路径(CLASSPATH)下。

为了支持中文的PDF报表导出,还需要有iTextAsian.jar文件,

该文件可以从http://prdownloads.sourceforge.net/itext/iTextAsian.jar?download 处下载。

注意,由于要连接数据库,还需要将数据库的JDBC驱动类包复制到类路径下。

编译报表(.jrxml -> .jasper),JasperCompileManager类的静态方法compileReportToFile用于编译报表文件第一个String参数为待编译的报表xml文件,

第二个String参数为编译后的文件名。

代码如下所示:

public void testCompile() throws Exception {
  JasperCompileManager.compileReportToFile("test.jrxml", "test.jasper");
}

填充报表(.jasper -> .jrprint),JasperFillMangager类的静态方法fillReportToFile用于实现对二进制报表文件的填充,

该方法有三个参数:

1. 一个参数为String类型,表示待填充的文件名。

2. 第二个参数为Map对象,存放用于填充报表参数(对应与报表中的$P{参数名称})的键值对,下面代码中map对象中存有键值对{Title=员工列表},则对应报表中的$P{Title}位置将被填充为“员工列表”。

3. 第三个参数为数据库的连接(java.sql.Connection)对象,方法进行数据填充时需要用到该连接实现查询。

代码如下所示:

public void testFill() throws Exception {
  Map map = new HashMap();
  map.put("Title", "员工列表");
  JasperFillManager.fillReportToFile("test.jasper", map, getConnection());
} private Connection getConnection() throws Exception {
  Class.forName("com.mysql.jdbc.Driver");
  Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
   return con; }

导出报表,JRPdfExporter类用于将.jrprint格式的报表导出Pdf格式,

类似的类还有:

JRXlsExporter 导出成Excel文件格式

JRHtmlExporter 导出成HTML文件格式

JRCsvExporter 导出成Csv文件格式

JRRtfExporter 导出成RTF文件格式

JRTextExporter 导出成纯文本文件格式

JRXmlExporter 导出成Xml文件格式

JasperPrint类用于封装.jrprint文件数据。

JRPdfExporter的setParameter用于指定导出属性,如:需要到处的JasperPrint对象、导出文件的文件名等。

JRPdfExporter的exprotReport方法将实现报表的导出产生相应的PDF报表文档。

public void testExportToPdf() throws Exception {
  JasperPrint jp = (JasperPrint) JRLoader.loadObject("test.jrprint");
  JRPdfExporter exporter = new JRPdfExporter(); //指定要导出的jrprit数据
  exporter.setParameter(JRExporterParameter.JASPER_PRINT, jp); //指定导出文件的文件名
  exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "test.xls"); //实现报表的导出
  exporter.exportReport();
}

下面两个方法用于演示Excel格式和HTML格式报表的导出。

public void testExportToExcel() throws Exception {
  JasperPrint jp = (JasperPrint) JRLoader.loadObject("test.jrprint");
  JRXlsExporter exporter = new JRXlsExporter();
  exporter.setParameter(JRExporterParameter.JASPER_PRINT, jp);
  exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "test.pdf");
  exporter.exportReport();
} public void testExportToHtml() throws Exception {
  JasperPrint jp = (JasperPrint) JRLoader.loadObject("test.jrprint");
  JRHtmlExporter exporter = new JRHtmlExporter();
  exporter.setParameter(JRExporterParameter.JASPER_PRINT, jp);
  exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "test.html");
  exporter.exportReport();
}

HelloWorld 之JasperReports初步的更多相关文章

  1. 【WEB】初探Spring MVC框架

    Spring MVC框架算是当下比较流行的Java开源框架.但实话实说,做了几年WEB项目,完全没有SpringMVC实战经验,乃至在某些交流场合下被同行严重鄙视“奥特曼”了.“心塞”的同时,只好默默 ...

  2. SpringMVC初步——HelloWorld的实现

    开通博客园好几个月了,今天开始要用博客园记录自己的学习过程! 目录: 导包: 1. 配置web.xml文件的springDispatcherServlet 在xml中 alt+/ 找到springdi ...

  3. Lucene 初步 之 HelloWorld

    万恶的源头 HelloWorld 要完成lucene 的配置 需要几个jar包 (如果需要可以留言我私发) 创建索引API分析: 1. Directory: 类代表一个Lucene索引的位置,FSDi ...

  4. Electron(一)--初步了解并动手HelloWorld

    现在需要做一个桌面应用,心里有点不甘,因为想做出一个简单的客户端,你要么使用Java的Swing编程,要么会使用MFC等等,这样学习的代价太高,也不便维护,于是了解了一下Electron,Electr ...

  5. [dpdk] 熟悉SDK与初步使用 (二)(skeleton源码分析)

    接续前节:[dpdk] 熟悉SDK与初步使用 (一)(qemu搭建实验环境) 程序逻辑: 运行参数: 关键API: 入口函数: int rte_eal_init(int argc, char **ar ...

  6. Docker初步认识安装和简单实例

    前话 问题 开发网站需要搭建服务器环境,FQ官网下载软件包,搭建配置nginx,apache,数据库等.官网没有直接可用的运行版本,担心网络流传的非官方发布软件包不安全还得自行编译官方源码安装,忘记步 ...

  7. vim插件开发初步

    [vim插件开发初步] 将如下代码存在helloworld.vim, 放在~/.vim/plugin目录下,插件即可生效.:w保存代码后, 用:source命令执行后,也可以使用Helloworld命 ...

  8. Qt版helloworld

    跟学别的编程语言一样,Qt也不例外,一开始就想写一个helloworld.初学Qt十几天,看了一点关于Qt视频的介绍和书上的基础知识,对于Qt写工程的概念有了初步的认识,就代码的形式来说,Qt Cre ...

  9. Android学习之Activity初步

    Activity作为Android的第一步接触的概念,在学习中将初步的认识总结下来,以便后续的回顾与反思. 1.在用Android Studio生成第一个helloworld应用程序运行在手机上时,发 ...

随机推荐

  1. nginx 日志切割(也适用于docker)

    =============================================== 2019/4/6_第2次修改                       ccb_warlock 201 ...

  2. Android方法引用数超过65535优雅解决

    随着应用不断迭代更新,业务线的扩展,应用越来越大(比如:集成了各种第三方SDK或者公共开源的Library文件.jar文件)这样一来,项目耦合性就很高,重复作用的类就越来越多了,SO:问题就来了.相信 ...

  3. LeetCode(10):正则表达式匹配

    Hard! 题目描述: 给定一个字符串 (s) 和一个字符模式 (p).实现支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符. '*' 匹配零个或多个前面的元素. 匹配应该覆盖整 ...

  4. 优雅的vue.js

    优雅的vue.js代码 https://www.cnblogs.com/zhengrunlin/p/9164951.html watch 与 computed 的巧妙结合 如上图,一个简单的列表页面. ...

  5. P1736 创意吃鱼法 图的DP

    题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...

  6. 020 shuffle的重要作用,以及分区的实践

    一:学shuffle原理的必要性 1.说明 学习shuffle的作用是可以对程序进行优化. 在shuffle这个部分有三个部分需要注意: 分区 排序 分组 这个可以进行优化. 二:分区的实践 1.说明 ...

  7. muduo学习笔记(二)Reactor关键结构

    目录 muduo学习笔记(二)Reactor关键结构 Reactor简述 什么是Reactor Reactor模型的优缺点 poll简述 poll使用样例 muduo Reactor关键结构 Chan ...

  8. “百度杯”CTF比赛 九月场 YeserCMS

    打开题目 进入后是一个cms,但肯定的是这个cms不叫yesercms 于是我们开始随便翻翻,寻找信息,后台我也看了除了一个登陆界面,就没有其他的提示信息. 最后在文档下载的评论栏里发现,这个cms的 ...

  9. Python基础笔记(三)

    1. 循环与流程控制 (1) for myList1 = ["A", "B", "C", "D"] # 正序遍历 for ...

  10. 洛谷.4721.[模板]分治FFT(NTT)

    题目链接 换一下形式:\[f_i=\sum_{j=0}^{i-1}f_jg_{i-j}\] 然后就是分治FFT模板了\[f_{i,i\in[mid+1,r]}=\sum_{j=l}^{mid}f_jg ...