从 Java 应用程序动态生成 PDF 文件:
http://www-128.ibm.com/developerworks/cn/opensource/os-javapdf/
如果应用程序需要动态生成 PDF 文档,则需要 iText 库。开放源码的 iText 库使 PDF 文档的创建能够在瞬间完成。本文介绍了 iText 并提供了使用它从 Java ™ 技术应用程序生成 PDF 文档的由浅入深的指南。我们创建了一个示例应用程序以更好地理解 iText。
很多应用程序要求动态生成 PDF 文档。这类应用程序包括银行生成用于电子邮件投递的客户报表,到读者购买特定图书章节并以 PDF 格式接收这些文档。例子罗列下去是很多的。在本文中,将使用 iText Java 库生成 PDF 文档,并引导您完成一个示例应用程序,以使您能够更好地理解和使用 iText。
iText 是 Lowagie.com 站点(请参阅 参考资料)免费提供的 Java 库。iText 库的功能很强大,支持 HTML、RTF 和 XML 文档的生成,此外还能够生成 PDF 文档。可以从多种字体中选择文档中所使用的字体。同时,iText 的结构允许使用相同的代码生成以上任意类型的文档。
iText 库中的类用于以各种字体来生成 PDF 文本、在 PDF 文档中生成表格、为页添加水印等。iText 还提供许多功能。在一篇文章中不可能一一演示。本文中将介绍生成 PDF 文档的基本需求。
我们将使用 Eclipse 来进行示例应用程序开发。作为一个开放源码的 IDE,可以免费获得 Eclipse,而且其功能非常强大。现在就可以下载 Eclipse(请参阅 参考资料)。
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 —— 这个类表示包含单元格的表,单元格有序地排列在矩阵中。
作为一个纯粹的 Java 库,iText 是以 JAR 文件的形式出现的(请参阅 参考资料)。一旦下载了这个库(在路径 C:/temp 下),执行下列步骤将会在 Eclipse 环境中配置 iText 库:
- 在 Eclipse 中创建一个新的 Java 项目,将其命名为 iText。
- 在 Package Explorer 视图中右击 iText 项目,然后选择 Properties。
- 单击 Java Build Path。在 Libraries 选项卡中,单击 Add External JARs。
- 浏览到 C:/temp 目录,选择该目录下的 itext-1.3.jar。
- 单击 OK。
现在已经配置好 iText,Eclipse 已经准备好创建 Java 应用程序以生成动态 PDF 文档。
还有什么能够比自己动手创建一个工作示例更好地演示技术了?现在有了所需的工具(Eclipse IDE)和库(iText 库),可以开始设计和开发一个示例应用程序了。
让我们创建一个简单的 PDF 文档,其中包含一些基本元素,如纯文本、非默认字体的彩色文本、表格、列表、章节和小节等。此应用程序的目的是让您熟悉 iText 库的使用方式。有很多与帮助生成 PDF 文档有关的类。在这里不可能介绍所有这些类。iText 的 javadoc 是介绍如何使用这些类的很好的资料。下面让我们来开始编写代码。
第一步是创建一个文档。文档是 PDF 文档的所有元素的容器。
|
第一个参数是页面大小。接下来的参数分别是左、右、上和下页边距。但是还没有定义该文档的类型。它取决于所创建的写入器的类型。对于我们的示例,选择了 com.lowagie.text.pdf.PdfWriter。其他写入器为 HtmlWriter、RtfWriter、XmlWriter 等等。它们的名称解释了它们的实际用途。
|
第一个参数是对文档对象的引用,第二个参数是文件的实际名称,在该名称中还会给出其输出路径。接下来,打开文档以写入内容。
现在,将在文档的第一页上添加一些文本。通过 com.lowagie.text.Paragraph 来添加文本。可以用文本及其默认的字体、颜色、大小等等设置来创建一个默认段落。或者,也可以设置自己的字体。下面让我们来看看这两种做法。
|
下面是上面代码的输出示例。在上面代码的结尾处添加 document.close();
以关闭文档。
您已经看到了如何向 PDF 文档中添加纯文本。接下来,需要向文档中添加一些复杂的元素。我们开始创建一个新的章节。章节是一个特殊的小节,默认情况下,章节从一个新的页面开始,并显示一个默认的编号。
|
在上面的代码中,创建了一个新的章节对象,chapter1
,其标题为 “This is Chapter 1”,将编号级别设为 0 就不会在页面上显示章节编号。
小节是章节的子元素。在下面的代码中,创建了一个标题为 “This is Section 1 in Chapter 1” 的小节。为在该小节下添加一些文本,创建了另一个段落对象,someSectionText
,并将其添加到小节对象中。
|
在添加表格之前,我们先看一下文档的样子。添加下面两行代码以关闭文档,然后编译并执行程序以生成 PDF 文档:document.add(chapter1);document.close();
。
接下来,创建一个表格对象。创建一个包含行列矩阵的表格。行中的单元格可以跨多个列。同样地,列中的单元格也可以跨多个行。因此,一个 3 x 2 的表格实际上不一定有 6 个单元格。
|
在上面的代码中,创建了一个表格对象,t
,它有三列、两行。然后设置表格的边框颜色。填充用于设置单元格中文本间的间隔以及单元格的边界。间隔指的是相邻单元格间的边界。接下来,将创建三个单元格对象,每个单元格中的文本都各不相同。接下来,将它们添加到表格中。将它们添加到第一行中,从第一列开始,移到同一行中的下一列。一旦该行创建完成,就将下一个单元格添加到下一行的第一列中。也可以通过只提供单元格的文本将单元格添加到表格中,例如,t.addCell("1.1");
。最后,将表格对象添加到小节对象中。
最后,我们来看一下如何将列表添加到 PDF 文档中。列表包含一定数量的 ListItem
。可以对列表进行编号,也可以不编号。将第一个参数设置为 true 表明想创建一个要进行编号的列表。
|
我们已经向 chapter1
对象中添加了所需的对象。因此,已经没有其他要添加到 chapter1
中的元素了,现在可以将 chapter1
添加到主 document
中了。与在示例应用程序中所做的一样,还要在这时关闭文档对象。
|
- 下载示例应用程序,j-itextsample.jar(参见 下载)。
- 在某个目录中解压缩 j-itextsample.jar。例如,如果将其解压缩到 C:/temp,则会将源码和类文件放到 C:/temp/com/itext/test 目录下。
- 打开一个命令提示,将目录更改为 C:/temp。
- 在这个命令提示中设置系统的类路径。将
C:/temp/itext-1.3.jar
包括在系统的类路径中。在 Windows® 上,执行命令set classpath=C:/temp/itext-1.3.jar;%classpath%
。 - 使用命令
java com.itext.test.ITextTest
运行应用程序。
程序会在 C:/ 目录下生成一个 ITextTest.pdf 文档。下面显示了这个 PDF 文档第二页的屏幕图。
您已经看到了一些生成 PDF 的基本元素。iText 的美妙之处是相同元素的语法可以供不同类型的写入器使用。而且,写入器的输出可以重定向到控制台(当写入器类型是 XML 和 HTML 时)、servlet 的输出流(在对 PDF 文档的 Web 请求作出响应时)或者是其他类型的 OutputStream。当响应相同,但其类型随所请求的是 PDF、RTF、HTML 或 XML 文档而有所不同时,使用 iText 是非常方便的。iText 允许用户创建水印,对文档进行加密以及设置其他输出细节。
将 ActiveX 控件集成到 SWT 应用程序:
http://www-128.ibm.com/developerworks/cn/linux/opensource/os-activex/index.html
通过使用标准窗口小部件工具箱(Standard Widget Toolkit,SWT),您可以开发独立的 Java 应用程序,它看起来和操作起来类似本机应用程序。如果您花了很多时间来开发用于 Windows 的 Java 客户机端应用程序,那么您或许希望将一些本机 Windows 组件集成到您的应用程序中。SWT,作为正在开发中的 Eclipse 项目的一部分,通过为您提供在独立 SWT 应用程序中方便地利用和集成 ActiveX 控件的方法来实现这一需求。
多年以来,Java 语言已经“统治”了基于服务器的应用程序的开发领域。在该语言开发早期,人们将它吹捧为开发跨平台的桌面应用程序的解决方案。遗憾的是,事实上它从未符合过这种大肆宣传。在最终用户和开发人员社区需要抽象窗口工具箱(Abstract Window Toolkit,AWT)之外的一些其它功能之后,Sun Microsystems 引入了 Java 基础类(Java Foundation Classes,JFC)(也称为 Swing)来诱使开发人员重新考虑将 Java 语言用于开发 GUI 应用程序。虽然 Swing 确实为开发客户机端的应用程序提供了一个成熟且经证实的模型,但它仍缺少本机应用程序的可视外观和操作。
在开发和引入标准窗口小部件工具箱(SWT)之前,业内权威人士和开发人员都宣告 Java 语言不适合开发桌面应用程序。SWT 通过为开发人员提供一个创建应用程序的框架(所创建的应用程序完全逼真地模仿本机应用程序),正开始给客户机端 Java 的时机带来新气象。与其前辈(例如 AWT 和 JFC)不同,SWT 给开发人员提供了一个与平台无关的 API,该 API 与操作系统的本机窗口环境紧密地集成在一起。虽然,传统上认为 Eclipse 项目是 Java 的开放源码集成开发环境(IDE),但是该项目涉及的范围更广。在 Eclipse 的网站首页上,将 Eclipse 描述成“……一种通用工具平台 — 只不过是一个开放的可扩展 IDE,并没什么特别之处。”
虽然在开发本文提供的样本应用程序期间使用了 Eclipse,但是我们将着重演示如何在独立应用程序的上下文中使用 ActiveX 控件。有关 Eclipse 项目的更多信息和背景知识,请参阅本文末尾的 参考资料。
在查看如何将 ActiveX 控件集成到 SWT 应用程序的代码和实现细节之前,让我们查看一下所包含的样本应用程序的用途和结构。该应用程序是一个简单的 PDF 查看器,它允许用户使用 Adobe 的 Acrobat Reader 控件来查看 PDF 文件并与之交互。用户可以在 SWT 应用程序中浏览其硬盘驱动器、定位文件和查看 PDF 文档,如 图 1中所示。
图 1. 样本应用程序:在 Microsoft Windows XP 上运行的 PDF 查看器
可以使用 参考资料中的链接下载样本 PDF 查看器应用程序。要测试 PDF 查看器应用程序,环境必须满足下列最低需求:
- Microsoft Windows 操作系统
- 安装了 Java 2 SDK,标准版 1.4 或更高版本(请参阅 参考资料以获取下载链接)
- 安装了 Apache Ant 1.5.2 或更高版本(请参阅 参考资料以获取下载链接)
- 安装了 Adobe Acrobat Reader 5.0
虽然已经费心使 Ant 构建脚本可以跨平台使用,但是只在 Microsoft Windows XP 上测试和验证了 PDF 查看器应用程序。让我们从安装和设置样本应用程序开始吧。
要安装和构建 PDF 查看器应用程序,请完成下列步骤:
- 使用 参考资料中的链接下载源代码软件包。
- 将
pdfviewer.zip
文件解压缩到临时目录中。 - 在新创建的目录中执行下面这个命令:
ant clean
。 - 在新创建的目录中执行下面这个命令:
ant
。
如果您的环境满足需求并且配置正确,那么您应当会看到类似于下面这样的内容:
|
既然我们已经介绍了 PDF 查看器应用程序的基础知识,那就让我们研究一下如何在 SWT 应用程序中集成和使用 ActiveX 控件。因为我们这里的目的是讨论 ActiveX 集成,所以我们将不研究如何创建独立的 SWT 应用程序以及如何在 Microsoft Windows 中使用 ActiveX 控件。有关如何在 Eclipse Workbench 之外使用 SWT 组件的更多信息和背景知识,请参阅 Adrian Van Emmenis 的由三部分所组成的文章系列,本文末尾的 参考资料这一节中突出显示了这些文章。
清单 1 概述了 PDFViewer
类的基本结构并演示了如何将 ActiveX 控件集成到 SWT 应用程序。
|
让我们逐步研究这一代码片段:
- 每次应用程序启动时,都会创建
PDFViewer
类的新实例。 - 如第 3 行和第 4 行所示,我们需要定义两个对象:
OleControlSite
和OleAutomation
。OleControlSite
对象变量处理与 ActiveX 控件的交互。OleAutomation
对象允许开发人员访问特性并执行 ActiveX 控件所提供的命令。 - 在第 18 行上,定义了
OleFrame
对象。该对象是 ActiveX 控件的容器,并管理该控件的生命周期。 - 在第 22 行上,通过使用两个参数来实例化
site
变量:第一个参数包含对OleFrame
的引用,第二个参数包含标识 ActiveX 控件的字符串。程序标识符(可在 Windows 注册表中找到)在 Microsoft Windows 中唯一地标识该控件。 - 在第 23 行上,使用对
OleControlSite
变量的引用来实例化site
变量。
在用户可以查看 PDF 文档之前,用户需要从其工作站选择 PDF 文档。下面 清单 2中的代码说明了为最终用户打开一个文件对话框所必需的对象和方法。
|
让我们简要地研究这一代码片段:
- 每当用户从菜单栏选择“Open...”时,都要执行第 13 行上的
run
方法。 - 如第 15 行和第 16 行所示,创建一个
FileDialog
对象。如 图 2 所示,该对象向用户显示一个本机文件对话框。 - 第 18 行构造一个字符串,该字符串包含 PDF 文档在用户工作站上的位置。
- 第 20 行将
window
对象的数据类型转换成PDFViewer
对象。 - 第 22 行执行
loadFile
方法并传入所选 PDF 文档的位置。在接下来的几节中,我们将更详细地研究loadFile
方法。
在讨论如何在查看器应用程序中显示 PDF 文档之前,了解在 Adobe Acrobat Reader Active X( PDF.PdfCtrl.5
)组件中实际上可以使用哪些命令是有用的。样本代码软件包包括了由 IBM 开发的类。该类列出了 ActiveX 控件所公开的所有公用命令。
要枚举用于 PDF.PdfCtrl.5
控件的命令,请在 PDFViewer 目录中执行下面的命令: ant activex
。
如果您的环境配置正确,那么您应当会看到类似于下面这样的内容:
|
要查看用于任何其它 ActiveX 控件的命令,只要编辑包含在源代码中的 build.xml
文件,并用一些其它 ActiveX 的程序标识符替换该类的参数。下面的 Ant 目标说明了要插入控件的程序标识符的位置。
|
从该类输出的第一个命令是 LoadFile。让我们研究一下如何在 PDF 查看器应用程序中应用这个命令。
一旦用户选择了一个 PDF 文档, PDFViewer
类就需要执行 ActiveX 控件中所公开的命令。下面 清单 4中的代码说明了使 ActiveX 控件装入用户所选的 PDF 文档所需的对象和方法。
|
让我们研究这一代码片段:
- 用户选择 PDF 文件之后,执行第 6 行上的
loadFile
方法。 - 第 8 行调用
showPdfControl
方法。必须使用doVerb
命令激活 ActiveX 控件之后,该控件在应用程序中才可见。在 Eclipse 网站上标题为“ActiveX Support In SWT”的文章中可以找到动词的完整清单和概述(请参阅 参考资料以获取该文章的链接)。 - 第 10 行到第 16 行调用 ActiveX 控件中的
LoadFile
命令。有关如何使用在这些行中用到的每个对象的更多信息,请参阅 参考资料中的链接以获取 org.eclipse.swt.ole.win32 JavaDoc。
要测试和运行 PDF 查看器应用程序,请完成下列步骤:
- 在将源代码解包的目录中执行下面这个命令:
ant run
。 - 执行 Ant 脚本之后,应当会出现 PDF 查看器应用程序。
- 从 File 菜单选择“Open...”,以从工作站选择 PDF 文件。呈现所选的 PDF 文档。
SWT 库向 Java 开发人员提供一种功能强大的机制,使 Microsoft Windows ActiveX 控件集成到高度交互的客户机端应用程序。有了 SWT 对 ActiveX 控件和 OLE 文档的支持,研究如何创建外观极棒的且集成了本机窗口小部件和组件的应用程序是令人激动的。