聪明文档网

聪明文档网

最新最全的文档下载
当前位置: 首页> Jasperreport和iReport详细功能介绍

Jasperreport和iReport详细功能介绍

时间:2013-10-11 10:05:38    下载该word文档

JasperReportIReport报表开发的功能介绍
目录

1 简介 4

2 JasperReportIReport的安装与配置 4

2.1 JDK的下载、安装和配置 4

2.2 ANT的下载、安装和配置 5

2.3 Jasperreport的下载、安装和配置 6

2.4 iReport的安装和配置 7

3 主要功能和实现过程 7

3.1 XML解析 8

3.2编译报表设计 8

3.3 Report Design 预览 9

3.4报表填充 10

3.5查看报表 11

3.6打印报表 11

3.7导出报表 11

3.8对象的载入和保存 11

4 iReport的使用指南 12

4.1一个简单的报表 12

4.2报表预览 13

4.3使用数据库的数据生成报表 15

5 报表设计 18

5.1DTD Reference 18

5.2XML编码 19

5.3报表属性 19

6 报表数据 21

6.1表达式 21

6.2参数 22

6.3数据源 24

6.4查询报表 25

6.5字段 26

6.6变量 28

7 Report Sections 31

7.1 Main Report Sections 31

7.2 数据分组 36

8 脚本程序 38

9 报表元素 38

9.1文本元素 40

9.2图像元素 45

9.3超链接 48

9.4元素组 48

10 子报表 49

10.1子报表参数 50

10.2子报表数据源 50

11高级JasperReports应用 50

11.1 XML报表的导入和设计 50

11.2实例化数据源接口 50

11.3自定义查看器 50

11.4导出新的格式 51


1 简介

Jasperreport是一款报表打印组件,是开放源代码组织sf.net中的一个java报表打印工程,是一款功能强大的报表生成工具。它既可以将报表内容在显示器上输出,也可以通过打印机打印出来,同时它还支持使用PDFHTMLXML等多种文件格式进行存储。在不久的将来,诸如CSVXLSRTF等格式也将会被兼容。

iReport也是开源组织sf.net中的一款免费软件,其主要作用是用来以可视化的方式设计生成JasperReport所使用的报表格式文件,因为JasperReport本身并未提供很好的可视化报表设计工具,iReport的出现正好弥补了这个缺陷。

2 JasperReportIReport的安装与配置

2.1 JDK的下载、安装和配置

下载

JDK的最新版本可以从SUN 公的官方网站上下载得到,网址为http://java.sun.com JDK共分为3 个版本,J2ME,J2SE,J2EE,因为是在计算机上使用,我们需要下载使用 J2SE SDK,如果您的计算机是用来做软件开发,需要下载J2SE SDK,如果是用来运行已经编译好的JAVA 程序的,可以只下载J2SE JRE 即可。

下载JDK SUN 公司会要求你同意一个JDK 的使用许可协议,选接受协议后,会出

现选择适合不同的操作系统平台使用的JDK 版本选择的界面,您可以根据自己使用的操作

系统平台选择适合的JDK 版本。

安装

Windows 平台的安装为例,在安装的过程中一路Next 即可,同时请注意记录下JDK

安装后的目录,稍后进行配置时要用到。

配置

以在Windows xp平台配置J2SE SDK 为例,鼠标右键点击桌面上的“我的电脑”图标,在弹出的菜单中选择属性,选择“高级”选项,选择“环境变量”。

点击“系统变量”下的新增按钮,在对话框中的变量名处输入大写的JAVA_HOME,在变量值处输入的JDK 安装目录。

点击“确定”完成第一步的配置,接下来以同样的方法配置系统环境变量CLASSPATH,在CLASSPATH的变量值处输入%JAVA_HOME%\lib\tools.jar; %JAVA_HOME%\lib\dt.jar,当然,也可以直接输入绝对路径,但建议使用%JAVA_HOME%的方式。

再接下来还要修改系统环境变量PATH,增加%JAVA_HOME%\bin 目录。

至此JDK 的配置也完成.

打开一个命令行窗口,键入set classpath set java_home 应该可 以看到正确的配置信息,同时,输入javac -version 看系统能否找到JAVA 的编译器。

2.2 ANT的下载、安装和配置

ant 是个很好用的工具,虽然对于JasperReport iReport 来说ant 并不是必须的,但还是建议以使用ant 的方式来应用。

ANT的下载和安装

ant apache 组织的一个子项目,可以从http://ant.apache.org 下载得到,Windows 平台

的可以下载ZIP 格式的安装文件,下载完成以后解压缩到某个目录,建议使用根目录下的直

接子目录作为ant 解压缩以后目录,ant 无需安装,解压缩文件以后就算安装完成。

Ant的配置

与设置JDK相同的操作过程打开系统环境变量设置窗口,增加ANT_HOME环境变量,变量值为解压缩以后的ant 所在目录

在系统的环境变量Path 中增加%ANT_HOME%\bin 目录

新开一个命令行窗口,输入ant 后如果出现如下图所示内容即算正确完成ant 的配置。

2.3 Jasperreport的下载、安装和配置

Jasperreport的下载和安装

因为JasperReport sf.net 的开源项目,最新的JasperReport 版本可以在sf.net 中找到,同时,为了方便世界各国程序员下载,sf.net 还设有许多的镜像站点供你选择。

强烈建议下载jasperreport source.zip,因为这里面包含了很多的示例程序,对于想深入研究jasperreport 的人来说会有很大的帮助。如果不想对JasperReport 有太多的深入了解,只需要下载.jar 文件就能正常开发应用了。

没有必要单独为JasperReport.jar 文件设置目录,建议放在系统中%JAVA_HOME%\lib\目录中。

Jasperreport的配置

JasperReport-x.x.x.jar 文件添加到操作系统的环境变量ClASSPATH 中即可完成JasperReport 的配置。

2.4 iReport的安装和配置

iReport的安装

iReport Windows 平台也是以.zip 形式的文件提供的,直接解压缩后就算完成了安装

如果是2.x版的,且您决定以ant 的方式运行iReport 程序,需要修改一下iReport 目录中的ireport.bat 文件中的内容,第一次运行ireport.bat 会生成javadoc,在确定已正确生成javadoc 文件后可以将生成doc 的那一段注释掉以便以后可以快速的启动iReport 程序。3.0 版无需修改ireport.bat 文件。

iReport 的使用

在有ant 环境的下运行iReport,直接运行iReport 目录中的ireport.exe 即可。

在没有ant 的环境下运行iReport2.X 版本使用iReport 目录中的noant 目录中的startup.bat 运行,3.0 版本使用bin 目录中的startup.bat 运行。

3 主要功能和实现过程

    现在我们将对XML报表设计进行分析,编译,装填数据,预览结果和导出到其他格式的过程。

Jasperreport的实例

下面是Jasperreport工具,将XML报表转变成的各种类型报表的流程图:

3.1 XML解析

    JasperReport使用SAX2.0 APIXML文件进行解析。然而,这并不是必须的,用于可以在执行其自行决定使用哪一种XML解析器。

JasperReport使用org.xml.sax.helpers.XMLReaderFactory类的createXMLReader()来获得解析器实例。在这种情况下,就像在SAX2.0文档中说的那样,在运行期,把Java系统属性org.xml.sax.driver的值设定为SAX driver类的全限定名是必要的。

设置系统属性有两种方法:

第一种方法是在你启动Java虚拟机的时候,在命令行窗口使用-D开关:

java -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser MySAXApp sample.xml

JasperReport提供的所有例子中,都采用ANT构建工具来执行不同的任务。我们通过使用内置的 task中的元素来提供这一系统属性;

第二种设置系统属性的方法是使用

java.lang.System.setProperty(String key, String value)

System.setProperty(org.xml.sax.driver, org.apache.xerces.parsers.SAXParser);

Jsp/compile.jspweb-inf/class/servlets/CompileServlet.java文件提供了这方面的例子。

3.2 编译报表设计

    为了生成一个报表,用户首先需要完成报表的设计,生成方法或采用直接编辑XML文件,或通过程序生成一个net.sf.jasper.engine.design.JasperDesign对象。在此,主要采用编辑XML文件的方法,因为这种方法在目前是使用JasperReport类库的最好的方法。

    XML报表设计是JasperReport用来生成报表的初级材料。这是因为XML中的内容需要被编译并载入到JasperDesign对象中,这些对象将在报表引擎向其中填入数据之前,必须经过编译过程。

    报表编译过程的主要目的是生成并装载含有所有报表表达式的类的字节码。这个动态生成的类将会被用来在装填数据,并在给所有报表表达式求值的时候使用。具体例子是,如果你用iReport生成一个报表名字叫SimpleSheetTest,它的XML设计文件名叫SimpleSheetTest.jrxml,同时和它在同一目录下iReport会自动生成一个文件名为SimpleSheetTest.java,里面主要是一些报表元素,如FieldParametersVariables的定义,以及一些求值表达式。当然,像上面提到的,这个文件在你直接使用JasperReport API的时候是看不到的,因为它是在执行期生成的一个Class。要想看到它的办法是:在IDEJBuilderEclipse)中单步执行程序,在报表打印的阶段,你将能跟踪到这个类,它的名字就是“你的报表名.java”,按上面的例子就是SimpleSheetTest.java,这和iReport是一致的。当然也可以像下面说的那样,到生成这个类的临时目录里找到它。

在这个类生成过程之前,JasperReport引擎需要验证报表设计的一致性,哪怕存在一处验证检查失败都不会继续运行下面的工作。

对于这个包含了所有报表表达式的类的字节码,我们至少需要关心三个方面的内容:临时工作目录、Java 编译器的使用、Classpath

   为了能够编译Java源文件,这个文件必须被创建并且被保存到磁盘上。Java编译过程的输出是一个.class文件,这个包含所有报表表达式的类在这个工作目录里被创建并编译,这也是为什么JasperReport需要访问这个临时目录的原因。当报表的编译过程结束之后,这些临时的类文件将被自动删除,而生成的字节码将保存在net.sf.jasper.engine.JasperReport对象中。如果需要的话,这个类可以将自己序列化并保存到磁盘上。这就是iReport的做法。

    缺省情况下,这个临时工作目录就是启动JVM时的当前目录,这却取决于JVM的系统属性user.dir。通过更改系统属性jasper.report.compile.temp,用户可以很容易更改这个工作目录。在Web环境下,特别是当你不想让含有启动Web Server的批处理文件的目录和报表编译过程的临时工作目录混在一起的时候,修改这个属性就可以了。

上面提到的第二个方面涉及用来编译报表表达式类的Java编译器。首先,报表引擎将试图使用sun.tools.javac.Main类来编译Java源文件。这个类包含在tools.jar中,当且仅当这个jar文件在JDK安装目录下的bin/目录中,或在classpath中时,sun.tools.javac.Main才能正常使用。

如果JasperReport不能成功装载sun.tools.javac.Main文件,程序将动态执行java编译过程,就像我们通常用命令行那样,使用JDK安装目录下的bin/目录下的javac.exe。这就是为什么将JDK安装目录/lib/下的tools.jar文件copyJasperReport工程的lib/目录下是一个可选的操作(optional operation)。如果tools.jar不在classpath中,JasperReport将显示错误信息并继续上面提到的操作。

  当编译Java源文件的时候,最重要的事情莫过于classpath。如果Java编译器不能在指定的classpath中找到它试图编译的所有相关类的源文件,则整个过程将失败并停止,错误信息将在控制台显示出来。同样的事情也将发生在JasperReport试图编译报表表达式类的时候。所以,在runtime为编译过程提供正确的classpath是非常重要的。例如,我们我们需要确认在classpath中,我们提供了在报表表达式中可能用到的类(custom class)。

    在这个方面也有一个缺省的行为。如果没有为编译report class特殊指定classpath,引擎将会使用系统属性java.class.path的值来确定当前的JVM classpath。如果你指定了系统属性jasper.reports.compile.class.path的值,你可以用你定义的classpath来覆盖缺省行为。

   大多数情况下,编译一个report只需要简单的调用JasperReport类库中的JasperCompileManager.compileReport(myXmlFileName);即可。调用之后将生成编译好的report design并存储在.jasper文件中,这个文件将会保存在和提供XML report design文件相同的目录中。

3.3 Report Design 预览

       JasperReport类库并没有提供高级的GUI工具来辅助进行设计工作。但是目前已经有至少4project试图提供这样的工具。然而,JasperReport本身提供了一个很有用的可视化组件来帮助报表设计者在编译的时候预览报表设计(其实不如直接用IReport方便)。

net.sf.jasper.view.JasperDesigner是一个基于SwingJava应用程序,它可以载入并显示XML形式或编译后的报表设计。尽管它不是一个复杂的GUI应用程序,缺乏像拖拽可视化报表元素这样的高级功能,但是它仍然是一个有用的工具。所有JasperReport工程提供的例子都利用了这个报表查看器。

       如果你已经安装了ANT,想要查看一个简单的报表设计,你只需要到相应的文件夹下输入如下命令:

ant viewDesignXML 或者 ant viewDesign
       如果你没安装ANT,要达到上面的效果就不是很容易,因为JasperReport本身需要一些其他辅助的jar包(在JasperReport安装目录/lib下),在运行的时候,你需要把这些jar包都包含到你的classpath里面,并且正确设计系统属性,如上面提到的org.xml.sax.driver。我可以展示一下在windows下的例子:

>java -classpath ./;../../../lib/commons-digester.jar;

../../../lib/commons-beanutils.jar;../../../lib/commons-collections.jar;

../../../lib/xerces.jar;../../../lib/jasperreports.jar

-Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser

dori.jasper.view.JasperDesignViewer -XML -FFirstJasper.xml

3.4报表填充

      报表填充过程是JasperReport library最重要的功能。它体现了这个软件最主要的目的,因为这一过程可以自由的操作数据集,以便可以产生高质量的文档。有3种材料需要装填过程中作为输入提供给JasperReportreport design、参数、数据源

      这一过程的输出通常是一个单一的最终要被查看,打印或导出到其他格式的文档。

要进行这一过程,我们需要采用net.sf.jasper.engine.JasperFillManager类。这个类提供了一些方法来让我们填充报表设计,report design的来源可以是本地磁盘,输入流,或者直接就是一个已存在于内存中的net.sf.jasper.engine.JasperReport类。输出的产生是于输入类型相对应的,也就是说,如果JasperFillManager接到一个report design的文件名,填充结束后生成的report将会是一个放在磁盘上的文件;如果JasperFillManager收到的是一个输入流,则生成的report将会被写到一个输出流中。

有些时候,这些JasperFillManager提供的方法不能满足某些特定的应用的要求,例如可能有人希望他的report design被作为从classpath中得到的资源,并且输出的报表作为一个文件存放在一个指定的磁盘目录下。遇到这种情况时,开发人员需要考虑在将报表设计传递给报表装填过程之前,用net.sf.jasper.engine.util.JRLoader类来装载report design对象。这样,他们就能获得像报表名这样的report design属性,于是开发者就能生成最终文档的名字,并将它存放到所需的位置上。

      在现实中,有许多报表装填的情境,而装填管理器仅试图覆盖其中最常被使用到的部分。然而对于想要自己定制装填过程的人来说,只要采用上面所说的方法,任何开发者都可以达到满意的结果。

报表参数通常作为java.util.Mapvalue提供给装填管理器,参数名为其键值。

作为装填过程所需的第三种数据源,有如下两种情况:

通常,引擎需要处理net.sf.jasper.engine.JRDataSource接口的一个实例,通过这个实例,引擎可以在装填过程中获取所需数据。JasperFillManager提供的方法支持所有的JRDataSource对象。

      然而,这个管理器还提供一些接受java.sql.Connection对象作为参数的方法集,来取代所需的数据源对象。这是因为在很多情况下,报表生成所需的数据都来源于某个关系型数据库中的表。

在报表中,用户可以提供SQL查询语句来从数据库中取回报表数据。在执行期,engine唯一需要做的是获得JDBC connection对象,并使用它来连接想要连接的数据库,执行SQL查询并取回报表数据。在后台,引擎将使用一个特殊的JRDataSource对象,但是它对于调用它的程序来说是透明的。

JasperReport工程提供了相关的例子,它们采用HSQL数据库服务器(在工程文件中,有一个相应的文件夹),要运行这些例子你需要首先启动该服务器,方法是:在/demo/hsqldb目录下输入如下命令:>ant 或者 >ant runServer

       没装ANT就麻烦点:>java -classpath ./;../../lib/hsqldb.jar org.hsqldb.Server

一下代码片断显示了query例子是如何装填数据的:

//Preparing parameters

Map parameters = new HashMap();

parameters.put("ReportTitle", "Address Report");

parameters.put("FilterClause", "'Boston', 'Chicago', 'Oslo'");

parameters.put("OrderClause", "City");

//Invoking the filling process

JasperFillManager.fillReportToFile(fileName, parameters, getConnection());

3.5 查看报表

      报表填充阶段的输出通常是一个JasperPrint对象,如果把它保存在磁盘上,通常以一个.jrprint文件的形式存在。JasperReport拥有一个内置的查看器,用来查看用内置的XML导出器获得的XML格式的报表文件。这个查看器就是以前提到过的net.sf.jasper.niew.JRViewer,用户可以通过继承这个类来定制自己所需的查看器。JasperReport工程中自带的例子webapp中,你可以阅读JRViewerPlus类的代码来获取进一步内容。

3.6 打印报表

      JasperReport类库的主要目标,就是生成可打印的文档。而且多数应用程序生成的报表都是需要打印到纸张上。我们可以用net.sf.jasper.engine.JasperPrintManager来打印JasperReport生成的文档。当然,报表也同样可以在被导出到其他格式如PDFHTML之后再被打印。通过JasperPrintManager提供的方法,我们可以打印整个文档,打印单个文档或打印某一范围内的文档,可以显示打印对话框也可以不显示。下面的例子演示了不显示对话框,打印整个文档的方法:JasperPrintManager.printReport(myReport,false);

3.7 导出报表

      在一些应用程序环境下,将JasperReport生成的文档从其特有的格式导出到其他更为流行的格式如PDFHTML是非常有用的。这样一来,其他人就可以在没有安装JasperReport的情况下查看这些报表,特别是当这些文档要通过网络发送出去的时候。

JasperReport提供了JasperExportManager类来支持此项功能。这项功能将会在以后不断加入对新的格式的支持。目前,JasperReport主要支持导出PDFHTMLXML类型的文档,下面是导出的代码片断:JasperExportManager.exortReportToHtmlFile(myReport);

       注意:想要将自己的报表导出到其他格式的用户,需要实现JRExporter的接口,或继承相应的JRAbstractExporter类。

3.8 对象的载入和保存

      当使用JasperReport的时候,你经常会与序列化的对象,如以编译的报表设计,或已生成的报表打交道。有时,你需要手动载入从不同的sourceinput stream或你用类库核心功能产生的序列化类。JasperReport提供了两个特殊的工具类来提供上述操作的能力,这些类通常供报表引擎自己使用:

net.sf.jasper.engine.util.JRLoader

net.sf.jasper.engine.util.JRSaver

      第一个类提供了一些方法让我们能够从不同类型的数据源如文件,URLinput streamclasspath里面获取序列化对象。最令人感兴趣的方法是loadObjectFormLocation(String)。它已经在上一章中介绍过了,这里不再赘述。

      与上面的对象载入工具相反的部分是JRSaver类,它可以帮助程序员将自己的类序列化之后存放到本地磁盘或通过Output Stream发送到网络上去。

       有时,开发人员可能想要载入已经生成好的report,或最终的已经被导出到XML格式的JasperReport文档,这与上面所说的直接load序列化对象有所不同。这时,我们需要载入的是将载入的XML内容进行编译,并生成JasperPrint对象,而并非仅仅是载入序列化对象。这时,我们可以通过net.sf.jasper.engine.xml.JRPrintXmlLoader类的一些静态方法,通过编译从XML文件中读取的内容构建出一个位于内存中的文档对象。

4 iReport的使用指南

4.1一个简单的报表

如上面左图所示新建一个文档,如右图设置报表的名称、大小等属性。

依照上图的标识,分别设计报表的各部分,可以通过以下快捷方式来插入图形、静态文字、动态文字图片等元素,设计如下图

报表设计完毕,选择菜单栏中的“建立”下拉菜单,选择其中“编译”,对报表尽进行编译,如有错误,会在底端提示,若无错误,则生成.Jrxml文件。编译成功之后,选择“执行报表”,进行预览。

4.2 报表预览

Ireport默认是用其自带的iReport JasperViewer进行预览。我们可以选择其他的预览方式,通过选择菜单栏中的“Option”下拉菜单,选择其中的“选项”,选择External Programs选项卡,如下图所示,对各个预览工具进行配置

配置之后,可以通过选择菜单栏中的“建立”下拉菜单,选择以配置好的预览方式,之后选择“执行报表”,就可以用相应的应用程序对其进行预览。

4.3 使用数据库的数据生成报表

4.3.1连接数据库

选择菜单栏中的“data”下拉菜单,选择“连结/资料来源”,

选择“New”新建一个连接,配置如下图,其中experiment是已建立的数据库名称

单击“Test”,测试数据库连接是否成功,若成功,有以下对话框

若不成功,有类似于下图的相应的对话框

测试成功,单击“save”保存新建连接。

4.3.2设置SQL查询语句

选择菜单栏中的“data”下拉菜单,选择“报表查询”,

之后在相应地方编写SQL语句。编写完毕,单击“OK”保存并退出编写。

4.3.3字段在报表设计器中的使用

点击工具栏中的在报表中的“Details”段中用鼠标拖拽到适合的大小,右击该

字段框,选择属性,在选择Text Fiel选项卡,如下图:

选中Text Field 项,如果没有设置正确的字段名称,则Textfield expression 中的内容将显示

蓝色,手工修改Textfield expression 中的内容为正确的字段名称,格式为$F{字段名称},正

确修改后将变为绿色显示。

4.3.4编译与预览带有字段的报表

对下面报表进行编译,其中数据已经在数据库中预先设好

编译报表可以选择菜单栏中“建立”下拉菜单中的“编译”,也可以直接点击工具栏中的图标,如果编译过程正确完成,iReport 设计器的下面会显示如下内容:

带有字段的报表进行预览有两种方式,一种是不使用数据库中的数据,默认所有字

段值为null 的方式,预览方法为选择“建立”菜单中的“执行报表”,也可以直接点击工具栏中的图标;第二种方式为使用数据库中的数据的方式,预览方法为选择“建立”菜单中的“执行报表(使用动态连接)”,也可以直接点击工具栏中的图标。下图进行预览:

5 报表设计

报表设计体现了一个模板,JasperReport引擎利用这个模板将同台生成的内容传递给打印机,屏幕或Web。存储在数据库中的数据在报表装填的过程中被组织起来,根据已有的报表设计来获得可以进行打印的,面向页面的(page oriented)文档。

总而言之,一个报表设计包含了所有的结构相关信息和将数据提供给报表所涉及的各个方面。这些信息涉及将在文档中显示出来的各种text或图像元素的位置和内容,自定义计算(custom calculation),数据组织,报表生成时的数据操作,等等。

报表设计通常都定义在一个拥有特殊格式的XML文档中,并且在被填充数据之前要经历JasperReport的编译过程。然而JasperReport也允许用户通过JasperReport提供的API构造in-memory报表对象,例如noxmldesign就是很好的例子。

5.1 DTD Reference

    当使用XML文件进行报表设计的时候,JasperReport将使用内置的DTD文件来验证其受到的XML内容的有效性。如果XML验证通过,则说明所提供的报表设计符合JasperReport所需要的XML结构和语法规则,其引擎能够生成经过编译的report design

    有效的XML文档总是在验证时指向JasperReport的内部DTD文件。如果没有提供DTD文档的引用,报表的编译过程将会突然结束。这对所有人来说都是一个负担,因为DTD引用通常是相同的,并且这些引用可能会简单的被从以前的报表设计中copy过来。在一开始,你需要将这个引用从给定的例子中copy过来。

    正如以前说的一样,报表引擎仅能识别指向其内部DTD文件的的引用。你不能随便从类库的源文件中将那些DTD文件copy到别的地方,再在你的报表设计文件中指向你copy的那些DTD文件。如果你想那样做的话,你将需要调整类库中某些类,包括dori.jasper.engine.xml.JRXmlDigester类的某些代码。如果你遇到像引擎无法找到其内部的DTD文件而导致的无法载入资源的问题,请确定你已经在使用外部DTD文件之前排除了所有可能发生的情况。遇到这样的问题是不太可能的,因为资源载入机制会随着时间不断改进。

JasperReport只有两种合法的XML报表设计的DTD引用,他们是:

"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">

或者:

"http://www.jasperreports.com/dtds/jasperreport.dtd">

     XML报表设计的根元素是,下面是一个普通的JasperReports XML报表设计文件的样子:

"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">

...

前三点描述了该报表设计的属性和设置,下面省略的部分则描述了各种报表设计要素如报表参数、字段、变量、组和报表栏等。

5.2 XML 编码

    当要生成不同语言的XML报表设计的时候,在XMl文件的首部的编码属性需要特别关注一下。缺省情况下,如果这个属性的值没被订制,则XML解析器将会使用“UTF-8作为XML文件的编码格式。这一点是非常重要的,因为报表设计通常包含了静态的本地化文本。

对于大多数西欧语言来说,ISO-8859-1编码,也就是我们常说的LATIN1将会很好的处理如法语中重音符号的显示问题。

在编辑XML文件的时候,要找到某种特殊语言的编码类型,你可以查看XML document.FIXME

5.3 报表属性

    我们上面已经看到,XML报表设计的根元素。这一节我们将介绍报表设计对象的Property的细节以及这些属性所对应的XML attributes

报表名称

    每一个报表都必须有一个名称。这个名称是相当重要的,因为类库需要它来生成文件,尤其是当编译,装填,导出报表的默认行为被使用的时候,这个名的作用更为重要。这个名称是以元素的name attribute的形式提供的,并且是强制必须填写。

列数

       JasperReport允许生成每页的列数超过一列的报表,正如下面的图片,展示了拥有两列的报表:

默认情况下,报表引擎生成每页一列的报表。

打印顺序

    对于拥有超过一列的报表,为其提供列将被以什么顺序填充是很重要的。你可以使用元素的printOrder attribute来进行设置。有如下两种情况:

Verticaln Filling:这个选项将导致列是自顶向下被填充(printOrder=Vertical”)

Horizontal filling:列将自左向右被填充(printOrder=Horizontal”)

缺省设置将是printOrder=Vertical
页面大小

    有两个attribute是用来提供要生成的文档大小的:pageWithpageHeight。像所有其他显示元素位置和尺寸的attribute一样,这两个attribute是以像素为单位的。JasperReport采用Java默认的每英寸72点的设置。这意味着pageWith=595将大约是8.26英寸,这大概是A4纸的尺寸。

默认的纸张大小是A4纸:pageWith=595 pageHeight=842

Page Orientation(默认设置为Portrait

    orientation属性用来设置文档打印格式是“Portrait”还是“Landscape”。JasperReport允许用户在从“Portrait”切换到“Landscape”的时候调整液面的宽度和高度。我们先看一个例子:我们假定要生成一个A4纸的报表,采用“Protrait”格式:

    pageWidth=595 pageHeight=842 orientation=Portrait

    如果我们决定用A4纸的“Landscape”布局,首先要调整相应的页面宽度和高度:

    pageWidth=842 pageHeight=595 orientation=Landscape

    这是因为JasperReport需要确切知道它所要绘制的报表页的宽度和高度,而不只看我们提供的orientation属性,至少在报表装填的时候是这样。orientation属性仅在报表打印时有用,来通知打印机或某些exporters页面的orientation设置。

页边距

    一旦页面大小确定下来,用户就可以在生成报表的时候设定报表的边距。有四个属性来完成这项工作:topMarginLeftMarginbottomMarginrightMargin。缺省的设置是上下边距20像素,左右边距30像素。

列宽和列间距Column Size and Spacing

    一个报表可能含有多列,我们可以通过上面提到的columnCount属性得到报表列数。JasperReport需要知道列的宽度和列间距的大小。有两个属性用于这项工作:columnWidthcolumnSpacing。当我们对报表设计进行编译的时候,编译器会对这项设置进行有效性检查(validation check--看列的宽度和列间距是否符合给定的页面宽度和页边距。因为缺省的列数为一,所以缺省的列间距为0像素,并且缺省的列宽等于页面宽度减去左右边距所得的值。在上面A4的例子中,列宽即为555像素。

空数据源时的行为

    有时我们提供给我们的报表的数据源可能会没有任何记录。whenNoDataType属性可以让你选择当所提供的数据源中没有数据的时候入和察看生成的报表。如下有三种不同的可能性,你可以任选其一:

Empty Document:生成的报表不含有页面(no page in it)。当你试图装载这样的文档(whenNoDataType=NoPages”)的时候,Viewer 可能会抛出一个错误。

Blank page:表示生成的报表将仅含有一个空白页(whenNoDataType=BlankPage”)

All sections displayed:除了detail部分的其他部分将在生成的文档中显示出来(whenNoDataType=AllSectionNoDetail”)。

缺省的设置是whenNoDataType=NoPages”。

标题和摘要的放置Title and Summary Sections Placement

       如果你想让title部分和summary部分在单独的一页里显示,你所需要做的事情就是让下面的一个或两个属性的值为“true”:isTitleNewPageisSummaryNewPage。这两个属性缺省情况下为false

注意:即使你选择了在最后一页的剩余部分显示summary,如果列数超过一列,并且第二列已经在最后一页出现的时候(没试过,等有机会试验一下),新的一页将会被自动生成。

脚本类Scriptlet Class

       scirptletClass属性用于设置用于当前报表的scriptlet类的名字。在后面会对Scriptlet进行详细讨论。如果你没为这个属性提供任何值,报表引擎将会使用dori.jasper.engine.JRDefaultScriptlet的实例。

6 报表数据

    当谈到报表装填过程的时候,有三样东西需要作为输入提供给报表引擎:报表设计(report design),参数值(parameter values)和报表的数据源(data source)。

在先前的介绍,我们已经看到了有关报表设计的某些方面,现在我们要更加详细的关注其他两方面的内容:参数(parameter)和报表数据源。他们描绘了报表引擎在装填报表过程中所用到的仅有的数据来源。像你用其他报表工具所希望的一样,这些数据将会根据报表设计中的定义的模板(template)被组织起来,并被用来生成准备打印的、面向页面的文档。

6.1 表达式(expressions

    表达式是JasperReports的一个非常有用的特性。他们可以用来声明执行各种执行各种计算(calculations)的报表变量(report variables),进行报表的数据组织,定制报表文本字段(text field)的内容或者进一步定制报表对象的appearance

所有报表表达式基本上都是Java表达式,他们可以以特殊的语法引用报表参数(parameter),报表字段(field)和报表变量(variable)。

XML报表设计中,有一些用于定义表达式的元素:, ,,,, 等。

因为所有的JasperReport表达式都是真正(real)的Java表达式,只要你用完整的类名(包括包名)来引用这些表达式,你就可以在任何class中使用他们。当你编译报表和装填数据的时候,你应该确定你在报表表达式中使用的类已经写入了classpath

报表参数引用是通过$P{}序列引入的,例如:

$P{ReportTitle}

    这个例子假定我们在报表设计中有一个名为ReportTitle的报表参数,这个参数是一个java.lang.String类。当报表进行装填的时候,文本字段将会显示这个参数的值。

为了在一个表达式中使用报表字段,字段名必须放在$F{}的括号中。例如,如果我们想要在一个文本字段中显示两个数据源字段的连接值(concatenated values,我们可以定义 如下表达式:

$F{FirstName} + " " + $F{LastName}

表达式可以更加复杂:

$F{FirstName} + " " + $F{LastName} + " was hired on " +

(new SimpleDateFormat("MM/dd/yyyy")).format($F{HireDate}) + "."

    正如你所看到的一样,参数、字段和变量引用都是通过用JasperReport的特殊语法从一个真正地Java对象中引入的。(实际上是一个JREvaluator对象,该对象是在运行其生成的动态对象,并不能在本地磁盘上见到它的身影,不过如果你使用iReport的话,你就可以在生成报表文件的同一目录下看到它的本来面目)

下面这个例子给我们显示了怎样从一个java.lang.String类型的报表字段中选取并显示第一个字符:

$F{FirstName}.substring(0, 1)

6.2 参数(Parameters

     Parameters是传递给报表装填操作的对象引用。这些参数主要作用于把那些不能从报表数据源中获得的数据传给报表引擎。例如,我们可能要把执行报表装填过程的用户名字专递给报表引擎,如果我们想让它显示在报表上或者在我们想在报表的title上动态的改变它,我们就可以以参数的形式传给报表引擎。

在一个报表设计中声明一个参数是很简单的,它只要求指定参数的名称和所属类:

这里所提供的报表参数值可以被用到各种报表表达式中,在报表SQL查询中,甚至可以用到报表的scriptlet类里。

下面是构成参数定义的全部组件(XML元素):

参数名

     name属性是参数的一个强制属性。JasperReport的命名习惯和Java语言的命名习惯是类似的,这意味着参数名应该是一个单词,其中不含特殊字符(如分号)。

参数类型

    报表参数的第二个强制属性是提供参数值的类型名。这个类型属性可以使任意的值,只要这个类型的名字在报表编译期和装填期能在classpath中找到即可。

提供给参数的值

    GUI引用程序中,建立一个报表参数集,让用户在执行装填过程之前输入某些应用程序需要用户输入的报表参数是很有用的。可选参数isForPropting参数用来声明是否显示提示信息让用户输入某些参数。下面的例子中,声明了一个文本参数,当需要用户输入参数值的时候,这个文本参数用来在一个已定制的对话框中描述需要用户输入什么样的参数:

Please type here the report comments if any

]]>

注意:相信大家都知道表示“内容”将不被XML解析器解析,也就是说,你可以在“内容”里加入XML的特殊字符,如>,等等。

参数的默认值(parameter default value

    通常参数值都是使用java.util.Map对象传给装填过程的,其中参数名作为Key。这样,你就不用每次都为每个参数提供一个value了,可以批量放到Map对象里一起传给装填管理器。如果你没有为参数提供一个value,引擎就认为它是null。但是如果你为它提供了一个默认值,则引擎将在你没提供这个参数值的情况下使用这个默认值。如果你在装填时没提供数据,下面的java.util.Date将在装填是被引擎使用来表示当天日期:

new java.util.Date()

在参数的默认表达式中,我们可以使用先前定义的报表参数。

6.2.1 内置的报表参数

    每一个报表设计中都含有一些预先定义的报表参数,这些内置的参数的描述如下:

Parameter REPORT_PARAMETERS_MAP

    这是一个内置的参数,这个参数总是指向一个java.util.Map对象,该对象保存了用户调用报表装填过程时传递给报表引擎的用户定的参数。

Parameter REPORT_CONNECTION

    这个报表参数指向一个java.sql.Connection对象,这个对象被提供给报表引擎用来通过JDBC来执行SQL报表查询。将master报表使用的JDBC Connection对象传递给subreport是非常有用的,有关这方面信息请查看subreport例子.

Parameter REPORT_DATASOURCE

    在报表装填的时候,我们可以或者直接由应用程序中提供,或由报表引擎从所提供的JDBC Connection在后台create而获得一个数据源。这个内置的参数允许我们在报表表达式中或scriptlet中访问报表数据源,而不论我们为什么要这么做。

Parameter REPORT_SCRIPTLET

即使报表不使用scriptlet,这个内置的参数仍将指向一个net.sf.jasper.engine.JRAbstracStriptlet实例,该实例实际是一个net.sf.jasper.engine.JRDefaultScriptlet对象。

但是当使用scriptlet时,报表装填过程所生成的这个指向scriptlet类实例的引用允许我们调用其中的某些特殊函数,使用或控制scriptlet对象在装填过程中已经准备好的数据。在scriptlet例子中你可以看到更详细的使用过程。

6.3 Data Source(数据源)

在进行报表装填的时候,JasperReport引擎迭代的从用户提供的数据源中提取record,并根据报表设计所提供的模版生成报表的各个部分(section)。通常情况下,引擎需要接收一个dori.jasper.engine.JRDataSource对象作为报表数据源。但是像我们即将看到的那样,当报表数据存储于关系型数据库的时候,JasperReport有了让用户提供一个JDBC链接对象来替代通常的数据源对象的特性。JRDataSource接口非常简单,如果我们想要实现它只需要实现下面两个方法:

public Boolean next() throw JRException;

public Object getFieldValue(JRField jrField) throw JRException

    在报表装填的时候,next()方法将被报表引擎调用,迭代的从数据源中获取数据。第二个方法用来为每个在当前数据源记录(data source record)中的报表字段(report field)提供value

    应当知道,从数据源取得数据的唯一方法是使用report field。一个数据源对象更像是一个二维表,表中含有数据。这个二维表的行是一条一条的record,而每一列都映射为一个report field。所以我们可以在report表达式中使用数据源。JasperReport提供了一些缺省的JRDataSource实现,我们来具体看一下:

Class dori.jasper.engine.JRResultSetDataSource

    这是一个非常有用的缺省实现,因为他外覆(wrap)了java.sql.ResultSet对象。由于多数报表的生成都采用关系数据库中存储的数据,所以这个类是被使用得最为广泛的数据源对象。然而在以下的两种情况下您可以不必在装填过程中自己生成这个对象:

    如果你选择在你的报表中用SQL查询来获得在关系数据库的某个table中的数据,报表引擎将会通过执行给定的SQL查询并且将返回的java.sql.ResultSet外覆为一个dori.jasper.engine.JRResultSetDataSource实例来执行这项操作。引擎唯一需要的是一个java.sql.Connection对象来执行查询操作。这时你可以提供connection对象来作为通用数据源对象(usual data source object)。例子有:jasperscriptletsubreportquery

当然你可以在应用程序中即JasperReport之外执行SQL查询。这样的话,你可以手动的外覆java.sql.ResultSet,再调用报表装填过程之前实例化这个数据源对象。当使用这种类型的数据源的时候,你需要为在result set中的每一列生命一个report fieldreport field的名字和类型必须和列的名字和类型匹配。

Class dori.jasper.engine.JREcptyDataSource

    这个类主要用于当生成报表的数据不是来自数据源,而是来自参数或重要的仅是数据源中virtual records的数量的时候。例子fontsimagesshapesunicode都使用了这个类来装填报表,来模拟数据源中没有一条记录,所有字段都为null的情况。

Class dori.jasper.engine.data.JRTableModelDataSource

    这个JRDataSource接口的缺省实现外覆了javax.swing.table.TableModel对象,它可以用在Java Swing应用程序中从已经显示到屏幕上的table中得数据来生成报表。

通常有两种方法来使用这种数据源:

通常,为了要从中取得数据,你需要为javax.swing.table.TableModel对象的每一列生命一个report field。但是有些情况下会出现问题,比如report field的命名需要遵照Java命名规范来声明变量,而table的列名则不需要。幸运的是,你仍然可以通过列的索引而不是它的名字来将report field与列进行映射。例如,一个列名为“Produce Description”不可能被映射到名为“Produce Description”的report field上,因为report field名中含有空格,这将引起一个编译错误。但是如果你知道这个列示table model对象的第三列(index=2),那么你就可以命名相应的字段“COLUMN_2”并无误地使用这一列的数据。例子有:

Class dori.jasper.engine.data.JRBeanDataSource

    这个类外覆了一个JavaBeans数组,并且通过反射来获取report field的值。在这种数据源中,一个JavaBean对象描述了一条记录。如果我们有一个名为“ProductDescription”的report field,在获取这个字段的值的时候,程序将会试图通过反射机制调用一个当前JavaBeans对象中]名为getProductDescription()的方法。对于boolean字段,当调用get前缀的属性不能返回其属性值的时候,程序将会试图使用is前缀的方法来获得属性值。

Class dori.jasper.engine.data.JRBeanCollectionDataSource

       这个类和上一个类非常类似,它也是使用反射机制和JavaBean命名规范,但是它外覆了一个java.util.Collection对象而不是一个JavaBean对象数组。在datasource例子中你可以看到进一步的用法。


6.4 报表查询(Report Query

     要为报表装填数据,我们需要为报表引擎提供所需的数据,或者至少告诉它怎样去获取数据。JasperReport通常需要接受一个net.sf.jasper.engine.JRDataSource对象作为报表的数据源,同时作为更为强大的功能,JasperReport能直接用JDBC从关系数据库总获取数据。类库允许用户在他们的报表设计中提供SQL查询以便可以自运行期从数据库中提取数据。要做到这一点,你只需要在装填的时候为装填管理器的fillReport()方法提供一个java.sql.Connection而不是JRDataSource对象即可。

在报表中,可以使用元素来引入查询。如果这个元素存在,则出现在报表参数声明之后,报表field之前。

如下是一个SQL查询的例子:

    为了更好的定制从数据库中取回的数据集(data set),一个重要的方面是在报表查询字符串中报表参数的使用(use of report parameters)。在查询中,这些参数可能会像动态过滤器(dynamic filter)一样工作,它们用特殊的语法被引入进来为报表提供数据,很像report expression

如下有两种在查询中的使用参数的方法:

1. 像通常的java.sql.PreparedStatement的参数那样使用,用如下语法:

SELECT * FROM Orders WHERE OrderID <= $P{MaxOrderID} ORDER BY ShipCountry

]]>

2. 有时,我们需要使用参数来动态更改SQL查询的某些部分,或将整个SQL查询作为参数提供给装填过程。在这种情况下,语法稍微有些不同,向下面的例子,注意“!”

SELECT * FROM $P!{MyTable} ORDER BY $P!{OrderByClause}

]]>

    在这个例子中,这个引入了参数值得特殊的语法确定了我们为这些参数所提供的值将会替代查询中的参数引用($P!{}的内容)。这些参数将被传给使用java.sql.PrepqredStatement对象的数据库服务器。

事实上,报表引擎首先处理$P!{}参数引用,通过使用他们的值来获取最重的SQL查询,并且仅当这件事完成之后,引擎才会将剩下的普通的$P{}参数引用传递给usual IN parameters

第二种用于SQL查询的参数引用允许你在运行期传递整个SQL查询语句:

$P!{MySQLQuery}

注意:你不能在参数值中再加入参数引用,也就是说,参数引用不能嵌套使用。

更详细的信息可以参看工程所带的例程:jaspersubreportscriptletwebapp以及最有学习价值的query

6.5 字段

报表字段是数据从数据源传到报表设计和使用报表表达式中的数据的唯一路径,以此来获得所要的输出。

声明报表字段时,你必须确保所选的数据源在报表的装填时间能提供所有这些已声明的字段。例如,万一你用了dori.jasper.engine.JRResultSetDataSource接口,并且使用报表查询时发生这种情况,你必须确保报表查询执行后的结果集中每一种字段都占有一列,并且相应的每一列都必须与传值给它的字段具有相同的名字和相同的数据类型。

这是一个字段声明的语法,字段的声明需要对应与数据库表中的某一字段。我们考虑一个名为Employees的表,其表结构如下:

报表字段需要下面这样定义:

如果我们声明的字段在结果集中没有相应的栏对应,执行时就会抛出异常(如果你用iReport,在编译时也会抛出异常)。然而执行SQL查询之后返回的结果集中包含的列不需要与报表字段一一对应(即列可以多于字段,只是在显示的时候不显示出来罢了)

下面描述一个报表字段定义的各个组成元素:

Field Name(字段名)

Name attribute是强制属性,你可以在表达式中通过它来引用该字段。声明的字段名,应该是单词,而且不含特殊字符如点和分号。

Field Class(字段类型)

报表字段的第二个属性描述了字段值的类型。其缺省为java.lang.String类型,但你如下类型可选:

java.lang.Object

java.lang.Boolean

java.lang.Byte

java.util.Date

java.sql.Timestamp

java.lang.Double

java.lang.Float

java.lang.Integer

java.io.InputStream

java.lang.Long

java.lang.Short

java.math.BigDecimal

如果某些数据源含有一些自定义的类型,则该类型所对应的字段应该声明为java.lang.Object。但是与参数定义不同的是,你只能选择上述列表中的类型名。

Field Description(字段描述)

这额外的文本块证明是非常有用的,例如实现自定义数据源时。你可以在其中存一个关键词或你可能需要的信息,这是为了确保在运行时能从自定义数据源找回字段值

使用Field Description这个选项,你可以轻松的越过字段名的约束。当要从数据源找回字段值时,可以使用field description 代替字段名来获取相应数据。

PERSON NAME

6.6 变量

报表变量是建立在报表表达式之上的一些特殊对象。们是用表达式定义的,用来执行某些运算,来简化报表中频繁出现或使用某些项目(如页号,页码,某些列的累加和等等)。

一个变量可以引用其他变量,当且仅当这些被引用的变量已经在报表中被定义过。因此,在报表设计中,变量的声明次序是很重要的。

Variable Name(变量名)

就像变量和字段,变量的name attribute是强制性的并且允许在报表表达式中允许用这个名字来引用该变量。我们提到的对参数和字段的命名约束同样也适用与变量。

Variable Class

Class attribute 包含了变量值所属类的类名,默认是java.lang.String。无论在报表的编译期还是报表的装填期,只要你所选的类型的类在classpath中可以找到,你就可以声明该类型的报表变量。

Reset Type

变量的值可以在每一次迭代(iteration)被改变, 但也可以在装填过程中的某一特定的时间(specified moments)通过它的初始的value表达式恢复其初始值这种行为是由ResetType attribute 来控制的。ResetType attribute 指出了在报表装填过程中变量何时需要重新初始化。

下面是变量的5reset type

No Reset:变量从不用它的初始值表达式来初始化,变量只通过运算变量表达式来获得值(resetType=None”)。

Report Level Reset:变量只在报表装填过程的起始使用变量的初始值表达式来进行初始化,并且只有这一次。(resetType=Report”)。

Page Level Reset:变量在每一页的起始时被重新初始化。(resetType=Page”)。

Column Level Reset:变量在每一新列的开始被初始化。(resetType=Column”)。

Group Level Reset:变量将在每次resetGroup attributes 提供的break的地方被重新初始化。(resetType=Group”)。

默认情况是resetType=Report”。

Reset Group

resetGroup attribute 包含报表组的名称并且仅与resetType=Group”的resetType属性相关联。

6.6.1 运算(Calculations

像以上所提到的,变量能执行内置的计算类型(build-in types of calculation下面将列出变量的calculation attribute 的所有可能的值:

Calculation Nothing

这是变量执行的缺省计算。它意味着变量值在数据源的每次迭代注:文章中提到的数据源的迭代都是指:例如,在报表装填的时候,引擎执行SQL查询返回的ResultSet中含有若干记录,每次迭代都是指从ResultSet中获得一条记录,并将这条记录的值赋给已经声明的字段时都被重新计算(这里的计算只是简单的通过变量表达式给变量赋值)。

Calculation Count

在每次数据源的迭代的时候,一个计数(count)变量将会把用主表达式(main expression)计算所得的非空(not null)值累加起来。计数变量(Count variables)必须是一个数字类型的变量,但是它的主表达式可以是一个非数字型表达式(non-numeric expression),因为报表引擎不关心表达式类型,而仅仅将这些非空的返回值得数目累加起来就好像一个累加器一样。

只有变量的初始值表达式必须是数字型的,并且需要和变量的类型相同,因为这个值将会在初始化的时候被直接赋给变量。

Calculation Sum

如果你选了这种计算类型并且确保变量是数字类型的,则报表引擎将会把变量主表达式的返回值累加起来。我们不能计算java.lang.String or java.util.Date类型的报表变量。

Calculation Average

对于数据源中的每一条记录,报表引擎可以计算通过对变量表达式求值所得的一些列结果的平均值(series of values obtained by evaluating the variable’s expression)。这种类型的计算的也只能是数字类型的变量

为了计算平均值,报表引擎在后台创建了一个helper报表变量,此变量的作用是计算values的累加和,然后可以通过它来计算平均值。这个helper sum variables的命名规则是在与它对应的变量名之后加上后缀“_SUM”。例如你给某个数字类型的表达式声明了一个平均计算变量名为“MyAverageVariable”,则报表引擎将会创建一个报表变量MyAverageVariable_SUM来帮助计算平均值。你可以在其他表达式中使用这个helper变量,就像你使用其他你声明的变量一样。

报表引擎为了计算平均值,也需要一个计数变量来与辅助加法变量对应。对“Report,Page”和”Column“这三种resetype,它用了内置的计数变量,这些我们在接下来的一个部分将会讲到。而对于resetType=Group”的情况,它在后台创建了一个helper计数变量,其名称为原始的平均变量名加上后缀”_COUNT”。

Calculation Lowest and Highest

对于每一个数据源记录来说,如果你想在一系列从赋值表达式中获得得最大或最小的value,你就需要选择这种类型的计算。

Calculation StandardDeviation and Variance

在一些特殊的报表中,你可能会需要执行一些高级的数字运算,而JasperReport已经内置了对的一些经过变量表达式赋值所得到的value的标准偏差和方差进行计算的算法。和前面计算均值的方法一样,报表引擎首先建立一些helper变量来获得相应于当前一系列值的计数和累加和,这些变量命名方式和上面一样,这里不再赘述。

Calculation System

当你不想要报表引擎去干预你的变量运算时,你可以选择这个选项。这意味着你要通过使用JasperReports scriptlets功能来亲自计算变量的值。

对于这种类型的运算,引擎唯一做的事就是从数据源的迭代中保存你已经计算好计算的那些值。

例子:

下面是一个简单的报表变量声明,用来计算名为“Quantity”的数字字段的值的总和:

$F{Quantity}

如果你想要每一页的该字段值的和,下面显示的是所要求的变量声明:

calculation="Sum">

$F{Quantity}

new Double(0)

在上面的这个例子中,我们的page sum variable 将会在每一新页的开头被初始为0

6.6.2 Built-in Report Variables(内置报表变量)

有如下的几种内置系统变量可以直接用在表达式中:

Variable Page_NUMBER

该变量保存当前的页号。在报表装填结束的时候,该变量值保存最终文档的总页数。所以要在JasperReport的文本字段中显示页号和总页数你都可以用它。

通过使用JasperReports text field 元素的一个名为evaluationTime 的特性,该变量就可以同时显示当前页码和页面总数。在大多数的例子中都会有上述这种情况。

Variable COLUMN_NUMBER

该变量表示当前的列码。例如,一个报表页面中有三列,则在isTitleNewPage和其他相关属性不干涉的情况下,报表的第二页中的列码应该是#4#5#6

Variable REPORT_COUNT

当数据源迭代结束之后,该报表变量值表示的是处理的记录的总个数。

Variable PAGE_COUNT

该报表变量用来表示在当前页中处理的记录总个数。

Variable COLUMN_COUNT

该报表变量用来表示在当前列中处理的记录总个数。

Variable GroupName_COUNT

当声明了一个报表组,引擎会自动创建一个计数变量来计算组成当前组的记录数目,即在组和组的rupture之间所处理的记录的数目。(注:这里的GroupName是泛指组名,即任意一个组的名字)

该变量名字的来源就是相应的组名加上后缀“_COUNT”,它像其他的报表变量一样可以用在任何报表表达式中。

7 Report Sections

在建一个报表设计时,我们需要定义它的每个section的内容和设计。报表设计的整体结构基于下面几个部分:, <pageHeader>, <columnHeader>, <groupHeader>, <detail>, <groupFooter>, <columnFoter>,<pageFooter>, <summary></span><span>。</span></p><p><span> </span><span>Sections</span><span>是报表模板的一部分,有指定的高度和宽度并且可以包含报表的一些元素如线、矩形、图片和文本域等。这些</span><span>Sections</span><span>在报表的生成过程中不断的被装填并且组成了所要的最终文档。当我们在一个</span><span>XML</span><span>报表设计中声明报表</span><span>section</span><span>的内容和设计时,用到了一般元素</span><span><band></span><span>。</span></p><p><img></img></p><p><span>有时用报表</span><span>band</span><span>来代替报表</span><span>section</span><span>。报表</span><span>band</span><span>几乎与其他所有报表工具具有相同的特性,所有它能以同样的方法被使用。</span></p><p><span>Band Height</span></p><p><span> </span><span>在报表</span><span>band</span><span>的声明中,该属性指定了特定</span><span>band</span><span>的高度所占的像素点数,这对总体的报表设计来说是很重要的。</span></p><p><span> </span><span>填在一个特定</span><span>band</span><span>中的元素应该总是适合该</span><span>band</span><span>的尺寸,这是为了避免在生成报表时产生负影响。当编译报表设计时,如果引擎发现有元素超出</span><span>band</span><span>的边界就会发出一个警告。</span></p><p><span>Skipping Bands</span></p><p><span> </span><span>所有的报表</span><span>section</span><span>都允许定义一个报表表达式,表达式在运行时间被运算并且在生成文档的时候用来决定某个特定的</span><span>section</span><span>是要产生还是放空。表达式通过</span><span><printWhenExpression></span><span>来引入。</span><span><printWhenExpression></span><span>在</span><span>XML</span><span>报表设计的所有</span><span>band</span><span>中都是可用的,并且总是返回一个</span><span>java.lang.Boolean</span><span>对象或着</span><span>null</span><span>。</span></p><p><span> </span></p><p><span> 7.1 Main Report Sections</span></p><p><span>一个最低限度的报表设计可以完全不含报表</span><span>section,</span><span>因为那些</span><span>section</span><span>中每个都是可选的,可是这样的报表设计将生成不了很好的文档。</span></p><p><img></img></p><p><span>下面我们就来认真了解每一种报表</span><span>section</span><span>:</span></p><p><span>Title</span><span> </span></p><p><span>title </span><span>段只在整个报表的第一页的最上面部分显示,除了第一页以外,不管报表中</span></p><p><span>共有多少个页面也不会再出现</span><span> Title band </span><span>中的内容。</span><span> </span></p><p><span>pageHeader</span><span> </span></p><p><span>顾名思义,</span><span>pageHeader </span><span>段中的内容将会在整个报表中的每一个页面中都</span></p><p><span>会出现,显示在位置在页面的上部,如果是报表的第一页,</span><span>pageHeader </span><span>中的内容将显示在</span></p><p><span>Title Band </span><span>下面,除了第一页以外的其他所有页面中</span><span> pageHeader</span><span>中的内容将在显示在页面的最上端。</span><span> </span></p><p><span>pageFooter</span><span> </span></p><p><span>显示在所在页面的最下端。</span><span> </span></p><p><span>Detail</span><span> </span></p><p><span>报表内容段,在这个</span><span> Band </span><span>中设计报表中需要重复出现的内容,</span><span>Detail </span><span>段中的</span></p><p><span>内容每页都会出现。</span><span> </span></p><p><span>columnHeader</span><span> </span></p><p><span>针对</span><span> Detail Band </span><span>的表头段,一般情况下在这个段中画报表的表头。</span><span> </span></p><p><span>columnFooter</span><span> </span></p><p><span>针对</span><span> Detail Band </span><span>的表尾段。</span><span> </span></p><p><span>Summary</span><span> </span></p><p><span>表格的合计段,出现在整个报表的最后一页中的</span><span> Detail band </span><span>的后面,一般用</span></p><p><span>来统计报表中某一个或某几个字段的合计值。</span></p><p><span>例子:</span></p><p><span>下面是一个测试用的报表,报表中的数据是从</span><span> Sql Server</span><span>的</span><span> pubs </span><span>数据库的</span><span> titles </span><span>表中取出的,这些数据只是用来做测试的,不代表任何意义。</span></p><p><span>设计状态的报表:</span></p><p><img></img></p><p><span>在不使用数据库数据的情况下,报表结果如下图所示:</span></p><p><img></img></p><p><img></img></p><p><span>由上面的两张图我们可以发现,除了</span><span> summary </span><span>段中的内容出现在了</span><span> detail </span><span>段的后面,其他几个</span><span> band </span><span>的位置与设计状态的位置是一样的,但是多页的话就可以看出不同了,下面是多页时的情况,注意</span><span> title band </span><span>中的内容只在第一页出现过,</span><span>summary band </span><span>中的内容只在最后一页出现过:</span><span> </span></p><p><span>多页时的第一页中的内容:</span></p><p><img></img></p><p><span> </span><span>(上图是第一页的页面上半部分内容)</span></p><p><img></img></p><p><span> </span><span>(上图是第一页的页面下半部分内容)</span></p><p></p><p><img></img></p><p><span>(上图是第二页的页面上半部分内容)</span><span> </span></p><p><span>第二页的下半部分与第一页下半部分相同,第三页的格式与第二页相同,以下图例为最后一</span></p><p><span>页的内容:</span></p><p><img></img></p><p><span> </span><span>(上图是最后一页的页面上半部分内容)</span></p><p><img></img></p><p><span> </span><span>(上图是最后一页的页面下半部分内容)</span></p><p></p><p><span>7.2 Data Grouping</span><span>(数据分组)</span></p><p><span>组是一个组织报表数据的灵活的方式,报表组代表数据源中一连串有共同点的记录。共同点比如说某个特定的报表字段的值等。</span></p><p><span>一个报表组有三个组成部分:</span></p><p><span>●</span><span> </span><span>group expression(</span><span>组表达式</span><span>)</span><span>;</span></p><p><span>●</span><span> </span><span>group header section</span><span>;</span></p><p><span>●</span><span> </span><span>group footer section</span><span>。</span></p><p><span> </span><span>组表达式的值使组的记录关联的更紧密,这个值是组中所有记录的共同点。当组表达式的值在报表的填充过程中经过数据源的迭代而发生改变时,这个组就破裂了并且对应的组的其他两个部分</span><span><groupFooter></span><span>和</span><span><groupHeader></span><span>就被插入到结果文件中。</span></p><p><span> </span><span>在一个报表上我们可以要尽可能多的报表组。因为一个组可能包含其他的组,所以在报表设计中组的声明次序是很重要的。一个组包含以下组等。如果一个包含其他组的较大的组破裂的话,则那些被被包含的组就会被重新初始化。</span></p><p><span>注意:只有在数据源中的相关记录已经依照报表中的组表达式而变得有序的时候,数据分组才会起到预期的作用。</span></p><p><img></img></p><p><span>Group Name</span><span>(组名)</span></p><p><span> </span><span>组名能精确地识别组。当你想要在其他的</span><span>XML</span><span>属性中使用到某个组时,你可以使用该组的组名。组名是强制性的并且它的命名约束与前面提到的参数、字段和变量的命名约束一样。</span></p><p><span>Starting New Page/Column When Group Breaks</span></p><p><span> </span><span>当一个新组开始时引入一个新页或新列有时是有用的,有可能是因为这个特殊的组是较重要的并且应该在它自己的页或列上开始。</span></p><p><span> </span><span>你必须设置</span><span>isStartNewPage</span><span>或</span><span>isStartNewColumn</span><span>为真来指示引擎为指定的组启动一个新页或新列,而不是在一个页或列的底部的剩余空间上来打印它。</span></p><p><span>注意:上述那两个属性是整个库中唯一能让你人为的引入页的翻动的属性。在其他的所有的情况下,报表引擎会根据需要自动的引入页的翻动。</span></p><p><span>但是,如果你不想要一直给某个组做新页或列的引入的事而只在某页或列的底部的剩余空间太小时才做页或列的列入,你可以考虑使用</span><span>minHeightToStartNewPage</span><span>属性,该属性指出了组不用启动一个属于自己的新页所要求的剩余垂直空间的最小值,该值是用像素来衡量的。</span></p><p><span>Resetting Page Number</span><span> </span></p><p><span> </span><span>如果需要的话,报表组可以重新设置记录当前页码的内置变量(变量</span><span>PAGE_NUMBER</span><span>)的值,这个可以通过设置</span><span>isResetPageNumber</span><span>属性为真来实现。</span></p><p><span>Group Header </span></p><p><span> </span><span>该部分在结果文件中标识一个新组的开始,而且每当组表达式的值通过数据源的迭代发生改变时,该部分就会被插入到文件中。</span></p><p><span>Group Footer</span></p><p><span> </span><span>每当一个报表组改变时,引擎就会在启动新组之前或报表结束时添加相关的</span><span>group footer </span><span>部分。</span></p><p></br><span>8 </span><span>脚本程序</span></p><p><span> </span><span>报表里面的内容显示是根据数据源和报表参数来确定的。我们可以通过更改报表变量和表达式来更改报表的内容。</span></p><p><span> </span><span>有时简单的报表变量并不能实现一些复杂的功能。这个时候我们就需要用到脚本程序。脚本程序在报表事件发生时执行。脚本程序可以使用报表变量,通过脚本程序可以轻易地完成修改报表内容的值。</span></p><p><span> </span><span>为了使用脚本程序,我们必须建立一个脚本类来继承下面的两个类中的一个:</span></p><p><span>dori.jasper.engine.JRAbstractScriptlet</span></p><p><span>dori.jasper.engine.JRDefaultScriptlet</span></p><p><span>我们所自定义的脚本类的名称必须在</span><span>scriptletClass</span><span>属性的</span><span><jasperReport></span><span>元素中定义过而且必须在定义</span><span>classpath</span><span>中。在填充报表是,如果在</span><span>scriptletClass</span><span>属性的</span><span><jasperReport></span><span>元素中找不到我们自定义的脚本类那么系统的引擎将默认实例化</span><span>JRDefaultScriptlet</span><span>类。</span></p><p><span>如果我们要建立脚本类,我们必须应用或重写以下的几个方法:</span><span>beforeReportInit(), afterReportInit(), beforePageInit(),afterPageInit(), beforeGroupInit(), afterGroupInit()</span><span>等等。在填充报表的某些适当时刻,就会调用相应的方法。</span></p><p><span>如果我们要建立非常复杂的报表,我们就需要复杂的报表表达式。这个时候脚本程序就会显得很有用,如某些复杂的分组或数据的显示方面。</span></p><p><span>9 </span><span>报表元素</span></p><p><span> </span><span>报表的元素基本上可分成两类:</span></p><p><span> </span><span>文本元素:静态文本、文本域(显示动态文本)</span></p><p><span> </span><span>图形元素:线、矩形、图像</span></p><p><span> </span><span>以下为这两类元素都共同有的属性:</span></p><p><span> </span><span>在定义一个报表元素的时候我们需要定义以下属性:报表的绝对位置、相对位置、尺寸、颜色等等。以下为</span><span>XML</span><span>的一些语法定义:</span></p><p><img></img></p><p><span> </span><span>绝对位置</span></p><p><span> </span><span>X</span><span>、</span><span>Y</span><span>属性是定义了报表的绝对位置(必须设定)。</span><span>X</span><span>、</span><span>Y</span><span>确定了报表的它所在区域或者父报表中左上角上的位置,以像素为标准。</span></p><p><span> </span><span>相对位置</span></p><p><span> </span><span>有些报表的元素是动态的,它的尺寸会根据具体情况来改变。所以我们在定义报表元素时可以定义报表位置时,需要定义报表相对位置,以防报表之间的尺寸改变影响报表的显示。</span></p><p><span> </span><span>我们可以通过设置</span><span>positionType</span><span>属性来设定报表的移动行为。</span></p><p><span> </span><span>positionType</span><span>有</span><span>3</span><span>种预定的属性值:</span></p><p><span> </span><span>Floating position:</span><span>元素会在所在的区域内移动,以保持它和相邻元素间的相对位置。</span></p><p><span>(positionType="Float")</span></p><p><span> Fixed position relative to the top of the parent band</span><span>:伸展的元素不会考虑到相邻的元素,它会根据它所在区域的顶端边界的相对位置来调整自己的位置,保持相对位置不变。</span></p><p><span> </span><span>Fixed position relative to the bottom of the parent band</span><span>:与上一个属性相似,不同的是以区域的底端的边界为标准。</span></p><p><span> </span><span>默认情况下会设置成第二种属性。</span></p><p><span> </span><span>元素的尺寸</span></p><p><span> </span><span>width </span><span>和</span><span> height</span><span>属性用来设置元素的尺寸,以像素为单位(必须设置)。有时候元素的尺寸不是静态的,但是改变后的尺寸大小必须大于原来的尺寸。</span></p><p><span> </span><span>元素的颜色</span></p><p><span> </span><span>有两个属性可以定义元素的颜色:</span><span>forecolor </span><span>和</span><span> backcolor</span><span>。分别是前景色和背景色。可以用十进制和十六进制来定义:</span></p><p><span> </span><span>forecolor="#FF0000"</span></p><p><span> forecolor="16711680"</span></p><p><span> </span><span>元素的透明度</span></p><p><span> </span><span>元素可以是透明或实体的。可以通过</span><span>MODE</span><span>属性来修改。</span></p><p><span> </span><span>元素的透明度属性的默认设置值各有不同。如:矩形和线的默认设置值是实体的,而静态文本和文本域是透明的。</span></p><p><span> </span><span>元素的显隐</span></p><p><span> </span><span>使用</span><span><printWhenExpression></span><span>属性可以决定元素在执行是是否会被打印或显示出来。当元素产生时,报表表达式就会返回一个</span><span>java.lang.Boolean</span><span>对象或者</span><span>NULL</span><span>值,根据这个值来决定这个元素是否要被显示或打印。</span></p><p><span> </span><span>NULL</span><span>的结果和</span><span>FALSE</span><span>是一样的,如果没有表达式,那么元素就默认被显示出来。</span></p><p><span> </span><span>元素的重复打印</span></p><p><span> </span><span>由于元素的动态伸展,有时一个区域的结束时元素还没有完全显示,我们就要开始新的一页或者一列。这是时候我们可能有需要再次打印已经打印过的元素在新的页或列中。</span></p><p><span> </span><span>我们可以通过设置</span><span>isPrintWhenDetailOverflows="true"</span><span>来实现这个功能。</span></p><p><span> </span><span>压缩重复值的显示</span></p><p><span> </span><span>让我们先看一下例子:</span></p><p><img></img></p><p><span> </span><span>在</span><span>"Family Name"</span><span>列中有很多重复的名称,我们希望达到以下效果:</span></p><p><img></img></p><p><span> </span><span>我们可以通过设置以下属性值来达到这个效果:</span></p><p><span>isPrintRepeatedValues="false"</span></p><p><span> </span><span>清除空白表格</span></p><p><span> </span><span>有时候</span><span><printWhenExpression></span><span>属性的表达式返回</span><span>FALSE</span><span>或者重复值被压缩了,报表元素并不会打印出来,这样就会留下空白的空间。我们可以通过改变设置来消除这些空白。以达到如下效果:</span></p><p><span> </span><span>一共有三个元素:</span></p><p><img></img></p><p><span> </span><span>第二个元素没有被打印出来,留下空白:</span></p><p><img></img></p><p><span> </span><span>消除空白空间:</span></p><p><img></img></p><p><span> </span><span>想要达到以上效果必须设置属性</span><span>isRemoveLineWhenBlank="true"</span></p><p><span> </span><span>有时某些情况并不能达到这样的效果,如:</span></p><p><img></img></p><p><span> </span><span>这样的情况下,空白空间将不能被消除。</span></p><p><span>9.1 </span><span>文本元素</span></p><p><span>上面已经介绍了有两种文本元素:静态文本、文本域</span></p><p><span>静态文本所要显示的内容是固定的,静态的内容;在填充报表的时候内容不会动态的改变。文本域则是动态的,在填充报表时,它的内容会根据相关报表表达式的返回值改变。</span></p><p><span>这两种元素有一些共同的属性:可以在</span><span><textElement></span><span>中设置。</span></p><p><img></img></p><p><span>文本的对齐</span></p><p><span>可以通过</span><span>textAlignment</span><span>属性来设置对其方式。有以下设定值:</span><span>"Left", "Center", "Right" or "Justified".</span></p><p><span>文本的行间距</span></p><p><span>可以用属性</span><span>lineSpacing</span><span>来设定行间距:</span></p><p><span>Single:</span><span>行间距和一行文本的高度一致。</span><span>(lineSpacing="Single").</span></p><p><span>1.5 Lines:</span><span>文本高度的</span><span>1.5</span><span>倍</span><span>(lineSpacing="1_1_2").</span></p><p><span>Double:</span><span>文本高度的</span><span>2</span><span>倍</span><span>(lineSpacing="Double").</span></p><p><span> </span><span>8.1.1</span><span> </span><span>字体、字码</span></p><p><span>每个文本元素都必须有自己的字体设置,我们可以在</span><span><font></span><span>标签内修改字体的设置。</span></p><p><span>报表字体</span></p><p><span>报表字体是一系列声明之后的字体和设置可以在整个报表的设置中重复运用。</span></p><p><img></img></p><p><span>报表字体名称</span></p><p><span>报表字体的名称可以在</span><span><reportFont></span><span>中设置,字体的名称必须是唯一的,否则将在报表的其它处引用字体是造成混乱。</span></p><p><span>默认的报表字体</span></p><p><span>我们可以在设置某一个字体的时候把,它的属性</span><span>isDefault="true"</span><span>设置为</span><span>true</span><span>。当我们的报表元素在定义是并没有指明它要引用的字体时,它就会使用我们刚才设置的那种字体,做为它的默认字体设置。</span></p><p><span>其它的报表字体的设置属性和字体的设置(下图中的属性)属性是一样的。</span></p><p><img></img></p><p><span>引用一个报表字体</span></p><p><span> </span><span>当我们设置报表字体时,我们经常会设置一种字体会元素所使用的默认字体。</span></p><p><span> </span><span>如果我们</span><span><font></span><span>元素中的属性设置只是为了在被</span><span>reportFont</span><span>使用而重写的。例如以下</span><span>reportFont</span><span>就对</span><span><font></span><span>元素中的属性进行了重写:</span></p><p><img></img></p><p><span> </span><span>如果我们要建立一个文本域,这个文本域要使用</span><span>reportFont</span><span>中设置的这种字体。而且我们又想对其中的某些属性进行修改,下面的例子介绍了我们如何针对某个个别的报表元素来修改属于它的字体:</span></p><p><img></img></p><p><span> </span><span>字体名称</span></p><p><span> </span><span>在</span><span>java</span><span>中有两种类型的字体:物理上的字体和逻辑字体。在</span><span><font> </span><span>元素或者</span><span> <reportFont> </span><span>元素的字体名称设置必须是物理字体的名称。</span></p><p><span> </span><span>物理字体:</span><span>Arial, Time, Helvetica, Courier</span><span>等等;它们都是在</span><span>java</span><span>的字体库中已经定义的字体。</span></p><p><span> </span><span>字体尺寸</span></p><p><span> </span><span>我们可以在</span><span>size</span><span>属性中设置字体的大小。</span></p><p><span> </span><span>字体的样式和修饰</span></p><p><span> </span><span>我们可以在</span><span><font></span><span>和</span><span><reportFont></span><span>元素中来设置字体的样式和修饰。通过以下属性值:</span><span>isBold, isItalic, isUnderline and isStrikeThrough</span><span>等等。</span></p><p><span> </span><span>PDF</span><span>字体名称</span></p><p><span> </span><span>当导出格式为</span><span>PDF</span><span>时,</span><span>JasperReports</span><span>库会使用</span><span>iText</span><span>库。</span></p><p><span> </span><span>PDF</span><span>文件需要在很多个平台上查看,为了确保</span><span>PDF</span><span>文件在各个平台上查看时都是一样的。</span><span>PDF</span><span>必须使用自身内部使用的字体库或者我们在</span><span>JasperRerport</span><span>上设置的字体必须在查看</span><span>PDF</span><span>文件的平台的</span><span>TTF</span><span>文件中找到。</span></p><p><span> </span><span>以下为</span><span>PDF</span><span>内置的字体:</span></p><p><img></img></p><p><span> </span><span>PDF</span><span>的编码</span></p><p><span> </span><span>如果我们建立的报表使用了很多中语言而且需要以</span><span>PDF</span><span>的格式导出,我们需要有相应的符号编码类型。以下为</span><span>PDF</span><span>的一些编码类型:</span></p><p><img></img></p><p><span>PDF</span><span>内嵌字体</span></p><p><span>我们可以把属性</span><span>isPdfEmbedded</span><span>设置为</span><span>true</span><span>。这样我们在报表文件中使用的字体编码就会在使用</span><span>PDF</span><span>平台时装入到使用平台的</span><span>PDF</span><span>字体库中。这样就能很好地在各个平台上查看同一个</span><span>PDF</span><span>文件。</span></p><p><span> </span><span>9.1.2</span><span> </span><span>静态文本</span></p><p><span>静态文本显示的内容是固定的,它的内容不会在填充报表时改变。</span></p><p><img></img></p><p><span>我们可以通过以上的</span><span>XML</span><span>文档看出,静态文本的属性都是在填充前所解释好的。</span><span> </span><span>静态文本只有</span><span><text></span><span>标签,它用来填写静态文本内要显示的内容。</span></p><p><span> </span><span>9.1.3</span><span> </span><span>文本域</span><span> </span></p><p><span>跟静态文本不同,文本域的内容会根据报表表达式和它的数据源的不同,在填充报表的时候动态填充如相应的内容。</span></p><p><img></img></p><p><span>文本域高度的改变</span></p><p><span>文本域的内容是可以改变的,所以我们并不能确定文本域元素实际占用空间的大小;所以我们必须通过某西设置来设定,让元素的内容得以全部显示出来。</span></p><p><span>我们可以通过设置属性值</span><span>isStretchWithOverflow</span><span>为</span><span>true</span><span>,来让文本域元素在它所设定的大小小于要显示的内容时,自动伸长到可以显示全部的内容。</span></p><p><span>统计的文本域</span></p><p><span>当文本域要显示的内容要通过前面的内容来计算或者统计出来时,我们就涉及到在何时对前面的值进行计算和统计。一个共四种内设的属性值提供给我们选择:</span></p><p><span>Immediate evaluation</span><span>:每填充一个区域就计算</span><span>(evaluationTime="Now").</span></p><p><span> </span><span>End of report evaluation:</span><span>在报表填充的最后才计算这些统计值</span><span>(evaluationTime="Report")</span></p><p><span> End of page evaluation:</span><span>在每一页的结束时计算这些值</span><span>(evaluationTime="Page")</span></p><p><span> End of column evaluation:</span><span>在每一列的结束时计算这些值</span><span>(evaluationTime="Column")</span></p><p><span>End of group evaluation:</span><span>在每一组的结束时计算这些值</span><span>(evaluationTime="Group").</span></p><p><span>去除</span><span>null</span><span>值的显示</span></p><p><span> </span><span>当文本域的关联表达式返回</span><span>null</span><span>值,文本域会在它相应的文本区域中显示</span><span>null</span><span>字符样。把可以通过设置</span><span>isBlankWhenNull</span><span>属性为</span><span>true</span><span>来去除</span><span>null</span><span>字样,让该区域显示空白。</span></p><p><span> </span><span>文本域的表达式</span></p><p><span> </span><span>JasperReport</span><span>表达式只允许返回以下值:</span></p><p><img></img></p><p><span>9.2 </span><span>图形元素</span></p><p><span> </span><span>第二大类报表元素是图形元素。图形元素包括:线、矩形和图像。</span></p><p><span> </span><span>这些图像元素都以下共同的属性值可以在</span><span><graphicElement></span><span>标签中设置。</span></p><p><img></img></p><p><span> </span><span>图形元素的伸展行为</span></p><p><span> </span><span>有时候图形元素会和文本域在同一个区域内。我们知道文本域会根据表达式和数据源来改变内容,其大小也会改变。当这些文本域的大小改变时,就自然而然地影响到相邻的元素(包括图形元素),这就需要图形元素也需要一些伸展行为。我们可以通过</span><span>stretchType</span><span>属性来设置图形元素的伸展行为。</span></p><p><span> </span><span>图形元素的伸展行为一共有</span><span>3</span><span>种:</span></p><p><span>Won't stretch:</span><span>图形元素不会伸展</span><span>(strechType="NoStretch").</span></p><p><span>Stretching relative to the parent band height:</span><span>图形元素会根据它所在区域的高度来改变自己的高度。</span><span>(stretchType="RelativeToBandHeight").</span></p><p><span>Stretching relative to the tallest element in group:</span><span>图形元素会根据组内伸长最长的元素来改变自己的高度。</span><span>(stretchType="RelativeToTallestObject").</span></p><p><span> </span><span>边缘的厚度</span></p><p><span> </span><span>跟文本不一样,图形往往有一个边界;所以有时我们需要一定的厚度线条来划分这条界限。边界线的颜色可以通过</span><span>forecolor</span><span>属性来设置。</span></p><p><span> </span><span>以下为设置边界线厚度的属性设置值:</span></p><p><span> </span><span>No border: </span><span>图形元素不会画出这条边界线</span><span>(pen="None")</span></p><p><span>Thin border: </span><span>画笔的厚度为是</span><span>1Point </span><span>的一半</span><span>(pen="Thin").</span></p><p><span>1 point thick border: </span><span>画笔为</span><span>1Point (pen="1Point").</span></p><p><span>2 points thick border: </span><span>画笔为</span><span>1Point</span><span>的两倍</span><span> (pen="2Point").</span></p><p><span>4 point thick border:</span><span>画笔为</span><span>1Point</span><span>的</span><span>4</span><span>倍</span><span> (pen="4Point").</span></p><p><span>Dotted border:</span><span>画笔的厚度为</span><span>1Point </span><span>,但是会由点组成</span><span>(pen="Dotted").</span></p><p><span>默认的设置为</span><span>(pen="Thin")</span><span>。</span></p><p><span>背景色的样式</span></p><p><span>实际上背景色只有一种设置值</span><span>(fill="Solid").</span></p><p><span> </span><span>8.2.1</span><span> </span><span>线</span></p><p><span>线元素实际上是以矩形来作为基础的。它只指定了矩形的一个对角点然后通过</span><span>x</span><span>、</span><span>y, width </span><span>和</span><span> height</span><span>属性来设置这条线。</span></p><p><img></img></p><p><span> </span><span>线的方向</span></p><p><span> </span><span>一共两个对角线方向:一个是从矩形左顶端到右下端,</span><span>direction="TopDown"</span><span>。</span></p><p><span>一个是从矩形左下端到右上端,</span><span>direction="BottomUp"</span><span>。默认的方向为:</span><span>TopDown</span></p><p><span> </span><span>如果我们要画水平线,我们可以设</span><span>width="0"</span><span>。</span></p><p><span> </span><span>如果我们要画垂直线,我们可以设</span><span>height="0"</span><span>。</span></p><p><span> </span><span>9.2.2</span><span> </span><span>矩形</span></p><p><span> </span><span>矩形是最基本的元素,所以矩形的属性也是最基本的;除了我们在</span><span><reportElement> </span><span>和</span><span> <graphicElement></span><span>标签中定义的属性之外,就没有别的附加属性了。</span></p><p><img></img></p><p><span> </span><span>9.2.3</span><span> </span><span>图像</span><span> </span><span> </span></p><p><span> </span><span>图像是最复杂的图形元素。</span></p><p><span> </span><span>图像元素也跟文本域一样,它的内容也会根据它的关联表达式在运行时才会被填充。</span></p><p><img></img></p><p><span> </span><span>图像的缩放</span></p><p><span> </span><span>图像元素跟文本域一样,都无法预先获知它所占的区域大小。所以我们需通过某些设置来确保或改变图像的显示。</span><span>scaleImage</span><span>属性就提供了几种图像大小改变时所要执行的动作。</span></p><p><span>它一共有</span><span>3</span><span>种设定值:</span></p><p><span> </span><span>Clipping the image:</span><span>如果图像的大小大于它之前所分配区域的大小,那么将切除超出区域的图像部分。</span><span>(scaleImage="Clip")</span></p><p><span> Forcing the image size:</span><span>如果图像的大小小于它所分配的区域,那么它将改变自己的形状来填充满整个区域。</span><span>(scaleImage="FillFrame").</span></p><p><span> Keeping image proportions:</span><span>如果区域大小和图像的大小不等,那么图像会缩放自己,以保持图像在区域内显示的是本身的比例。</span></p><p><img></img></p><p><span>图像的存储</span></p><p><span> </span><span>图像没有特别的静态元素来保持静态的图像,不想文本一样,文本有专门的静态文本元素来保持文本。然而有些图像实际上是静态的,它不需要根据表达式和数据源来获取,它可以直接从硬盘上或其它地方获取。</span></p><p><span> </span><span>如果我们要重复地显示一张静态的图像在每一页或者每一列的标题上,实际上我们并不需要每一次都从硬盘上去读取这样图像。我们可以把这种图像存储起来,然后重复应用。</span></p><p><span> </span><span>要达到上述效果,我们必须设置</span><span>isUsingCache</span><span>属性为</span><span>true</span><span>。这样当填充报表时遇到图像的名称或者</span><span>URL</span><span>与之前用过的图像的一样就直接把之前保持的图像填充到报表中。</span></p><p><span> </span><span>这个存储功能只能使用于那些图像元素,它的表达式返回值是</span><span>java.lang.String</span><span>对象,这些对象代表着图像的名称或者</span><span>URL</span><span>或者</span><span>classpath</span><span>资源。</span></p><p><span> </span><span>统计图像</span></p><p><span> </span><span>统计的图像和之前文本域中介绍的类似。有些图像元素需要根据之前的图像元素来计算出自己的值或图形。</span><span>evaluationTime</span><span>属性可以用来控制计算的时间。一共有五种属性:</span></p><p><span> </span><span>Immediate evaluation:</span><span>立即计算出图像当前表达式</span><span>(evaluationTime="Now")</span></p><p><span> End of report evaluation:</span><span>图像表达将在报表的其它元素都填充完成时才会被计算</span><span>(evaluationTime="Report")</span><span>。</span></p><p><span> </span><span>End of page evaluation:</span><span>图像的表达将在每一页的结束时计算</span><span>(evaluationTime="Page")</span></p><p><span> End of column evaluation:</span><span>图像的表达式将在列结束时计算</span><span>(evaluationTime="Column")</span></p><p><span> End of group evaluation:</span><span>图像的表达式将在组结束时计算</span><span>(evaluationTime="Group")</span></p><p><span> </span><span>默认值为:</span><span>(evaluationTime="Now")</span></p><p><span> </span><span>图像表达式</span></p><p><span> </span><span>图像表达式的返回值将会被作为图像将要填充内容的源。返回值可以是以下类型:</span></p><p><img></img></p><p><span> </span><span>返回值是</span><span>String</span><span>时,它可以是图像的名称或者</span><span>URL</span><span>或</span><span>Classpath</span><span>,填充报表时会根据这些返回值来查找图像。</span></p><p><span> </span><span>图像表达式的返回值默认为</span><span>java.lang.String</span><span>。</span></p><p><span>9.3 </span><span>超链接</span></p><p><span>超链接元素是</span><span>JasperReport</span><span>提供给用户的一种元素,这种元素可以重定向页面的内容。重定向的目标可以是本地的一个文件或者是</span><span>WEB</span><span>上面的一个页面等等。这种报表元素是超链接元素。</span></p><p><span>超链接不仅仅是锚,因为它可以重定向到非本地资源。</span></p><p><span>文本域元素和图像元素都可以成为超链接元素。</span></p><p><img></img></p><p><span> </span><span>超链接类型</span></p><p><span> </span><span>我们可以通过</span><span>hyperlinkType</span><span>属性来设置超链接的类型。</span></p><p><span> </span><span>No hyperlink:</span><span>默认的属性设置,内容将不是以超链接的形式呈现。</span></p><p><span> </span><span>External reference:</span><span>超链接将指向一个非本地资源。这个</span><span>URL</span><span>可以在</span><span><hyperlinkReferenceExpression></span><span>中设置。</span></p><p><span> </span><span>Local anchor:</span><span>超链接指向一个本地的锚,这个锚须在</span><span><hyperlinkAnchorExpression></span><span>中定义。</span></p><p><span> </span><span>Local page:</span><span>超链接将指向报表的一页,它将根据页面的</span><span>index</span><span>来确定。页面的</span><span>index</span><span>在</span><span><hyperlinkPageExpression></span><span>中定义。</span></p><p><span> </span><span>Remote anchor:</span><span>超链接将指向一个外部的锚,锚在</span><span><hyperlinkAnchorExpression></span><span>里面说明,而外链接在</span><span><hyperlinkReferenceExpression></span><span>中说明。】</span></p><p><span> </span><span>Remote page:</span><span>超链接将指向外部的一个页面,页面的</span><span>index</span><span>在</span><span><hyperlinkPageExpression></span><span>里面说明,而外链接在</span><span><hyperlinkReferenceExpression></span><span>中说明。</span></p><p><span> </span><span>锚表达式</span></p><p><span> </span><span>如果一个文本域或者一个图像在属性</span><span><anchorNameExpression></span><span>将其设置为锚,那么锚的指向将根据锚表达式的返回值来决定。表达式的返回值是</span><span>java.lang.String</span><span>对象。</span></p><p><span> </span><span>超链接表达式</span></p><p><span> </span><span>超链接表达式的返回值是用来计算出超链接的指向的。有三种超链接表达式,它们功能组成最后的结果。</span></p><p><span> </span><span><hyperlinkReferenceExpression></span></p><p><span><hyperlinkAnchorExpression></span></p><p><span><hyperlinkPageExpression></span></p><p><span>前两个表达式返回类型为:</span><span>java.lang.String</span></p><p><span>最后那个表达式返回类型为:</span><span>java.lang.Integer</span></p><p><span>9.4 </span><span>元素组</span></p><p><span>我们可以让一系列元素合为一组。合成元素组的内的元素当遇到元素尺寸上调整时,可以容易得实现整个组的调整。</span></p><p><img></img></p><p><span>10 </span><span>子报表</span></p><p><span> </span><span>子报表是制作报表的有力工具。运用子报表可以制作出功能复杂、多样式,适合多种需求的报表。</span></p><p><span> </span><span>子报表实际上也不是一个报表,它不过是在令一个报表的一个区域中显示而已。子报表也可以拥有自己的子报表。</span></p><p><span> </span><span>因为子报表也是一个普通的报表,所以它的大部分属性我们已经介绍过了。运用子报表必须使用</span><span><subreport></span><span>元素。</span></p><p><img></img></p><p><span> </span><span>子报表表达式</span></p><p><span> </span><span>子报表表达式在执行时被计算出来,根据返回值可以获得</span><span>dori.jasper.engine.JasperReport</span><span>对象。</span></p><p><span> </span><span>子报表表达式的返回类型有以下:</span></p><p><span>java.lang.String</span></p><p><span>java.io.File</span></p><p><span>java.net.URL</span></p><p><span>java.io.InputStream</span></p><p><span>dori.jasper.engine.JasperReport</span></p><p><span>临时存储的子报表</span></p><p><span>跟图形元素一样,当要显示同一个子报表时,我们大可不必要去每次都硬盘上或其它地方获取子报表。如果我们要填充的子报表的名称或</span><span>URL</span><span>与之前的子报表相同,我们就直接之前保持的子报表填充到父报表中。我们可以设置属性值</span><span>isUsingCache</span><span>为</span><span>ture</span><span>来实现这个功能。</span></p><p><span>这个存储功能只能使用于那些子报表元素,它的表达式返回值是</span><span>java.lang.String</span><span>对象,这些对象代表着子报表的名称或者</span><span>URL</span><span>或者</span><span>classpath</span><span>资源。</span></p><p><span>10.1 </span><span>子报表参数</span></p><p><span>由于子报表也是报表所以它也需要数据源和参数来提供它自己要填充的数据。子报表在提供参数除了一般报表提供的方法外,还可以在</span><span><subreportParameter></span><span>元素中提供你想要的参数。在</span><span><subreportParameter></span><span>中定义参数需要一个一个地输入你想要的参数;输入的参数名必须与定义的参数名相对应,而且需要自己为每个参数提供它的表达式。算出来的参数将为填充子报表时从数据源提供数据。</span></p><p><span>我们可是使用之前我们在报表参数时所提供参数的方法提供参数,也可以运用</span><span><subreportParameter></span><span>来提供参数。当我们同时运用两种方法来提供参数时,第二种方法提供的参数会重写第一种方法所提供的参数。</span></p><p><span>10.2 </span><span>子报表数据源</span></p><p><span>子报表也需要数据源来提供给子报表填充的数据,这跟普通报表是一样的。我们也有两种方式来提供给子报表数据源:直接提供给子报表一个数据源对象;提供给子报表一个链接字符串,然后根据这跟链接字符串来获取数据源对象。当然我们也可以使用一个</span><span>SQL</span><span>语句来提取数据源中的数据,这跟普通报表是一样的。</span></p><p><span>我们可以在</span><span><dataSourceExpression></span><span>元素内直接提供给子报表一个数据源对象,或者在</span><span><connectionExpression></span><span>元素内提供给子报表一个数据源的链接字符串。这两种方式在一个时刻只能使用一种,这样才不会在填充数据时造成混乱。</span></p><p><span>在使用两种获取数据源的方式时,第一种需要输入的是</span><span>dori.jasper.engine.JRDataSource</span><span>对象,而第二种则是希望返回一个</span><span>java.sql.Connnection</span><span>对象。</span></p><p><span>11 </span><span>高级</span><span>JasperReports</span><span>应用</span></p><p><span> </span><span>如果我们要设计一些更加复杂的报表,那么我们就有可能用到一些高级的应用。例如</span><span>XML</span><span>报表的导入和设计,实例化数据源接口,自定义查看器,导出新的格式等。</span></p><p><span>11.1 XML</span><span>报表的导入和设计</span></p><p><span>JasperReport</span><span>引擎会解析</span><span>XML</span><span>报表设计文件,然后直接对它进行一些测试,然后编译成</span><span>dori.jasper.engine.JasperReport</span><span>对象。</span></p><p><span>有时我们希望能够自己设计和导入</span><span>XML</span><span>报表设计文件,而不需要直接编译。</span></p><p><span>我们可以使用一个静态的方法</span><span>load()</span><span>(这个方法在</span><span>dori.jasper.engine.xml.JRXmlLoader</span><span>里面定义,并暴露出来)从</span><span>XML</span><span>报表设计文件中导入</span><span>dori.jasper.engine.design.JasperDesign</span><span>对象。这样我们就能从文件中或着输入流中获取</span><span>XML</span><span>文件并导入报表设计对象。</span></p><p><span>11.2 </span><span>实例化数据源接口</span></p><p><span>JasperReport</span><span>会采用几个默认的方法来实例化</span><span>dori.jasper.engine.JRDataSource</span><span>接口。这个接口定义了我们要填充报表时所以填充的数据源。</span></p><p><span>这种默认的实例化</span><span>dori.jasper.engine.JRDataSource</span><span>接口,会定义我们所要填充的相关数据源必须是符合一定的结构的,如果我们要让一些具有特别结构的的数据填充到我们的报表中来,我们就必须自己实例化</span><span>dori.jasper.engine.JRDataSource</span><span>接口。这样当我们使用特殊结构的数据源时</span><span>JasperReport</span><span>就能够读懂我们的数据源。</span></p><p><span>11.3 </span><span>自定义查看器</span></p><p><span>JasperReport</span><span>使用默认的查看器,当我们最终显示报表或者预览报表时都使用的是默认的查看器。</span></p><p><span>这些查看器都是从以下两个类中继承而来:</span></p><p><span>dori.jasper.view.JasperViewer :</span><span>这个类是用来查看已经生成的报表。</span></p><p><span>dori.jasper.view.JasperDesignViewer :</span><span>这个类是用来预览报表设计的。</span></p><p><span>当然</span><span>JasperReport</span><span>使用的默认查看器并不一定会符合所有人的需要,所以如果有时我们必须定义自己的查看器。</span></p><p><span>如果我们要定义我们自己的查看器,我们就必须继承</span><span>ori.jasper.view.JRHyperlinkListener</span><span>接口,实现接口中的方法。</span></p><p><span>11.4</span><span>导出新的格式</span></p><p><span>JasperReport</span><span>有一些预定义的导出格式,如:</span><span>PDF, HTML </span><span>和</span><span> XML</span><span>。为了提供给用户不</span></p><p><span> </span><span>不同的导出格式,</span><span>JasperReport</span><span>也提供了一些接口给用户加以实例化,然后实现用户自定义的导出格式。</span></p><p><span> </span><span> </span><span>我们必须自己实例化</span><span>ori.jasper.engine.JRExporter</span><span>接口,然后设置一样相应的参数和重写和使用一系列的方法。</span></p><p></p><p></p> <script type="text/javascript">s();</script> <div id="bdleft"> <script type="text/javascript">s();</script> </div> <div> <script type="text/javascript">s();</script> </div> </div> <style> .ls-radius-btn { border-radius: 3px; } .ls-blue-white-btn { background-color: #fff; border: 1px solid #3395f6; } .line-h-2-6 { line-height: 2.6; } .ls-h-huge-padding { padding-left: 30px; padding-right: 30px; } .display-i-block { display: inline-block; } </style> <div class="gradient-mask" id="gradientMask" style="padding-top: 20px;padding-bottom: 20px;" align="center"> <a class="ls-radius-btn ls-blue-white-btn ls-h-huge-padding line-h-2-6 display-i-block" id="readAll">阅读全文</a> </div> <script> //阅读全部 $('#readAll').click(function () { $('#contents').removeClass('hid-section'); $('#gradientMask').hide() }); </script> <div class="answer_content"> <div></div> </div> </div> <div class="down"> <h3> <img src="/Public/Home/images/save.png" alt="免费下载" border="0" align="absmiddle" /> Word文档免费下载: <a href="javascript:void(0);" title="Jasperreport和iReport详细功能介绍" id="download_id2">Jasperreport和iReport详细功能介绍</a> </h3> </div> <div class="about"> <h2> <a href="#">TOP</a>热门搜索 </h2> <ul class="clearfix"> <li><a href="/content/id/18ea529ff08583d049649b6648d7c1c709a10b3a" title="婚前房产公证书样本" target="_blank">婚前房产公证书样本</a></li> <li><a href="/content/id/d2b998db905f804d2b160b4e767f5acfa0c7833e" title="高中地理会考知识点总结" target="_blank">高中地理会考知识点总结</a></li> <li><a href="/content/id/b307e7e04b649b6648d7c1c708a1284ac85005e3" title="六年级上册语文教案少年闰土4人教新课标" target="_blank">六年级上册语文教案少年闰土4人教新课标</a></li> <li><a href="/content/id/250e052405a1b0717fd5360cba1aa81145318fec" title="绿色世纪特许经营招商书最新修正版" target="_blank">绿色世纪特许经营招商书最新修正版</a></li> <li><a href="/content/id/99c0e77a1b37f111f18583d049649b6649d70921" title="[优质]2.部编人教版五年级上语文:快乐读书吧教案" target="_blank">[优质]2.部编人教版五年级上语文:快乐读书吧教案</a></li> <li><a href="/content/id/b1278b04112de2bd960590c69ec3d5bbfd0adaaa" title="建国大业观后感" target="_blank">建国大业观后感</a></li> <li><a href="/content/id/4c31c87127fff705cc1755270722192e453658e2" title="铭记、感恩,再出发! - 2019年高考全国卷三作文简要解析(附范文)" target="_blank">铭记、感恩,再出发! - 2019年高考全国卷三作文简要解析(附范文)</a></li> <li><a href="/content/id/bc39761da76e58fafab003c1" title="目前国内国际主流GIS平台软件对比" target="_blank">目前国内国际主流GIS平台软件对比</a></li> <li><a href="/content/id/576aa9b0a7c30c22590102020740be1e640ecc77" title="苏教版语文二年级下册《闪光的金子》课件4" target="_blank">苏教版语文二年级下册《闪光的金子》课件4</a></li> <li><a href="/content/id/3bdbafd4970590c69ec3d5bbfd0a79563d1ed40e" title="幼儿园教案格式模板" target="_blank">幼儿园教案格式模板</a></li> </ul> </div> </div> <div class="category"> <div class="ad_d"> <script type="text/javascript">s();</script> </div> <h2 class="navname"> 相关推荐: </h2> <ul class="lista"> <p><a href="/content/id/09c88ec7b34e852458fb770bf78a6529647d357f" title="统编人教2019版必修中外历史纲要上册高中人教版新教材第1课中华文明的起源与早期国" target="_blank">统编人教2019版必修中外历史纲要上册高中人教版新教材第1课中华文明的起源与早期国</a></p> <p><a href="/content/id/b9aff1f3a800b52acfc789eb172ded630b1c98c4" title="广东省深圳市布吉中学九年级数学上期中测试题(无答案) 北师大版" target="_blank">广东省深圳市布吉中学九年级数学上期中测试题(无答案) 北师大版</a></p> <p><a href="/content/id/c65414e9854769eae009581b6bd97f192379bf3c" title="苏教版2019年英语六年级上册期中试卷-六年级英语试题" target="_blank">苏教版2019年英语六年级上册期中试卷-六年级英语试题</a></p> <p><a href="/content/id/fd190924ecfdc8d376eeaeaad1f34693daef101c" title="KPI绩效考核管理办法" target="_blank">KPI绩效考核管理办法</a></p> <p><a href="/content/id/dd27415e1cb91a37f111f18583d049649b660ec6" title="爱的早晨六年级精选作文" target="_blank">爱的早晨六年级精选作文</a></p> <p><a href="/content/id/2f81953bd1d233d4b14e852458fb770bf78a3b99" title="最新口语交际《应对》教案设计" target="_blank">最新口语交际《应对》教案设计</a></p> <p><a href="/content/id/4becff65f68a6529647d27284b73f242336c31d4" title="在行程问题的学习中渗透数学建模的思想" target="_blank">在行程问题的学习中渗透数学建模的思想</a></p> <p><a href="/content/id/b6ac6152370cba1aa8114431b90d6c85ed3a8835" title="关于几个法定时间在招投标实践中的应用" target="_blank">关于几个法定时间在招投标实践中的应用</a></p> <p><a href="/content/id/889fe2c0f08583d049649b6648d7c1c709a10b28" title="电视谈话节目的品牌生存策略观" target="_blank">电视谈话节目的品牌生存策略观</a></p> <p><a href="/content/id/adcf5e78988fcc22bcd126fff705cc1754275fd1" title="建筑工人安全常识" target="_blank">建筑工人安全常识</a></p> </ul> <div class="ad_d"> <script type="text/javascript">s();</script> </div> <h2 class="navname"> <a href="/tag/t/武陵山上的星光观后感">武陵山上的星光观后感</a> </h2> <ul class="lista"> <p><a href="/content/id/9857d8fca22d7375a417866fb84ae45c3a35c211" title="《武陵山上的星光》观后感10篇" target="_blank">《武陵山上的星光》观后感10篇</a></p> <p><a href="/content/id/bd592d6328f90242a8956bec0975f46527d3a7f7" title="《武陵山上的星光》观后感心得体会精选五篇" target="_blank">《武陵山上的星光》观后感心得体会精选五篇</a></p> <p><a href="/content/id/8273bc050042a8956bec0975f46527d3250ca60a" title="《武陵山上的星光》观后感" target="_blank">《武陵山上的星光》观后感</a></p> <p><a href="/content/id/0ef1a8ff7dd5360cba1aa8114431b90d6c85898f" title="观看《武陵山上的星光》观后感范文1000字三篇_图文" target="_blank">观看《武陵山上的星光》观后感范文1000字三篇_图文</a></p> <p><a href="/content/id/5012dfc4cebff121dd36a32d7375a417876fc1c5" title="《武陵山上星光》电影观后感范本" target="_blank">《武陵山上星光》电影观后感范本</a></p> <p><a href="/content/id/cd816651951ea76e58fafab069dc5022abea4670" title="观看《武陵山上的星光》观后感范文1000字三篇" target="_blank">观看《武陵山上的星光》观后感范文1000字三篇</a></p> <p><a href="/content/id/fdf9d6e66e85ec3a87c24028915f804d2a1687e5" title="武陵山上的星光观后感(最新)" target="_blank">武陵山上的星光观后感(最新)</a></p> <p><a href="/content/id/0230ed496a0203d8ce2f0066f5335a8103d266c6" title="《武陵山上的星光》电影观后感范文_图文" target="_blank">《武陵山上的星光》电影观后感范文_图文</a></p> <p><a href="/content/id/e0e0ea399b8fcc22bcd126fff705cc1754275fc4" title="武陵山上的星光 观后感_图文" target="_blank">武陵山上的星光 观后感_图文</a></p> <p><a href="/content/id/04f15afd5beef8c75fbfc77da26925c52dc59125" title="《武陵山上的星光》观后感2篇_图文" target="_blank">《武陵山上的星光》观后感2篇_图文</a></p> <p><a href="/content/id/e26f7bdb846fb84ae45c3b3567ec102de2bddfb6" title="武陵山上的星光上映-武陵山上的星光观后感_图文" target="_blank">武陵山上的星光上映-武陵山上的星光观后感_图文</a></p> <p><a href="/content/id/9514f1f45afb770bf78a6529647d27284a73377b" title="最新团委书记《武陵山上的星光》观后感" target="_blank">最新团委书记《武陵山上的星光》观后感</a></p> <p><a href="/content/id/258a7782e65c3b3567ec102de2bd960591c6d9ff" title="2021年党员《武陵山上星光》观后感" target="_blank">2021年党员《武陵山上星光》观后感</a></p> <p><a href="/content/id/0f39e62a504de518964bcf84b9d528ea80c72ffd" title="电影《无问西东》观后感.doc_图文" target="_blank">电影《无问西东》观后感.doc_图文</a></p> <p><a href="/content/id/659a5b3dbb0d4a7302768e9951e79b896902686e" title="观李玫瑾家庭教育有感2篇" target="_blank">观李玫瑾家庭教育有感2篇</a></p> <p><a href="/content/id/ed06a446a48da0116c175f0e7cd184254b351b94" title="单位主题教育总结汇报材料" target="_blank">单位主题教育总结汇报材料</a></p> <p><a href="/content/id/d68509f7814d2b160b4e767f5acfa1c7ab008207" title="在主题教育总结会上的讲话材料" target="_blank">在主题教育总结会上的讲话材料</a></p> <p><a href="/content/id/80c24d50e73a580216fc700abb68a98270feace0" title="主题教育总结报告2020_主题教育总结报告-最新合集_图文" target="_blank">主题教育总结报告2020_主题教育总结报告-最新合集_图文</a></p> <p><a href="/content/id/ef744c0bb72acfc789eb172ded630b1c59ee9bee" title="单位开展主题教育特色亮点总结汇报" target="_blank">单位开展主题教育特色亮点总结汇报</a></p> <p><a href="/content/id/22e5507d4b649b6648d7c1c708a1284ac950055f" title="2020年主题教育总结报告_图文" target="_blank">2020年主题教育总结报告_图文</a></p> </ul> </div> </div> <!-- huiyuan--start --> <div class="info_mask"></div> <div class="charging_box"> <div class="charging_box_c"> <div class="banner_bg"> <div class="closed_b fr" onclick="guanbi();"> <img src="/Public/Home/user/images/closed_p.png" alt="" /> </div> <div class="clear"> </div> <div class="member_n"> <dl> </dl> </div> </div> </div> <div class="option"> <ul id="zhengchang_viplist"> <li class="active v_pay_item" v="2"> <div> <span> <p> <i>¥</i>29.8 </p> <del> ¥45 </del> <u> 每天只需1.0元 </u> </span> </div> <em> <i>1个月</i> </em> <strong> 推荐 </strong> </li> <li class="v_pay_item" v="1"> <div> <span> <p> <i>¥</i>9.9 </p> <del> ¥15 </del> </span> </div> <em> <i>1天</i> </em> </li> <li class="v_pay_item" v="3"> <div> <span> <p> <i>¥</i>59.8 </p> <del> ¥90 </del> </span> </div> <em> <i>3个月</i> </em> </li> </ul> </div> <div class="pay"> <h3> 选择支付方式 </h3> <ul> <li class="active" v="1"> <img src="/Public/Home/user/images/wechat.png" /> <span> 微信付款 </span> </li> </ul> <input type="hidden" name="hidbuytype" id="hidbuytype" value="2" /> <input type="hidden" name="hidpaytype" id="hidpaytype" value="1" /> <input type="button" onclick="submitbuy('67ed39adec3a87c24128c40c')" value="立即支付" id="input_submitbuy" /> </div> <div class="a_box"> <a href="#" target="_blank"> 会员须知 </a> <a href="#" target="_blank"> 联系在线客服 </a> <span id="concat"> <a href="/login/login" target="_blank" class="denglu">登录账号</a> </span> </div> <div class="pupop_small"> 郑重提醒:支付后,系统自动为您完成注册 </div> </div> <div class="wxpay_area" id="wxpay"> <div class="closed fr"> <a onclick="hidewxpay()"> </a> </div> <div class="clear"> </div> <div class="zf_content"> <h3> 请使用微信扫码支付(元) </h3> <dl> <dd id="wxprice"> </dd> <dt> <img id="wxcode" src="" style="height:194px;width:194px;" /> </dt> </dl> <p> 订单号: <span id="wxorder"> </span> <br /> 支付后,系统自动为您完成注册 <br /> 遇到问题请联系 <a href="#" target="_blank"> 在线客服 </a> </p> </div> </div> <div class="finish" id="paySuccess" style="display:none;"> <div class="fin_mask"> </div> <div class="fin_con"> <img src="/Public/Home/user/images/ts_colse.png" class="ts_close" alt="" onclick="hidepayS()"> <div class="fin_top"> <div class="fin_top_con"> <img src="/Public/Home/user/images/confirm.png" class="top_bg" alt=""> <p class="fin_top_p"> <span class="top_span"> 恭喜您 ! </span> <br> <span class="top_span"> 购买会员成功 </span> </p> </div> </div> <div class="fin_account"> <div class="fin_form"> <p class="fin_form_p"> <span class="fin_form_s"> 账 号 </span> <span class="fin_form_t" id="uname"> </span> </p> <p class="fin_form_p"> <span class="fin_form_s"> 密 码 </span> <span class="fin_form_t" id="userpwd"> </span> </p> </div> </div> <p class="fin_btn"> <!-- <a class="fin_btn_edit" onclick="updatepwd()" style="cursor:pointer;"> 绑定手机 </a> --> <a href="/user/orderlist" target="_blank" class="fin_btn_edit" style="cursor:pointer;"> 绑定手机 </a> <a href="javascript:void(0);" target="_blank" class="fin_btn_save" onclick="hidepayS()"> 保存账号 </a> <!-- <a href="/user/orderlist" target="_blank" class="fin_btn_save"> 自动登录 </a> --> </p> <p class="fin_tips"> 温馨提示:请截图保存您的账户信息,以方便日后登录使用。 </p> </div> </div> <div class="account_number" id="updatepwd"> <div class="closed fr"> <a onclick="hideuppwd()"> </a> </div> <div class="h10"> </div> <div class="modify_password"> <dl> <dd> 常用手机号: </dd> <dt> <input name="txtEmail" type="text" id="txtEmail" class="modify_input" /> </dt> <dd> <span class="remind_p"> 用于找回密码 </span> </dd> </dl> <dl> <dd> 图片验证码: </dd> <dt> <input name="txtVerify4" type="text" id="txtVerify4" class="modify_input" style="width:120px" autocomplete="off" onfocus="checktxtNew(this)" onblur="checktxtsNew(this,0)" maxlength="4" placeholder="请输入计算结果" /> <a class="comput"> <img class="vcimg" id="imgVerify4" style="height:40px;vertical-align:bottom;" src="" alt="看不清?点击更换" onclick="this.src=this.src+'?'" /> </a> </dt> </dl> <dl> <dd> 短信验证码: </dd> <dt> <input name="smsCode3" type="text" id="smsCode3" class="modify_input" style="width:120px" onfocus="checktxtNew(this)" onblur="checktxtsNew(this,1)" maxlength="6" placeholder="请输入手机验证码" /> <input type="button" id="btnSenSMS3" value="获取验证码" class="get_yzm" style="height: 40px;line-height: 40px;width: 111px;border: 1px solid #ccc;" /> </dt> </dl> <dl> <dd> 新密码: </dd> <dt> <input name="txt_newPwd" type="password" id="txt_newPwd" class="modify_input" /> </dt> </dl> <dl> <dd>   </dd> <dt> <input id="Button6" type="button" class="modify_btn" onclick="checkuppwd()" value="确认绑定" /> </dt> <dd style="width:180px;"> <span class="remind_p"> 绑定后可用手机号登录 </span> </dd> </dl> </div> </div> <div class="account_number" id="alipay" style="height: 180px;"> <div class="complete_p"> <dl> <dd style="font-size: 16px;"> 请不要关闭本页面,支付完成后请点击【支付完成】按钮 </dd> </dl> <ul style="width: 300px;"> <li> <input type="button" class="cha_btn" value="支付完成" onclick="ajaxstatus(0)" /> </li> <li> <input type="button" class="cha_btn" style="background:#999;" value="取消支付" onclick="location.reload();" /> </li> </ul> <div class="clear"> </div> <dl> <dd style="font-size: 12px; color: #333;"> 遇到问题请联系 <a href="#" target="_blank"> 在线客服 </a> </dd> </dl> </div> </div> <!-- 底部 --> <!-- huiyuan-end --> <div class="footer"> <p> <a href="#" target="_blank">侵权投诉</a>  © 2013-2019 http://www.tcm999.cn   <a href="/sitemap.html">站点地图</a> |  <a href="http://m.tcm999.cn">手机版</a> <script type="text/javascript">tj();</script> </p> <p>本站文档均来自互联网及网友上传分享,本站只负责收集和整理,有任何问题可通过上访投诉通道进行反馈</p> </div> </div> <script type="text/javascript"> //$(".charging_box").css("display","block"); //$("#wxpay").css("display","block"); //判断用户是否登录,如果已经登录并且处于会员期内,则显示全部答案;否则显示弹窗要求付费 var username=""; var user_vip=""; var user_vip_time=""; //alert(user_vip_time); var now_time="1714904126"; //alert(now_time); //alert(user_vip_time); //alert(parseInt(user_vip_time)>parseInt(now_time)); //alert(username); if(username && user_vip=='1' && (parseInt(user_vip_time)>parseInt(now_time))){ //if(1){ //$(".answer_content").css("display","block"); //$(".s_mess2_m").html(""); //$(".answer_content").html("<img style='float:left' src='/Public/Home/images/doc.gif'><strong>该篇</strong>,全文共有个字。聪明文档网为全国文档知名网站,下载全文稍作修改便可使用,即刻完成写稿任务。下载全文:<a href='' class='zjbtn' id='zjbtn'>下载word文档!</a>"); //设置顶部下载链接 //$("#download_id").attr("href",""); //如果已经登录下,则对登录账号进行充值,否则自动生成随机账号发给用户 }else{ //$(".answer_content").html("<img style='float:left' src='/Public/Home/images/doc.gif'><strong>该篇</strong>,全文共有个字。聪明文档网为全国文档知名网站,下载全文稍作修改便可使用,即刻完成写稿任务。下载全文:<a class='zjbtn' id='zjbtn'>下载word文档</a>"); //$("#zjbtn").click(function(){ //$(".charging_box").css("display","block"); //$('.info_mask').show(); //}); //复制文字功能 document.body.oncopy=function(){ $(".charging_box").css("display","block"); $('.info_mask').show(); } //a链接下载点击弹窗 //$("#download_id").click(function(){ //$(".charging_box").css("display","block"); //$('.info_mask').show(); //}); } //***点击效果 //点击效果,获取金额 $(".v_pay_item").click(function(){ /*点击效果*/ $(".v_pay_item").removeClass("active"); $(this).addClass("active"); /*赋值购买方式123*/ $("#hidbuytype").val($(this).attr("v")); /*获取金额*/ //var money=$(this).find(".v_item_price span").text();//获取点击金额 //$(".vip_price span").text(money);//将金额放到底部订单金额: /*获取有效期*/ //var effective_time=$(this).find(".v_item_expire").text();//获取 //$(".vip_effective_time").text(effective_time);//赋值 //alert(effective_time); }); //点击效果end //***函数调用 //关闭大窗口 function guanbi() { $(".charging_box").css("display","none"); $('.info_mask').hide(); } //关闭付款窗口 function hidewxpay() { var qq = ''; if (confirm("如您已完成付款,请不要关闭本页面,耐心等待系统为您分配账号。如长时间未完成分配,请联系客服。")) { $('.info_mask').hide(); $("#wxpay").hide(); } } //关闭账号窗口 function hidepayS() { //$("#paySuccess").css("display","none"); //location.href = "/67ed39adec3a87c24128c40c.html"; window.open("/content/id/67ed39adec3a87c24128c40c"); } //查询订单是否支付成功,id是用户手机号,order订单号 var flags = 0; function ajaxstatus(id,order,money) { var askid = "67ed39adec3a87c24128c40c"; if (flags == 0) { $.ajax({ url: "/Ajax/weixin_pay_ok?type=2&id=" + askid + "&buyid=" + id +'&order='+ order+'&money='+money + '&t=' + new Date().getTime(), type: "GET", dataType: "text", data: "", success: function(data) { if (data == 1 || data == 2) { location.href = "/content/id/" + askid; } else if (data == 0) { } else { flags = 1; $("#uname").html(data.split('|')[0]); $("#userpwd").html(data.split('|')[1]); $('#alipay').hide(); $('#wxpay').hide(); //$(".zda_win").hide(); $('#paySuccess').show(); $(".info_mask").show(); } }, error: function() { //alert("请求订单状态出错"); } }); } } //立即支付 function submitbuy(id) { //hidebuymember(0); var buytype = $("#hidbuytype").val(); var paytype = $("#hidpaytype").val(); //alert(buytype); //alert(paytype); if (paytype == 1) { $.ajax({ url: "/Ajax/weixin_pay?id=" + id + "&type=0&buytype=" + buytype + '&t=' + new Date().getTime(), type: "GET", dataType: "text", success: function(data) { if (data == 2) { alert("您已经开通了会员,不需要重复开通"); window.location.href = "//www.tcm999.cn/content/id/" + id; } else { //alert(data); $(".charging_box").css("display","none"); var winHeight = $(window).height(); if (winHeight < 388) { $("#wxpay").css("top", "0"); } else { $("#wxpay").css("top", (winHeight - 388) / 2 + "px"); } $('#wxpay').show(); $(".info_mask").show(); var s = data.split('|'); $("#wxorder").html(s[1]); $("#wxprice").html(s[2]); $("#wxcode").attr("src", s[3]); setInterval("ajaxstatus('"+s[0]+"','"+s[1]+"','"+s[2]+"')", 3000); //setInterval("ajaxstatus('18695793071','123')", 1000); //setInterval("ajaxstatus(" + s[0] + ")", 1000); } }, error: function() { //alert("请求订单状态出错"); } }); } } </script> <script> //判断字符是否为空的方法 function isEmpty(obj){ if(typeof obj == "undefined" || obj == null || obj == ""){ return true; }else{ return false; } } /******文档下载业务******/ /*1、完成下载功能*/ //获取用户昵称 var username=""; //alert(username); //获取laiyuanid var id="67ed39adec3a87c24128c40c"; //alert(id); //拼接url var url="/k/doc/"+id+".html"; //alert(url); //没有付费下载时文章内容底部的显示 $(".answer_content").html("<img style='float:left' src='/Public/Home/images/doc.gif'><strong>该篇</strong>,全文共有94277个字。聪明文档网为全国文档知名网站,下载全文稍作修改便可使用,即刻完成写稿任务。下载全文:<a class='zjbtn' id='zjbtn'>下载word文档</a>"); //下载word公用方法 function downloadWord(){ /*2、完成付费下载功能*/ //判断用户是否登录 //未登录 if(isEmpty(username)){ alert("请登录"); //附带来源地址 window.open("/login/login?sourceUrl="+window.location.pathname); //已登录 }else{ /*判断当前用户下载币是否剩余*/ //获取当前用户下载币 var user_downcurrency=""; //user_downcurrency=1; //console.log(user_downcurrency); //alert(user_downcurrency); //return false; //充值下载币入库失败下载扣币失败,先做后面 //未充值 if(isEmpty(user_downcurrency) || user_downcurrency<=0){ //提示充值 alert("请充值"); window.open("/user/userdeposit"); //已充值 }else{ var downConfirm=confirm("下载本文档扣除10个下载币"); if(downConfirm==true){ $.ajax({ url: "//www.dyhzdl.cn/wenkucms/index.php/Home/index/ajaxGetWenku", type: "POST", data: {url:url}, dataType:"text", //缓存true/false //cache: false, success: function (data) { //console.log(data); //alert(data); var download_url=data; //alert(download_url); //$(".jhcdown").attr('href',download_url); //$('.jhcdown').trigger("click"); window.location.href = download_url; } }); //下载完成后进行下载币扣币10币 $.ajax({ url: "/ajaxdown/ajaxDecDownCurrency", type: "POST", data: {url:id,title:document.title}, dataType:"json", //缓存true/false //cache: false, success: function (data) { //console.log(data); } }); } } } } //a链接下载点击弹窗 $("#download_id").click(function(){ downloadWord(); }); $("#download_id2").click(function(){ downloadWord(); }); $("#download_id3").click(function(){ downloadWord(); }); $("#zjbtn").click(function(){ downloadWord(); }); </script> </body> </html>