===================2005-08-24======================
Class dori.jasper.engine.JasperExportManager,这个类里面包含了各种函数,处理来自不同源来的数据,并转化为各种不同的形式来输出 。
Class dori.jasper.engine.JasperRunManager,有时候如果只需要产生一种格式的文档,比如PDF,那么就不需要将由报表填充进程产生的中间形式的dori.jasper.egine.JasperPrint类型的对象,
存储在硬盘上。这个类可以完成将由报表填充进程产生的文档直接输出为需要的形式。
在webapp这个例子中,有这种形式。
Class dori.jasper.view.JRViewer,是一个可视化的组件,用来在Swing based applications显示JasperReports library产生的报表。
通过由dori.jasper.engine.JasperPrintManager类产生一个java.awt.Image类型的对象。
Class dori.jasper.view.JasperViewer,这是一个示例教学模式(didactical)的类,利用dori.jasper.view.JRViewer组件来显示例子。
Class dori.jasper.view.JasperDesignViewer,这个是在设计时用来预览模版的,可以用来方便调试。
Class dori.jasper.engine.util.JRLoader,所有JasperReports的主进程,比如报表编译、报表填充、报表输出,都要用到一种序列化(serialized)的对象,
有的时候,可能想在提交的相应的处理进程之前,手动加载这些序列化的对象。这个类可以从不同的源,如文件、Url、以及输入流中加载序列化的对象。
其中有一个loadObjectFromLocation(String location)函数,当我们利用这个函数从一个位置来加载一个对象的时候,首先会试图将这个位置解析为一个Url,
如果没有,则解析成File,如果fail,则从classpath中寻找一个相应的资源,如果还没有,那就只好抛出异常啦。
===Main Tasks and Processes
In this chapter we shall see what you have to know in order to parse your XML report designs, compile
them, fill them with data, view them, print them, or export them to other formats.总之,这里是主要的部分啦 !
XML Parsing
JasperReports利用SAX 2.0 API来解析(parse)XML文件,但是并没有指定要用特定的解析器,只要是实现了SAX 2.0 API接口的解析器都可以 ,可以在运行时(runtime)指定要使用的解析器。
为了启动(instantiate)解析进程,JasperReports利用rg.xml.sax.helpers.XMLReaderFactory里的一个createXMLReader()方法。
这就需要在运行时,给SAX指定org.xml.sax.driver的java 系统属性。(it will be necessary at runtime to set the org.xml.sax.driver Java system property to
the full class name of the SAX driver)
有两种方法可以完成这个工作,我们这里会利用Xerces XML parser来示例。
第一种方法是在用在命令行时用-D开关,例如
java -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser MySAXAppsample.xml
在所有的例子中,我们使用了ANT命令来完成,我们在配置文件中用<sysproperty>指定了JVM的系统属性:
<sysproperty key="org.xml.sax.driver" value="org.apache.xerces.parsers.SAXParser"/>
第二种方法是利用:java.lang.System.setProperty(String key, String value)函数
System.setProperty("org.xml.sax.driver","org.apache.xerces.parsers.SAXParser");
在webapp下的 jsp/compile.jsp and WEB-INF/classes/servlets/CompileServlet.java 文件中有例子。
Compiling Report Designs
为了生成一个报表,必须要先建立一个report's design,可以通过编辑一个xml文件或者编程建立一个dori.jasper.engine.design.JasperDesign类型的对象。
在这里我们主要用XML的方式来做。
XML report designs是要来产生报表的未加工的材料(raw material),因为xml的内容必须经过解析并被装载到一个dori.jasper.engine.design.JasperDesign类型的对象里
才能被报表引擎填入数据。
报表编译过程的主要目的是产生并装载包含所有报表表达式(expressions)的类的字节编码(bytecodes),这个动态建立的类在填充报表的时候用来评估报表表达式。
但是在生成这个类之前,会检查报表设计(report design)的一致性(consistency)。
有三个很重要的方面:
temporary working directory;
Java compiler used;
classpath
为了编译包含所有表达式的类,需要一个temporary working directory,当编译完成以后,这些文件(.class)会被删除,而产生的字节编码被存储在一个dori.jasper.engine.JasperReport类型的对象里,
这个对象可以自己序列化或者可以存储在硬盘上(如果需要的话)
这个默认的路径是JVM的路径,可以很方便的改变,利用给系统属性jasper.reports.compile.temp赋值改变。
第二方面是编译器,首先会寻找sun.tools.javac.Mainclass来解析,这样的前提是在JDK的lib目录下有tools.jar文件,并把它copy到JasperReports的lib下。如果失败了,则用javac.exe
通常来说,编译一个report之需要简单的调用dori.jasper.engine.JasperCompileManager.compileReport(myXmlFileName);就可以了,会的得到一个.jasper结尾的文件,位置在myXmlFileName相同的位置下。
Report Design Preview
有一个dori.jasper.view.JasperDesigner可以完成显示的功能,可以以想要的形式显示。
在所提供的例子里面的在build.xml中,都指定了这个view来显示,然后再利用ant编译的时候,会根据这个编译。“TODO:以后要仔细研究一下build.xml”
实际上,在每个report里面ant有两个任务,viewDesign and viewDesignXML,viewDesign用来装载编译过的.jasper的文件,viewDesignXML用来加载xml report design,
这样可以修改xml之后,点击reload就可以立即看到改变。
>ant viewDesignXML
or
>ant viewDesign
Filling Reports
是JasperReports最重要的功能啦,有三个重要事情必须要做来做为报表填充数据的输入:
report design (report template);
parameters;
data source.
输出是一个单个的文件,已经可以view了。
我们要使用dori.jasper.engine.JasperFillManager来填充数据,有各种函数,可以让我们来填充存储在硬盘上的report design,或者输入流,或者是在内存中的
dori.jasper.engine.JasperReport类型的对象。输出一般和输入是同一个类型的。
有可能这些方法还不够,例如可能想要从classpath中的resources来读入一个report design,然后输出到一个在硬盘上的文档中。
在这种情况下,必须要考虑在把report design交给report filling routines之前先装载,利用dori.jasper.engine.util.JRLoader类,这种方式,可以接收一些
报表设计属性,例如报表名称之类的,这样就可以按着名称来产生相应的输出文档。
报表参数值是以一个java.util.Map类型的对象来传递的,其中的key是参数的名称。
关于数据源方面,有两种情况:
通常情况下是对于dori.jasper.engine.JRDataSource接口类型的实例交互,dori.jasper.engine.JasperFillManager这个Facade中有一系列的方法,来从dori.jasper.engine.JRDataSource类型的对象中得到数据。
还有一种情况是接收一个java.sql.Connection类型的对象,在这种情况下,其实还是在后台会有一个dori.jasper.engine.JRDataSource 类型的对象,不过这事自动的,透明的。
在例子中的jasper, query, scriptlet and subreport都是这种数据填充的例子,数据库是HSQL,首先要启动HSQL,方法是在/demo/hsqldb目录下,
用>ant
or
>ant runServer命令
填充数据的例子:
//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());
Viewing Reports
报表填充过程的输出是一个dori.jasper.engine.JasperPrint类型的对象,如果存储在硬盘上,将是一个.jrprint的文件。
dori.jasper.view.JRViewer可以用来显示,而且用户可以继承这个类来实现自己的东西。在webapp的例子中,JRViewerPlus加入了一个新的button。
Printing Reports
dori.jasper.engine.JasperPrintManager用来是实现打印的功能,里面有各种方法,比如打印全部,打印一页,按选择打印等,并且可以选择是否出现打印窗口等。
打印整页,不要打印窗口:dori.jasper.engine.JasperPrintManager.printReport(myReport, false);
打印5-11页:dori.jasper.engine.JasperPrintManager.printPages(myReport, 4, 10, true);
Exporting Reports
将文档转化为需要的格式:有一个Facade,dori.jasper.engine.JasperExportmanager类。
输入的对象是一个dori.jasper.engine.JasperPrint类型的。想要转化为现在这里没有的类型,要实现一个dori.jasper.engine.JRExporter接口,或者继承dori.jasper.engine.JRAbstractExporte类。
现在library里面有三个输出类,分别产生PDF,HTML和XML,它们的位置在dori.jasper.engine.export包下,但是可以用Facade manager 里面适当的方法来调用。
输出到html格式:dori.jasper.engine.JasperExportManager.exportReportToHtmlFile(myReport);
Object Loading and Saving
可能有需要要手动的添加序列化的对象,两个常用的类dori.jasper.engine.util.JRLoader和dori.jasper.engine.util.JRSaver.
dori.jasper.engine.util.JRSaver可以用来序列化对象并把它们放到文件中,或者将它们通过输出流将它们输出到网络。
它所加载的是已经生成的report或者已经被输出为xml格式的最终的JasperReports文档。和上一个读取序列化的文档不同,这个是要解析xml内容,并建立一个dori.jasper.engine.JasperPrint类型的副本。
这个可以通过dori.jasper.engine.xml.JRPrintXmlLoader类来实现,里面有静态的方法通过解析xml内容可以建立in-memory document objects。
==Report Designs
通常,Report design 是通过一个XML文档来实现的,要以特定的格式来写。然后再装数据之前,提交到JasperReports的编译程序来处理。
但是它们也可以在运行时被创建,通过JasperReports API.有一个例子noxmldesign,演示了如果建立in-memory report designs,而不写xml文档。
DTD Reference
JasperReports用自己内建的DTD文件,如果要用外部的DTD,则要更改dori.jasper.engine.xml.JRXmlDigester 类。只有两个合法的DTD,如下:
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN"
"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
or
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN"
"http://www.jasperreports.com/dtds/jasperreport.dtd">
开始的标签是<jasperReport>,看起来是这个样子:
<?xml version="1.0"?>
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN"
"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<jasperReport name="name_of_the_report" ... >
...
</jasperReports>
XML Encoding
默认是UTF-8,对大多数的西方字体,用的是<?xml version="1.0" encoding="ISO-8859-1"?>,更多的字体,要查看XML documentation. FIXME
Report Properties
XML Syntax
<!ELEMENT jasperReport (reportFont*, parameter*, queryString?, field*,
variable*, group*, title?, pageHeader?, columnHeader?, detail?,
columnFooter?, pageFooter?, summary?)>
<!ATTLIST jasperReport
name NMTOKEN #REQUIRED
columnCount NMTOKEN "1"
printOrder (Vertical | Horizontal) "Vertical"
pageWidth NMTOKEN "595"
pageHeight NMTOKEN "842"
orientation (Portrait | Landscape) "Portrait"
whenNoDataType (NoPages | BlankPage | AllSectionsNoDetail) "NoPages"
columnWidth NMTOKEN "555"
columnSpacing NMTOKEN "0"
leftMargin NMTOKEN "20"
rightMargin NMTOKEN "20"
topMargin NMTOKEN "30"
bottomMargin NMTOKEN "30"
isTitleNewPage (true | false) "false"
isSummaryNewPage (true | false) "false"
scriptletClass NMTOKEN #IMPLIED
>
Report Name:名字
Column Count:可以在一页里面建立多个列,默认是一列
Print Order:在多于一列的页里,指明列的填充顺序是很重要的。有两种可能:Vertical filling----指的是从上到下、从左到右;Horizontal filling----指的是从左到右、从上到下
Page Size:里面有两个用来定义页面尺寸的pageWidth和pageHeight,默认的是A4纸的大小。
Page Orientation:Portrait和Landscape形式,分别指的是竖式和横式,默认是竖式的。jasperReports 要求自己更改Page Size,例如:
pageWidth="595" pageHeight="842" orientation="Portrait"转到pageWidth="842" pageHeight="595" orientation="Landscape"
在报表填充进程中并不去看orientation字段,只是看pageWidth和pageHeight。orientation只在发送给打印机的时候有用。
Page Margins:有四个属性,topMargin, leftMargin,bottomMargin, rightMargin 默认的是Top和Bottom是30个pixels,Left和Right是20个pixels
Column Size and Spacing:因为可以有多列,所以要指定每个列的宽度和列间的距离columnWidth and columnSpacing。
Empty Data Source Behavior:因为数据是从数据库中读出来的,而有可能数据库中并没有数据,whenNoDataType用来指定没有数据时处理。
Empty document:whenNoDataType="NoPages" ;Blank page:whenNoDataType="BlankPage" ;All sections displayed:whenNoDataType="AllSectionsNoDetail" ;
Title and Summary Sections Placement:如果想要标题或者汇总单页,就设定这里的属性isTitleNewPage和isSummaryNewPage为“ture”
Scriptlet Class:指定处理这页的scriptlet的类的名字,如果没有指定这个属性的值,则自动调用一个dori.jasper.engine.JRDefaultScriptlet类的实例
==Report Data
报表填充进程的输入是:report design,参数值,数据源
Expressions
Expressions是JasperReports的一个非常强大的特性,它们可以用来声明报表变量来进行各种计算,进行数据分组,指定text field内容或者配置报表上对象的外观等
基本上,所有的报表Expressions都是Java Expressions,按着特定的格式它们可以引用(reference)report parameters, report fields和 report variables等
在XML的report design里,有很多定义Expressions的元素,例如<variableExpression>, <initialValueExpression>, <groupExpression>,
<printWhenExpression>, <imageExpression>, <textFieldExpression>等
因为所有的JasperReports expressions 都是真正的java expressions,所以可以在任何的类里面使用,使用的时候要带上完整的路径。
Report parameter references是用$P{} 例如:
<textFieldExpression>
$P{ReportTitle}
</textFieldExpression>
这个例子假设我们在Report design 里定义了一个名为ReportTitle的参数,类是java.lang.String,这个text field在report 被填充的时候会显示这个参数的值。
report field reference是用$F{} 例如:
<textFieldExpression>
$F{FirstName} + " " + $F{LastName}
</textFieldExpression>
还可以更复杂,如:
<textFieldExpression>
$F{FirstName} + " " + $F{LastName} + " was hired on " +
(new SimpleDateFormat("MM/dd/yyyy")).format($F{HireDate}) + "."
</textFieldExpression>
report variable reference是用$V{} 例如:
<textFieldExpression>
"Total quantity : " + $V{QuantitySum} + " kg."
</textFieldExpression>
还可以在expression上调用方法,例如,得到第一个字符:
<textFieldExpression>
$F{FirstName}.substring(0, 1)
</textFieldExpression>
Parameters
参数是传送给报表填充进程的对象引用,在给报表engine 那些它不能从数据库中得到的信息时非常有用,例如启动这个报表的用户名,
以及动态生成标题等等。
XML Syntax
<!ELEMENT parameter (parameterDescription?, defaultValueExpression?)>
<!ATTLIST parameter
name NMTOKEN #REQUIRED
class NMTOKEN #REQUIRED
isForPrompting (true | false) "true"
>
<!ELEMENT parameterDescription (#PCDATA)>
<!ELEMENT defaultValueExpression (#PCDATA)>
定义一个变量很简单:<parameter name="ReportTitle" class="java.lang.String"/>只要指定其名称和类就可以了
Parameter Name
Parameter Class
Prompting for Parameter Values,在报表出来之前,可能会要用户输入一些信息,然后根据这些信息来生成报表,所有就有了isForPrompting这个属性,
然后再<parameterDescription>里面指定一些信息,例如:
<parameter name="Comments" class="java.lang.String" isForPrompting="true">
<parameterDesciption>
<![CDATA[
Please type here the report comments if any
]]>
</parameterDesciption>
</parameter>
Parameter Default Value
参数值是通过java.util.Map类型的对象传递给报表填充进程的,如果不给某个Key赋值,那么默认的null,但是如果想给默认的值的话,
可以用来指定<defaultValueExpression>,例如:
<parameter name="MyDate" class="java.util.Date">
<defaultValueExpression>
new java.util.Date()
</defaultValueExpression>
</parameter>
Built-in Report Parameters
Parameter REPORT_PARAMETERS_MAP,这个built-in parameter会一直指向用户传递的java.util.Map类型的对象,这个在想子报表使用一些父报表的参数的时候很有用。
Parameter REPORT_CONNECTION,指向一个java.sql.Connection类型的对象,这个对象是用户传递给engine的来通过JDBC执行SQL查询;只有在report真的收到了一个
用来填充数据的java.sql.Connection而且不是一个dori.jasper.engine.JRDataSource实例的时候,才不为空。否则是空的。这个也是在子报表中很有用。
Parameter REPORT_DATASOURCE,指向数据填充时用的数据源。
Parameter REPORT_SCRIPTLET,即使不用scriplet的时候,也指向一个Parameter REPORT_SCRIPTLET的实例;但当用到了scriplet的时候,则指向在数据填充时的scriptlet classs实例,
在scriptlet例子中有介绍,可以用来调用特定的方法、复制或使用在数据填充时scriplet准备的数据。
Data Source
在填充数据时,JasperReport递代数据,dori.jasper.engine.JRDataSource接口很简单,要继承它的话,只要实现两个方法,
public boolean next() throws JRException;和public Object getFieldValue(JRField jrField) throws JRException;
从数据源得到数据的唯一方法是通过“report fields”。dori.jasper.engine.JRDataSource有很多实现,下面来分别看看:
Class dori.jasper.engine.JRResultSetDataSource,用来包装java.sql.ResultSet类型的对象。在例子like jasper, scriptlet, subreport and query中可以看到。
通常是自动调用的,当要手动的时候,还要自己包装一个java.sql.ResultSet类型的对象,用一个数据源类的实例,在数据填充之前。
在使用这种类型的数据源时,最重要的一点是要对ResultSet中的每一个列都声明一个report field,并且report field的名字和类型都要和ResultSet中的相同。
“这样好像是错误的!!!:为了最大的可能性,可以对数据库中的每个列都对应声明一个report field”
Class dori.jasper.engine.JREmptyDataSource,前面提过,例如fonts, images, shapes and unicod等都需要
Class dori.jasper.engine.data.JRTableModelDataSource,用来包装javax.swing.table.TableModel类型的对象。有两种方法来使用这种对象,
通常要从它得到数据,要声明对javax.swing.table.TableModel对象里面的每个列都声明一个report field。另一种方法是利用index,例如知道要取得数据在index=2的位置,
则可以用"COLUMN_2"来访问,在datasource中有例子。
Class dori.jasper.engine.data.JRBeanArrayDataSource,包装an array of JavaBeans,然后利用reflection来取得report field值,
一个JavaBean代表这种数据源的一条记录,例如有一个report field名字是"ProductDescription",那么在取得值的时候,程序会默认的调用getProductDescription()来取得它的值。
如果是boolean的值,则还可以调用is前缀。在datasource例子里也有。
Class dori.jasper.engine.data.JRBeanCollectionDataSource,这个和前一个很类似,但是它包装的是java.util.Collection类型的对象。
Report Query
为了填充报表,我们要给reporting engine提供报表数据,或者至少告诉他该怎么取得我们要的数据。通常是要接收到一个dori.jasper.engine.JRDataSource类型的对象,但是也支持JDBC的SQL查询。
<queryString>,这个字段出现在报表参数之后,report fields之前。
XML Syntax
<!ELEMENT queryString (#PCDATA)>
例如:<queryString><![CDATA[SELECT * FROM Orders]]></queryString>
一个很重要的方面是报表参数在这里的应用,例如:
第一种方式是参数像普通的java.sql.PreparedStatement一样使用,规范是:
<queryString>
<!CDATA[
SELECT * FROM Orders WHERE OrderID <= $P{MaxOrderID} ORDER BY ShipCountry
]]>
</queryString>
第二种方式是将一条查询语句作为一个参数传递过来,例如:
<queryString>
<!CDATA[
SELECT * FROM $P!{MyTable} ORDER BY $P!{OrderByClause}
]]>
</queryString>
这样就要求再交给java.sql.PreparedStatemen之前,将参数解析出来。<queryString>$P!{MySQLQuery}</queryString>
jasper, subreport, scriptlet, and webapp use internal SQL有例子
Fields
XML Syntax
<!ELEMENT field (fieldDescription?)>
<!ATTLIST field
name NMTOKEN #REQUIRED
class (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.String) "java.lang.String"
>
<!ELEMENT fieldDescription (#PCDATA)>
例如:
ColumnName DataType Length
EmployeeID int 4
LastName varchar 50
FirstName varchar 50
HireDate datetime 8
相应应该声明的report fields 如下:
<field name="EmployeeID" class="java.lang.Integer"/>
<field name="LastName" class="java.lang.String"/>
<field name="FirstName" class="java.lang.String"/>
<field name="HireDate" class="java.util.Date"/>
Field Class包含的类型有: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类型,当数据源是custom made data sources时,要用这种类型。
有一个附加的属性<fieldDesciption>,这个有时会很有用处,你可以在里面存储key等任何需要的信息,以便在runtime从custom data source取得值,例如:
<field name="PersonName" class="java.lang.String" isForPrompting="true">
<fieldDesciption>PERSON NAME</fieldDesciption>
</field>
Variables
是在report expression建立的一种特殊的对象,可以用来简化报表设计,比如只声明一此次频繁使用的expression,或者在相应expression的上实现个各种各样的计算。
XML Syntax
<!ELEMENT variable (variableExpression?, initialValueExpression?)>
<!ATTLIST variable
name NMTOKEN #REQUIRED
class NMTOKEN "java.lang.String"
resetType (None | Report | Page | Column | Group) "Report"
resetGroup CDATA #IMPLIED
calculation (Nothing | Count | Sum | Average | Lowest | Highest |
StandardDeviation | Variance | System) "Nothing"
>
<!ELEMENT variableExpression (#PCDATA)>
<!ELEMENT initialValueExpression (#PCDATA)>
变量声明的位置很重要,后声明的可以引用先声明的。
Variable Name
Variable Class
Reset Type,来指示在报表填充进程中,这个变量的重新加载特性,有五个级别:
There are 5 reset types for a variable:
No Reset: The variable will never be initialized using its initial value expression and will only
contain values obtain by evaluating the variable's expression (resetType="None").
Report Level Reset: The variable is initialized only once, at the beginning of the report filling
process, with the value returned by the variable's initial value expression
(resetType="Report").
Page Level Reset: The variable is reinitialized at the beginning of each new page
(resetType="Page").
Column Level Reset: The variable is reinitialized at the beginning of each new column
(resetType="Column").
Group Level Reset: The variable is reinitialized every time the group specified by the resetGroup
attributes breaks (resetType="Group").
默认的是 resetType="Report".
Reset Group
Calculations
变量可以按着它们相应的表达式的值来实现内建式的计算,类型有:
Calculation Nothing,表示数据源的每次迭代变量都要进行重新加载,只是简单的根据变量的表达式得到值。
Calculation Count,
Calculation Sum
Calculation Average
Calculation Lowest and Highest
Calculation StandardDeviation and Variance
Calculation System
“TODO:具体的各个的含义还要再细看 P36”
例子:这个例子中的每页汇总
<variable name="QuantitySum" class="java.lang.Double" resetType="Page"
calculation="Sum">
<variableExpression>$F{Quantity}</variableExpression>
<initialValueExpression>new Double(0)</initialValueExpression>
</variable>
Built-in Report Variables
一些系统内建的变量,
Variable PAGE_NUMBER,用它可以得到当前的页号,在完成是还可以得到总的页号(利用evaluationTime)。
Variable COLUMN_NUMBER,
Variable REPORT_COUNT,记录的总数
Variable PAGE_COUNT,当页的记录总数
Variable COLUMN_COUNT,当前列的记录总数
Variable COLUMN_COUNT,当声明了一个组的时候,则会自动的声明一个,用来计算当前组的记录数
==Report Sections
建立一个report design的时候,我们需要定义内容和格式,格式的限定是由下面的定义的<title>, <pageHeader>,<columnHeader>, <groupHeader>,
<detail>, <groupFooter>, <columnFoter>,<pageFooter>, <summary>,当定义格式时,用<band>。
XML Syntax
<!ELEMENT band (printWhenExpression?, (line | rectangle | image | staticText
| textField | subreport | elementGroup)*)>
<!ATTLIST band
height NMTOKEN "0"
>
<!ELEMENT printWhenExpression (#PCDATA)>
Band Height,制定这个band 的高度,如果发现对象超过这个高度,则编译时会有报警信息。
Skipping Bands,“TODO:不清楚”
Main Report Sections
XML Syntax
<!ELEMENT title (band?)>
<!ELEMENT pageHeader (band?)>
<!ELEMENT columnHeader (band?)>
<!ELEMENT detail (band?)>
<!ELEMENT columnFooter (band?)>
<!ELEMENT pageFooter (band?)>
<!ELEMENT summary (band?)>
Title,要在page header section之前加载,要是想page header section在title section 之前被加载出来,则需要在title section开始之前,
将page header section 中的elements也都拷贝过来,这样他们就可以利用<printWhenExpression>在第一页上suppress真正的page header section,
当然这要有PAGE_NUMBER的支持。
Page Header
This section appears at the top of each page in the generated document.
Column Header
This section appears at the top of each column in the generated document.
Detail
For each record in the data source, the engine will try to generate this section.
Column Footer
This section appears at the bottom of each column in the generated document. It never stretches
downward to acquire the content of its containing text fields and will always remain of declared fixed
height.
Page Footer
This section appears at the bottom of each page in the generated document. Just like the column footer
section above, the page footer never stretches downwards to acquire the content of its containing text
fields and will always remain of declared fixed height.
Summary
This section is generated only once per report and appears at the end of the generated document, but is
not necessarily the last section being generated.
That's because in some cases, the column footer or/and page footer of the last page can follow it.
As mentioned in the 4.3 Report Properties paragraph, the summary section can start a new page of its
own, by setting the isSummaryNewPage attribute to "true". Even if this attribute remains false, the
summary section always starts a new page if it does not fit on the remaining space of the last page or if
the report has more than one column and on the last page it has already started a second column.
If the main report sections that we have seen here are not sufficient for what you need, maybe you
should consider introducing supplementary sections like group headers and group footers.
We are now going to see how to group data on the report.
Data Grouping
group report 有三个组件:
group expression;
group header section;
group footer section.
当group expression的值在报表填充时,随着数据库的迭代而变化时,将会有一个group rupture产生,相应的<groupFooter> and <groupHeader>会变化。
值得注意的是,所有用来group的应该是已经经过排序的数据,因为jasperReport 并不进行排序。
XML Syntax
<!ELEMENT group (groupExpression?, groupHeader?, groupFooter?)>
<!ATTLIST group
name NMTOKEN #REQUIRED
isStartNewColumn (true | false) "false"
isStartNewPage (true | false) "false"
isResetPageNumber (true | false) "false"
isReprintHeaderOnEachPage (true | false) "false"
minHeightToStartNewPage NMTOKEN "0"
>
<!ELEMENT groupExpression (#PCDATA)>
<!ELEMENT groupHeader (band?)>
<!ELEMENT groupFooter (band?)>
Group Name,没什么多说的
Starting New Page/Column When Group Breaks,有时用来产生一个新页或者列断点,通常是因为新的组更重要,要在一个自己的页或列上开始。
要开始新的,或者要对isStartNewPage或isStartNewColumn设置为true。
如果你不想总是设置这种,而只是想在页的底部不够大的时候,才产生新页,则要用minHeightToStartNewPage,这个指定不开始新的一页的最小vertical。
Resetting Page Number,如果需要,report groups可以重设内置的variable PAGE_NUMBER,方法是将isResetPageNumber设为true。
Group Header,这部分是用来在结果文档中标记一个新组的开始的 ,在数据库的迭代中,每当group expression发生变化的时候都要被插入文档那个中。
Group Footer,每当一个report group变化时,都在开始一个新group或者报表结束之前加入一个group footer section
例子在:like jasper, datasource or query,中
==Scriptlets
所有显示数据都是来自report parameters 和 the report fields的,有很多变量的值是在运行时指定的,或者是在特定的时刻,比如重组一页等等。
JasperReports允许在它初始化报表变量之前或之后执行一段用户代码,根据他们的reset type: Report, Page, Column or Group.
为了要实现这种功能,用户要实现下面的两个类中的一个dori.jasper.engine.JRAbstractScriptlet或dori.jasper.engine.JRDefaultScriptlet
在<jasperReport>下的scriptletClass中完整的类路径要被指定,当用户建立自己的Scriptlet时,一些方法必须实现,例如beforeReportInit(), afterReportInit(), beforePageInit(),
afterPageInit(), beforeGroupInit(), afterGroupInit(),这些方法会在填充报表时在适当的时候被调用。对于一些复杂的应用,可以考虑建立一个类,然后建立简单的变量来掉用它们。
而Scriptlets也可以做这样的事情,有一个内置的REPORT_SCRIPTLET。具体的例子在scriptlet中。
==Report Elements
有两种形式:
Text elements: static texts and text fields that display dynamic content;
Graphic elements: lines, rectangles and images.
首先说一些通用的东西:包含在<reportElement>之内
XML Syntax
<!ELEMENT reportElement (printWhenExpression?)>
<!ATTLIST reportElement
positionType (Float | FixRelativeToTop | FixRelativeToBottom)
"FixRelativeToTop"
isPrintRepeatedValues (true | false) "true"
mode (Opaque | Transparent) #IMPLIED
x NMTOKEN #REQUIRED
y NMTOKEN #REQUIRED
width NMTOKEN #REQUIRED
height NMTOKEN #REQUIRED
isRemoveLineWhenBlank (true | false) "false"
isPrintInFirstWholeBand (true | false) "false"
isPrintWhenDetailOverflows (true | false) "false"
printWhenGroupChanges CDATA #IMPLIED
forecolor CDATA #IMPLIED
backcolor CDATA #IMPLIED
>
<!ELEMENT printWhenExpression (#PCDATA)>
Absolute Position,由X,Y坐标指定的位置,相对于左上角的位置。
Relative Position,有一些报表元素,例如文本域有一个特别属性,可以使他们向下延伸来显示所有的信息,这样就会影响到下面元素的显示。有三个选择,
Floating position: The element will float in its parent section if it is pushed downwards by other
elements fount above it. It will try to conserve the distance between it and the neighboring
elements placed immediately above (positionType="Float").
Fixed position relative to the top of the parent band: The current report element will simply ignore
what happens to the other section elements and tries to conserve the y offset measured from the top
of its parent report section (positionType="FixRelativeToTop").
Fixed position relative to the bottom of the parent band: If the height of the parent report section is
affected by elements that stretch, the current element will try to conserve the original distance
between its bottom margin and the bottom of the band
(positionType="FixRelativeToBottom").
可以参看stretch例子。
Element Size,原大小
Element Color,有forecolor 和backcolor.
Element Transparency,透明与否,mode指定。
Skipping Element Display,<printWhenExpression>”TODO:不懂”
Reprinting Elements on Section Overflows,因为可能地方不够了,所以要用新的一页来显示,用isPrintWhenDetailOverflows="true"来设定那些要在下一些中重画的。
Suppressing Repeating Values Display,用来设定重复的内容的显示,isPrintRepeatedValues="false",则只显示一次。当然这都是在<printWhenExpression>不存在的情况下的。
用isPrintInFirstWholeBand="true",可是保证在每一个新页上都可以显示,如果是重复的值跨越几个组的话可以用printWhenGroupChanges
Removing Blank Space,为指定的单元设置isRemoveLineWhenBlank="true"属性,则当没有值得时候就移除了。
然后是一些对每种元素不同的设置
Text Elements,有两种类型的文本元素,static texts 和text fields,第一种的内容不会变,而第二种在运行时决定内容。
由<textElement>指定其属性
XML Syntax
<!ELEMENT textElement (font?)>
<!ATTLIST textElement
textAlignment (Left | Center | Right | Justified) "Left"
lineSpacing (Single | 1_1_2 | Double) "Single"
>
Fonts and Unicode Support,在<textElement>里面的<font>里可以指定
Report Fonts是一种可以在整个Report design中使用的
XML Syntax
<!ELEMENT reportFont EMPTY>
<!ATTLIST reportFont
name NMTOKEN #REQUIRED
isDefault (true | false) "false"
fontName CDATA "sansserif"
size NMTOKEN "10"
isBold (true | false) "false"
isItalic (true | false) "false"
isUnderline (true | false) "false"
isStrikeThrough (true | false) "false"
pdfFontName CDATA "Helvetica"
pdfEncoding CDATA "CP1252"
isPdfEmbedded (true | false) "false"
>
Report Font Name,用<reportFont>指定
Default Report Font,isDefault="true"
其它的report font属性和下面所要说的<font>元素是一样的。
XML Syntax
<!ELEMENT font EMPTY>
<!ATTLIST font
reportFont NMTOKEN #IMPLIED
fontName CDATA #IMPLIED
size NMTOKEN #IMPLIED
isBold (true | false) #IMPLIED
isItalic (true | false) #IMPLIED
isUnderline (true | false) #IMPLIED
isStrikeThrough (true | false) #IMPLIED
pdfFontName CDATA #IMPLIED
pdfEncoding CDATA #IMPLIED
isPdfEmbedded (true | false) #IMPLIED
>
Referencing a Report Font,reportFont属性,例如我们定义了下面的report font
<reportFont
name="Arial_Normal"
isDefault="true"
fontName="Arial"
size="8"
pdfFontName="Helvetica"
pdfEncoding="Cp1252"
isPdfEmbedded="false"/>
后来我们要定义一个文本框,它的font属性和这个基本一样,只是size不同,则可以这样定义:
<textElement>
<font reportFont="Arial_Normal" size="14"/>
</textElement>
Font Name
Font Size
Font Styles and Decorations ,isBold, isItalic, isUnderline and isStrikeThrough
PDF Font Name,默认的iText library中有的是下面这些:
Courier
Courier-Bold
Courier-BoldOblique
Courier-Oblique
Helvetica
Helvetica-Bold
Helvetica-BoldOblique
Helvetica-Oblique
Symbol
Times-Roman
Times-Bold
Times-BoldItalic
Times-Italic
ZapfDingbats
还可以加入其他的字体包来得到使用新的字体,
Language PDF Font Name
Simplified Chinese STSong-Light
Traditional Chinese MHei-Medium
MSung-Light
Japanese HeiseiKakuGo-W5
HeiseiMin-W3
Korean HYGoThic-Medium
HYSMyeongJo-Medium
PDF Encoding,Europe is Cp1252,其他的有:
Latin 2: Eastern Europe Cp1250
Cyrillic Cp1251
Greek Cp1253
Turkish Cp1254
Windows Baltic Cp1257
Simplified Chinese UniGB-UCS2-H
UniGB-UCS2-V
Traditional Chinese UniCNS-UCS2-H
UniCNS-UCS2-V
Japanese UniJIS-UCS2-H
UniJIS-UCS2-V
UniJIS-UCS2-HW-H
UniJIS-UCS2-HW-V
Korean UniKS-UCS2-H
UniKS-UCS2-V
PDF Embedded Fonts,isPdfEmbedded attribute to "true".
Static Texts,
XML Syntax
<!ELEMENT staticText (reportElement, textElement?, text?)>
<!ELEMENT text (#PCDATA)>
静态文本有一个<text>属性,来指定里面显示的值
Text Fields,
XML Syntax
<!ELEMENT textField (reportElement, textElement?, textFieldExpression?,
anchorNameExpression?, hyperlinkReferenceExpression?,
hyperlinkAnchorExpression?, hyperlinkPageExpression?)>
<!ATTLIST textField
isStretchWithOverflow (true | false) "false"
evaluationTime (Now | Report | Page | Column | Group) "Now"
evaluationGroup CDATA #IMPLIED
pattern CDATA #IMPLIED
isBlankWhenNull (true | false) "false"
hyperlinkType (None | Reference | LocalAnchor | LocalPage |
RemoteAnchor | RemotePage) "None"
>
<!ELEMENT textFieldExpression (#PCDATA)>
<!ATTLIST textFieldExpression
class (java.lang.Boolean | java.lang.Byte | java.util.Date |
java.sql.Timestamp | java.lang.Double | java.lang.Float | java.lang.Integer
| java.lang.Long | java.lang.Short | java.math.BigDecimal |
java.lang.String) "java.lang.String"
>
Variable Height Text Fields,可能有一些文本的长度会超过预先设定的值,这样的时候应该自动加长文本框的长度,可以用isStretchWithOverflow to "true"来实现
Evaluating Text Fields,比如计算总计的那些文本域,在数据库完全跌代完成之前,不能知道它的值,有一个evaluationTime可以指定何时来显示它的值,有下列几种选择:
Immediate evaluation: The text field expression is evaluated when filling the current band
(evaluationTime="Now").
End of report evaluation: The text field expression is evaluated when reaching the end of the
report (evaluationTime="Report").
End of page evaluation: The text field expression is evaluated when reaching the end of the current
page (evaluationTime="Page").
End of column evaluation: The text field expression is evaluated when reaching the end of the
current column (evaluationTime="Column").
End of group evaluation: The text field expression is evaluated when the group specified by the
evaluationGroup attribute changes (evaluationTime="Group").
Suppressing Null Values Display,isBlankWhenNull attribute to "true"则将null转化为空来显示
Formatting Output,<textField>
Text Field Expression,<textFieldExpression>
各种图形图表的显示,这里略去“TODO:”
Hyperlinks,略去“TODO:”
Element Groups,
==Subreports
==Advanced JasperReports