从Java应用程序动态生成PDF文件(转)[@more@]如果应用程序需要动态生成 PDF 文档,则需要 iText 库。开放源码的 iText 库使 PDF 文档的创建能够在瞬间完成。本文介绍了 iText 并提供了使用它从 Java ? 技术应用程序生成 PDF 文档的由浅入深的指南。我们创建了一个示例应用程序以更好地理解 iText。
很多应用程序要求动态生成 PDF 文档。这类应用程序包括银行生成用于电子邮件投递的客户报表,到读者购买特定图书章节并以 PDF 格式接收这些文档。例子罗列下去是很多的。在本文中,将使用 iText Java 库生成 PDF 文档,并引导您完成一个示例应用程序,以使您能够更好地理解和使用 iText。
熟悉 iText iText 是 Lowagie.com 站点(请参阅 参考资料)免费提供的 Java 库。iText 库的功能很强大,支持 HTML、RTF 和 XML 文档的生成,此外还能够生成 PDF 文档。可以从多种字体中选择文档中所使用的字体。同时,iText 的结构允许使用相同的代码生成以上任意类型的文档。
iText 库中的类用于以各种字体来生成 PDF 文本、在 PDF 文档中生成表格、为页添加水印等。iText 还提供许多功能。在一篇文章中不可能一一演示。本文中将介绍生成 PDF 文档的基本需求。
我们将使用 Eclipse 来进行示例应用程序开发。作为一个开放源码的 IDE,可以免费获得 Eclipse,而且其功能非常强大。现在就可以下载 Eclipse。
iText API:近距离观察 com.lowagie.text.Document 是生成 PDF 的主要的类。它是需要使用的第一个类。一旦开始创建文档,将需要一个写入器向文档中写入内容。 com.lowagie.text.pdf.PdfWriter 就是一个 PDF 写入器。下面列出了通常需要使用的类:
com.lowagie.text.Paragraph —— 这个类表示一个缩进的段落。
com.lowagie.text.Chapter —— 这个类表示 PDF 文档中的章节。使用 Paragraph 作为题目并使用 int 作为章节号码来创建它。
com.lowagie.text.Font —— 这个类包含了全部的字体规范,例如字体、大小、样式和颜色。各种字体都在这个类中声明为静态常数。
com.lowagie.text.List —— 这个类表示一个列表,按顺序包含许多 ListItems。
com.lowagie.text.Table —— 这个类表示包含单元格的表,单元格有序地排列在矩阵中。
下载 iText 并在 Eclipse 中进行配置
作为一个纯粹的 Java 库,iText 是以 JAR 文件的形式出现的(请参阅 参考资料)。一旦下载了这个库(在路径 C: emp 下),执行下列步骤将会在 Eclipse 环境中配置 iText 库:
在 Eclipse 中创建一个新的 Java 项目,将其命名为 iText。
在 Package Explorer 视图中右击 iText 项目,然后选择 Properties。
单击 Java Build Path。在 Libraries 选项卡中,单击 Add External JARs。
浏览到 C: emp 目录,选择该目录下的 itext-1.3.jar。
单击 OK。
现在已经配置好 iText,Eclipse 已经准备好创建 Java 应用程序以生成动态 PDF 文档。
示例应用程序 还有什么能够比自己动手创建一个工作示例更好地演示技术了?现在有了所需的工具(Eclipse IDE)和库(iText 库),可以开始设计和开发一个示例应用程序了。
让我们创建一个简单的 PDF 文档,其中包含一些基本元素,如纯文本、非默认字体的彩色文本、表格、列表、章节和小节等。此应用程序的目的是让您熟悉 iText 库的使用方式。有很多与帮助生成 PDF 文档有关的类。在这里不可能介绍所有这些类。iText 的 javadoc 是介绍如何使用这些类的很好的资料。下面让我们来开始编写代码。
第一步是创建一个文档。文档是 PDF 文档的所有元素的容器。
清单 1. 实例化文档对象
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
第一个参数是页面大小。接下来的参数分别是左、右、上和下页边距。但是还没有定义该文档的类型。它取决于所创建的写入器的类型。对于我们的示例,选择了 com.lowagie.text.pdf.PdfWriter。其他写入器为 HtmlWriter、RtfWriter、XmlWriter 等等。它们的名称解释了它们的实际用途。
清单 2. 创建 PdfWriter 对象
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream("C:ITextTest.pdf"));
document.open();
第一个参数是对文档对象的引用,第二个参数是文件的实际名称,在该名称中还会给出其输出路径。接下来,打开文档以写入内容。
现在,将在文档的第一页上添加一些文本。通过 com.lowagie.text.Paragraph 来添加文本。可以用文本及其默认的字体、颜色、大小等等设置来创建一个默认段落。或者,也可以设置自己的字体。下面让我们来看看这两种做法。
清单 3. 创建段落对象
document.add(new Paragraph("First page of the document."));
document.add(new Paragraph("Some more text on the
first page with different color and font type.",
FontFactory.getFont(FontFactory.COURIER, 14, Font.BOLD, new Color(255, 150, 200))));
下面是上面代码的输出示例。在上面代码的结尾处添加 document.close(); 以关闭文档。
400) {this.resized=true; this.width=400; this.alt='Click here to open new window';}" border=0 resized="true">
图 1. 上面代码的输出示例
您已经看到了如何向 PDF 文档中添加纯文本。接下来,需要向文档中添加一些复杂的元素。我们开始创建一个新的章节。章节是一个特殊的小节,默认情况下,章节从一个新的页面开始,并显示一个默认的编号。
清单 4. 创建章节对象
Paragraph title1 = new Paragraph("Chapter 1",
FontFactory.getFont(FontFactory.HELVETICA,
18, Font.BOLDITALIC, new Color(0, 0, 255)));
Chapter chapter1 = new Chapter(title1, 1);
chapter1.setNumberDepth(0);
在上面的代码中,创建了一个新的章节对象,chapter1,其标题为 “This is Chapter 1”,将编号级别设为 0 就不会在页面上显示章节编号。
小节是章节的子元素。在下面的代码中,创建了一个标题为 “This is Section 1 in Chapter 1” 的小节。为在该小节下添加一些文本,创建了另一个段落对象,someSectionText,并将其添加到小节对象中。
清单 5. 创建小节对象
Paragraph title11 = new Paragraph("This is Section 1 in Chapter 1",
FontFactory.getFont(FontFactory.HELVETICA, 16,
Font.BOLD, new Color(255, 0, 0)));
Section section1 = chapter1.addSection(title11);
Paragraph someSectionText = new Paragraph("This
text comes as part of section 1 of chapter 1.");
section1.add(someSectionText);
someSectionText = new Paragraph("Following is a 3 X 2 table.");
section1.add(someSectionText);
在添加表格之前,我们先看一下文档的样子。添加下面两行代码以关闭文档,然后编译并执行程序以生成 PDF 文档:document.add(chapter1);document.close();。
400) {this.resized=true; this.width=400; this.alt='Click here to open new window';}" border=0 resized="true">
图 2. 章节输出示例
接下来,创建一个表格对象。创建一个包含行列矩阵的表格。行中的单元格可以跨多个列。同样地,列中的单元格也可以跨多个行。因此,一个 3 x 2 的表格实际上不一定有 6 个单元格。
清单 6. 创建表格对象
Table t = new Table(3,2);
t.setBorderColor(new Color(220, 255, 100));
t.setPadding(5);
t.setSpacing(5);
t.setBorderWidth(1);
Cell c1 = new Cell("header1");
c1.setHeader(true);
t.addCell(c1);
c1 = new Cell("Header2");
t.addCell(c1);
c1 = new Cell("Header3");
t.addCell(c1);
t.endHeaders();
t.addCell("1.1");
t.addCell("1.2");
t.addCell("1.3");
section1.add(t);
在上面的代码中,创建了一个表格对象,t,它有三列、两行。然后设置表格的边框颜色。填充用于设置单元格中文本间的间隔以及单元格的边界。间隔指的是相邻单元格间的边界。接下来,将创建三个单元格对象,每个单元格中的文本都各不相同。接下来,将它们添加到表格中。将它们添加到第一行中,从第一列开始,移到同一行中的下一列。一旦该行创建完成,就将下一个单元格添加到下一行的第一列中。也可以通过只提供单元格的文本将单元格添加到表格中,例如, t.addCell("1.1");。最后,将表格对象添加到小节对象中。
最后,我们来看一下如何将列表添加到 PDF 文档中。列表包含一定数量的 ListItem。可以对列表进行编号,也可以不编号。将第一个参数设置为 true 表明想创建一个要进行编号的列表。
清单 7. 创建列表对象
List l = new List(true, false, 10);
l.add(new ListItem("First item of list"));
l.add(new ListItem("Second item of list"));
section1.add(l);
我们已经向 chapter1 对象中添加了所需的对象。因此,已经没有其他要添加到 chapter1 中的元素了,现在可以将 chapter1 添加到主 document 中了。与在示例应用程序中所做的一样,还要在这时关闭文档对象。
清单 8. 向主文档中添加章节
document.add(chapter1);
document.close();
运行示例应用程序 下载示例应用程序,j-itextsample.jar(参见 下载)。
在某个目录中解压缩 j-itextsample.jar。例如,如果将其解压缩到 C: emp,则会将源码和类文件放到 C: empcomitext est 目录下。
打开一个命令提示,将目录更改为 C: emp。
在这个命令提示中设置系统的类路径。将 C: empitext-1.3.jar 包括在系统的类路径中。在 Windows? 上,执行命令 set classpath=C: empitext-1.3.jar;%classpath%。
使用命令 java com.itext.test.ITextTest 运行应用程序。
程序会在 C: 目录下生成一个 ITextTest.pdf 文档。下面显示了这个 PDF 文档第二页的屏幕图。
400) {this.resized=true; this.width=400; this.alt='Click here to open new window';}" border=0 resized="true">
图 3. PDF 文档的屏幕图
结束语 您已经看到了一些生成 PDF 的基本元素。iText 的美妙之处是相同元素的语法可以供不同类型的写入器使用。而且,写入器的输出可以重定向到控制台(当写入器类型是 XML 和 HTML 时)、servlet 的输出流(在对 PDF 文档的 Web 请求作出响应时)或者是其他类型的 OutputStream。当响应相同,但其类型随所请求的是 PDF、RTF、HTML 或 XML 文档而有所不同时,使用 iText 是非常方便的。iText 允许用户创建水印,对文档进行加密以及设置其他输出细节。