2023年7月13日发(作者:)
3
创建第一份报表
本章我们将创建、编译、预览我们的第一份报表。
通过本章学习,我们将能够:
•
•
•
•
•
创建一份简单的JRXML报表模板
用JasperReports自定义ANT目标来预览报表模板
编译JRXML文件生成Jasper二进制报表模板
编写从JasperReports模板生成报表的代码
通过JaspreReports提供的工具浏览生成的JasperReports本地格式报表
•
•
生成能够显示在web浏览器中的报表
识别与报表中各片段相对应的JRXML元素
创建JRXML报表模板
创建报表的第一步是创建一份JRXML模板,我们在第1章中介绍了,JasperReports的JRXML模板是标准的XML文件。但是,依照惯例,其扩展名为.jrxml,称为JRXML文件或JRXML模板。JRXML模板可以手工编写,也可以使用可视化报表模板生成工具。时下,最流行的JRXML报表模板生成工具是iReport。我们将在第10章中介绍它。
山西老醯儿(FromSX)
·23·所有的JRXML文件都包含一个
我们的第一份报表将显示一个静态的字符串,其JRXML如下:
xmlns="/jasperreports" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/ jasperreports jasperreports. /xsd/" name="FirstReport">
在这个JRXML文件的元素中,有些我们在前面的章节中还没有接触过。例如:
•
•
•
在上面的例子中,我们看到了
山西老醯儿(FromSX)
·24·对于
义的x和y相对于包含它的父元素(本例中为
预览XML报表模板
JasperReports里有个工具可以用来预览报表的设计效果,它使得报表的设计更加快速。通过它,我们不用编译和填充就能立即对报表进行预览。
该工具是一个独立的Java应用程序,它包含在JasperReports的JAR文件中。需要执行的类是DesignViewer,执行它的最简单方法是把所有需要的库都添加到CLASSPATH中,然后使用ANT目标来运行它,这也是在工程JAR文件中的JasperReports范例所使用的方法,下面的ANT构建文件将加载JasperDesignViewer来预览我们刚完成的报表:
basedir="."> Previews our First Report XML Design value="/opt/jasperreports-3.5.2"/> description="Launches the design viewer to preview the XML report design."> 山西老醯儿(FromSX) ·25· fork="true">
这个ANT构建文件必须和JRXML文件保存在相同的目录中,建议把JRXML文件的报表名和文件名使用一致的名称。报表名称在
如果我们保存ANT构建文件为标准名称,就不需要在命令行中再指定构建文件名。此处的示例中,构建文件有一个名为viewDesignXML的
$ ant
Buildfile:
viewDesignXML:
执行完viewDesignXML目标后,我们会看到一个窗口显示出预览状态的报表模板,其标签名称为JasperDesignViewer。
通过关闭窗口,或在命令行窗口中输入Ctrl-c,这个JasperDesignViewer可以被安全地关闭。
山西老醯儿(FromSX)
·26· 在这个特殊的例子中中,我们能在预览状态下看到全部文本,这是因为此报表只包含了静态文本。如果报表的数据是来源于数据库或报表参数,此处不会显示实际文本,而是显示包含了要显示这是因为JasperDesignViewer不会对数据源
的数据的表达式。或报表参数进行实际访问。
创建二进制报表模板
JRXML不能用来直接生成报表,它们需要被编译成JasperReports的本地二进制格式,编译后的报表模板称为Jasper文件。有两种不同的方法来把JRXML文件编译成Jasper文件:通过编程实现,或通过JasperReports提供的自定义ANT任务来实现。
通过编程来编译JRXML模板
通过调用CompileManager类的compileReportToFile()方法,可以把JRXML模板编译成Jasper文件。eReportToFile()方法有三个重载版本,如下所示:
•
eReportToFile(String
sourceFileName)
•
eReportToFile(String
sourceFileName, String destFileName)
•
eReportToFile(JasperDesign
jasperDesign, String destFileName)
下面的表格对这些方法的参数进行了说明:
参数
String sourceFileName
说明
此参数指定JRXML模板的位置,它被用于编译生成报表模板。它可以是绝对路径,也可以相对路径。编译生成山西老醯儿(FromSX)
·27·的报表模板会以相同的文件名保存到和它相同的位置,并以.jasper作为扩展名。
String destFileName
此参数指定在文件系统中用于保存编译生成的报表模板的文件名,它可以是绝对路径或相对路径。
JasperDesign jasperDesign
这是报表在内存中的存在形式,Design实例可以通过在oader中调用相应的方法来创建。
下面的代码段演示了怎样使用eReportToFile()方法:
package book;
import ption;
import CompileManager;
public class FirstReportCompile
{
public static void main(String[] args)
{
try
{
n("");
eReportToFile(
"reports/");
n("Done!");
}
catch (JRException e)
{
tackTrace();
}
}
}
编译执行上面的代码,我们会得到一个名为的文件。此文件就是编译生成的JasperReports本地格式的模板。在本例中,我们使用前面讨论的第一个版本的eReportToFile()方法,源文件名会被用于编译生成的报表。如果我们希望编译后的报表为不同的文件名,就需要使用第二个版本的山西老醯儿(FromSX)
·28·eReportToFile()方法,并在其第二个参数中指定要生成的名字。
预览编译后的报表模板
前面讨论的DesignViewer可用于预览编译后的报表模板,就象JRXML模板一样。执行此工具的最简单的方法是在ANT目标中封装一个调用。下面,我们在文件中添加第二个ANT目标,并把它命名为viewDesign,它将使我们能够预览编译后的报表。
basedir="."> value="/opt/jasperreports-3.5.2" /> description="Launches the design viewer to preview the XML report design."> fork="true"> description="Launches the design viewer to preview the compiled report design."> 山西老醯儿(FromSX) ·29· fork="true"> description="Compiles the XML report design and produces the .jasper file."> classname="ompileTask"> description="Launches the report viewer to preview the report stored in the .jrprint file."> fork="true">
我们可以从命令行调用这个新目标:
ant viewDesign
调用完成后,我们会看到一个和前面的JRXML模板预览相同的窗口。
用ANT来编译JRXML模板
山西老醯儿(FromSX)
·30·JasperReports包含一个自定义的ANT任务,用它可以来编译报表模板。其编译方式非常便利,我们不需要编写执行编译的代码。然而,对于一些特殊的应用程序,还是需要通过编写相应的代码来编译报表的(比如JRXML文件是在运行时进行才创建的情况)。JasperReports中的自定义ANT任务在ompileTask类中进行定义,名为jrc。下面,让我们在中添加第三个自定义的目标来调用jrc任务。
basedir="."> value="/opt/jasperreports-3.5.2" /> description="Launches the design viewer to preview the XML report design."> fork="true"> description="Launches the design viewer to preview the compiled report design."> fork="true"> 山西老醯儿(FromSX) ·31· description="Compiles the XML report design and produces the .jasper file."> classname="ompileTask">
可以从命令行来调用这个新目标:
ant compile
编译目标会产生如下的输出:
Buildfile:
compile:
[jrc] Compiling 1 report design files.
[jrc] File :
/home/heffel/NetBeansProjects/Code_8082/jasper_book_
chapter_3/reports/ ... OK.
BUILD SUCCESSFUL
Total time: 3 seconds
目标编译完成后,我们会在文件系统里得到一个文件。
这个文件和通过调用eReportToFile()方法生成的文件是一样的。
山西老醯儿(FromSX)
·32·这里生成的Jasper文件也可以用JasperReports中包含的JasperDesign工具进行预览,其方法和输出与前面章节介绍的是相同的。
生成报表
按照JasperReports的习惯,从报表模板或Jasper文件生成报表的处理过程,称为填充(filling)报表。报表通过编写程序来进行填充,具体调用的是FillManager类的fillReportToFile()方法。此方法会将填充完报表并把它保存到磁盘。
fillReportToFile()方法有六个重载版本,如下所示:
•
portToFile(JasperReport jasperReport,
String destFileName, Map parameters, Connection connection)
•
portToFile(JasperReport jasperReport,
String destFileName, Map parameters, JRDataSource
datasource)
•
portToFile(String sourceFileName, Map
parameters, Connection connection)
•
portToFile(String sourceFileName, Map
parameters, JRDatasource dataSource)
•
portToFile(String sourceFileName,
String destFileName, Map parameters, Connection connection)
•
portToFile(String sourceFileName,
String destFileName, Map parameters, JRDataSource
dataSource)
下面的表格对这些方法的参数进行了说明:
参数 说明
山西老醯儿(FromSX)
·33·JasperReport jasperReport
此参数用于报表模板,Report实例是编译后的报表模板在内存中的存在形式。
String destFileName
Map parameters
指定用于保存报表的目标文件名。
这是一个接口实现类的实例,用于初始化报表模板中定义的所有报表参数。
Connection connection
此参数用于连接数据库,以便执行报表模板中定义的SQL查询。
JRDataSource dataSource
这是一个Source接口实现类的实例。
可以看出,在大多数情况下,我们通过一个实现了Source接口的类实例来传送填充报表的数据。报表模板可以包含内嵌的SQL查询,它们定义在JRXML文件的
尽管在报表模板中嵌入SQL查询可以简化开发,但传递JRDataSource还有其它的好处。即相同的报表可以使用不同的数据源,如数据库、CSV文件、Java对象,等等。我们将在第5章中详细讨论JasperReports对其它数据源的支持。
在这里的报表例子中,我们只包含了静态文本,不需要显示动态数据。由于没有JRDataSource或Connection就没办法填充报表,因此JaspreReports提供了一个不包含任何数据的JRDataSoruce实现,其名称为JREmptyDataSource。另外,由于我们这里的报表没有参数,所以只需传递一个p的空实例。我们将遵循JasperReports推荐的方法,把报表命名为与报表模板相同的名字(不包括文件的扩展名)。考虑到所有这些因素,最适当的fillReportToFile()版本是上面列出的第4个,如下所示:
portToFile(String sourceFileName, Map
parameters, JRDataSource dataSource)
下面的Java类将添充报表,并把它保存在磁盘里:
山西老醯儿(FromSX)
·34·package book;
import p;
import yDataSource;
import ption;
import FillManager;
public class FirstReportFill
{
public static void main(String[] args)
{
try
{
n("");
portToFile("reports/",
new HashMap(),
new JREmptyDataSource());
n("Done!");
}
catch (JRException e)
{
tackTrace();
}
}
}
执行这个类,我们会在编译报表模板的目录里得到一个名为t的文件。
查看报表
JasperReports中有个工具名为Viewer的类,可以用来查看生成的报表。和报表设计预览的工具一样,其最简使用方法是:把它包装到ANT目标里。这是JasperReprots内含示例程序所使用的方法,也是我们这里将要使用的方法。现在让我们添加一个新的目标到ANT构建文件中,按照JasperReports范例中的惯例,我们将此目标命名为“view”。
basedir="."> value="/opt/jasperreports-3.5.2" /> description="Launches the design viewer to preview the XML report design."> fork="true"> description="Launches the design viewer to preview the compiled report design."> fork="true"> description="Compiles the XML report design and produces the .jasper file."> classname="ompileTask"> 山西老醯儿(FromSX) ·36· description="Launches the report viewer to preview the report stored in the .jrprint file."> fork="true">
执行这个新的ANT目标,我们将看到一个如下图所示的窗口:
对,就是它!这就是我们成功创建的第一份报表。
在web浏览器中显示报表
前面我们讨论了怎样创建报表,并用JasperReports的本地格式把它保存到磁盘。下面我们介绍如何在web浏览器里显示报表,这需要借助于Servlet API,如下面的例子所示:
package book;
import ption;
import tream;
import riter;
山西老醯儿(FromSX)
·37·import Writer;
import p;
import tException;
import tOutputStream;
import rvlet;
import rvletRequest;
import rvletResponse;
import yDataSource;
import ption;
import RunManager;
public class FirstReportSendToBrowserServlet extends HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException
{
ServletOutputStream servletOutputStream = response.
getOutputStream();
InputStream reportStream =getServletConfig().getServletContext()
.getResourceAsStream("/reports/");
try
{
ortToPdfStream(reportStream,
servletOutputStream,
new HashMap(),
new JREmptyDataSource());
tentType("application/pdf");
();
();
}
catch (JRException e)
{
// display stack trace in the browser
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
tackTrace(printWriter);
tentType("text/plain");
putStream().print(ng());
}
}
}
山西老醯儿(FromSX)
·38·由于Web浏览器不能显示JasperReports的本地格式的报表(至少在不使用applet的情况下是这样),我们必须把报表导出为浏览器可以识别的格式。JasperReports允许我们把报表导出为PDF等多种格式,由于PDF是最流行的格式之一,我们在此处的示例中就选择它作为导出格式。
上例中的Servlet调用了静态方法ortToPdfStream(),其格式为:
runReportToPdfStream ( tream inputStream,
Stream outputStream,
parameters,
JRDataSource dataSource)
要想在浏览器中显示报表,我们需要在第一个参数中以流的形式传入二进制报表模板,也就是Jasper文件。我们可以通过调用ourceAsStream()方法达到这个目的,它需要传入一个包含Jasper文件位置信息的String作为参数。此方法返回一个tream实例,我们可以把它作为ortToPDFStream()方法的第一个参数。
ortToPDFStream()方法需要一个Stream()实例来对编译后的报表执行写操作。我们可以简单地使用Servlet的缺省的输出流,可以通过调用putStream()方法得到它。
ortToPDFStream()方法的另外两个参数是和JRDataSource,前者用于传递报表的任意参数,后者用于以Source形式传递数据。这个例子中,我们不需要传递任何参数和数据,所以使用一个空的HashMap和JREmptyDataSource。
山西老醯儿(FromSX)
·39·为了确保浏览器正确地显示报表,我们必须把内容类型设置为application/pdf,通过调用tentType()方法可以完成这件事。
最后的示例代码需要部署到一个Servlet容器中,我们可以通过ANT脚本来自动地完成这一过程。该脚本作为本书源代码的一部分,可以从/files/code/8082_下载得到。下面的屏幕截图显示了浏览器中的PDF格式报表:
JRXML报表模板的元素
在前面的袋子中,我们用JRXML报表模板的
下面就来介绍一下
山西老醯儿(FromSX)
·40·此元素用来给报表模板输入任意的信息。
加裁了报表的Java应用程序通过调用perty()方法可以载入这些属性。JRXML模板可以包含零个或多个
此元素用于导入个别的Java类或完整的包。
报表的样式可以定义在独立的报表模板中,这样可以方便地在报表之间进行重用。这一机制类似于HTML中的级联样式表可定义在独立的CSS文件中。报表样式模板可以用XML文件进行定义。按照惯例,这是一个JRTX文件。另外,报表样式模板也可以用一个实现了late接口的类的实例进行定义,此方法比较少见。
"my_"