Itext使用说明
1、 简单的Itext
第一章:创建一个文档
创建文档的5个步骤:HELLO WORLD
下载第一个例子的源文件:chap0101.java
这个例子包含使用itext产生pdf文件的5个最重要的步骤:
第一步:创建一个com.lowagie.text.document的对象实例:Document document = new Document();
第二步:创建一个writer,用于查看文档和根据你的输出流写入文档:PdfWriter.getInstance(document, new FileOutputStream("Chap0101.pdf"));
第三步:打开文档:document.open();
第四步:把内容写入文档:document.add(new Paragraph("Hello World"));
第五步:关闭文档:document.close();
检验结果:chap0101.pdf
测试步骤1:文档对象
com.lowagie.text.Document对象有三个构造器
public Document();
public Document(Rectangle pageSize);
public Document(Rectangle pageSize,
int marginLeft,
int marginRight,
int marginTop,
int marginBottom);
第一个构造器通过使用PageSize.A4作为参数调用第二个构造器,第二个构造器通过使用36作为每一个页边空白的值来调用第三个构造器。
Pagesize(页面尺寸)
你能够创建你自己的矩形对象,可以设定某一个颜色。在例子chap0102.java中,我们创建了一个以黄色为背景色的长窄的文档。
Rectangle pageSize = new Rectangle(144, 720);
pageSize.setBackgroundColor(new java.awt.Color(0xFF, 0xFF, 0xDE));
Document document = new Document(pageSize);
这是结果:chap0102.pdf,通常,你不必担心创建这个矩形,因为你可以使用在pagesize.java类中的数据,有下列的页面大小可供选择:A0-A10, LEGAL, LETTER, HALFLETTER, _11x17, LEDGER, NOTE, B0-B5, ARCH_A-ARCH_E, FLSA 和 FLSE。这些页面尺寸中大多数是portrait形式的,如果你想要它们为landscape形式,你所要做的就是rotate()这个矩形:Document document = new Document(PageSize.A4.rotate());
查看这个例子:chap0103.java和它的结果。
页边空白
当你正在创建一个文档时,你可以定义左右上下的页面间距:Document document = new Document(PageSize.A5, 36, 72, 108, 180);在例子chap0104.java(这是它的结果:chap0104.pdf),你可以看见这个文档有 0.5 英寸 的左边距和 1 英寸 的右边距,上边距是 1.5 英寸 ,下边距是 2.5 英寸 。
测量法
当你正在创建一个矩形或是选择一个页面的边距时,你可能会很疑惑是使用什么度量的单位:厘米,英寸或是像素。实际上,默认的度量单位粗略的与多种的排字印刷单位相对应,这种度量单位就是点(point)
一英寸 有72个点,如果你想要创建一个有a4矩形大小的pdf文档,你必须计算点的数目:
21 cm
/ 2.54 = 8.2677 inch
8.2677 * 72 = 595 points
29.7 cm
/ 2.54 = 11.6929 inch
11.6929 * 72 = 842 points
默认的36点的边与半英寸相近。
注意:如果你改变了页面的尺寸,这只会影响下一页(看page initialisations),如果你改变了页面的边距,会有实时的影响,因此要格外的小心。
测试步骤2:writer对象
一旦我们创建了文档,我们可以创建一个或是多个writer的实例用于监听文档。所有的writer都是从com.lowagie.text.DocWriter这个抽象类继承下来的。因此有两种可能性:你可以使用com.lowagie.text.pdf.PdfWriter来产生pdf格式的文档,或者你可以使用com.lowagie.text.html.HtmlWriter来产生html的文档,例如你如果想产生TeX的文档,你可以写一个包:com.lowagie.text.TeX.TeXWriter
注意:我是为了测试的目的而写html类的,你实际上在产品的环境中并不需要使用它,html的结果并不很好,而且有很多的相关工具。Itext的html包对于调试很有用,html比pdf更加的简单,当产生pdf文件有错误发生时,很难发现导致错误的bug所在,pdf被毁坏了不能打开查看它的内容。因此在测试阶段我会同时产生html文档来获得错误发生的实际位置,或是产生异常的实际对象。
这里还有com.lowagie.text.xml和com.lowagie.text.rtf两个包,但是xml和rtf的生成函数还不稳定(看第7和第8章)。
Writer类的构造器还是私有类型的,你只可以以下列的方法产生一个实例:public static xxxWriter getInstance(Document document, OutputStream os) throws DocumentException(xxx为pdf或是html)。
你可以这样创建一个实例:PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("Chap01xx.pdf"));但是你将几乎不需要writer对象(除非你想生成高级的pdf或是你想使用一些特定的函数,如ViewerPreferences或是Encryption),因此只得到这个实例是足够了:PdfWriter.getInstance(document, new FileOutputStream("Chap01xx.pdf"));
在创建文档的第一步中的第一个参数并不重要,第二个参数可以是任何一种的输出流,直到现在,我们都还是一直以java.io.FileOutputStream来写一个文档,但是在例子chap0105中,输出流是一个javax.servlet.ServletOutputStream(这不是一个独立的例子,你只能在servlet引擎中来测试),如果你使用msie作为浏览器,你会看见一个空白页,这是由于微软的特定版本的浏览器的bug所导致的,在许多的邮件列表和comp.text.pdf的新闻组中你可以获得很多的信息。如果你想尝试更加困难的例子,试试下面的代码:calendar.java和month.java,tal liron提供了一个jsp的例子:pdf.jsp。
测试步骤3:元数据+打开文档
元数据
在你添加实际的数据(内容)时,你可能想要添加一些元数据到你的文档中去,你可以使用以下的方法:
public boolean addTitle(String title)
public boolean addSubject(String subject)
public boolean addKeywords(String keywords)
public boolean addAuthor(String author)
public boolean addCreator(String creator)
public boolean addProducer()
public boolean addCreationDate()
public boolean addHeader(String name, String content)
你可以选择你自己的头衔、主题、关键字、作者和创建者,但是添加procedure数据的方法一直都是:itext(或是itext的参照),而且添加创建日期的方法是添加目前的系统时间(实际上,这两个方法是自动加以调用的)。
你也可以给header添加一个自定义的名称,但是在pdfwriter上是没有效果的(由于它只是应用于htmlwriter),如果我们看看第一步的例子:chap0101.java,我们会发现在信息窗口中只有producer和date的信息,如果我们运行cbhap0106.java,结果类似于chap0106.pdf但是在信息窗口中我们可以看到更多的信息。
作为这一事实的额外说明,你可以把文档发送给任何一个输出流;例6把html发送给了System.out
你可以看到一个自定义的头被添加了“expires”的标记在这里有一个异常:如果你使用htmlwriter.stylesheet添加了一个自定义的头,你得到了stylesheet的链接
document.add(new Header(HtmlWriter.STYLESHEET, "my.css"));
结果是:<link rel="STYLESHEET" type="text/css" href="my.css">
在你打开文档前的需要做的事情
在打开文档之前,你只能添加元数据。这是itext开发者所做的抉择,在html元信息在文档起始位置的头标记中被提交。调用打开的方法导致了writer把头写入输出流。因此一旦文档被打开,没有任何办法可以修改数据,如果pdf头部包含任何元数据,它看上去就如同:
%PDF-1.2
%噌忏
第一行显示产生的文档是pdf1.2的版本。
第二行表示参考手册。
在pdf文档中,元数据被pdfinfo对象所控制,当文档被关闭时,由pdfwriter写入。因此,为什么人们不能随时的添加或是改变链接库是没有技术上的理由的,这是设计的选择。
页面初始化
Open方法在不同的writer中触发了一些初始化动作,例如:如果你想让watermark或是headerfooter对象出现在打开文档的第一页,你必须在打开文档之前做一些初始化动作。为了设置剩余文档的水印、页首、页脚、页号和尺寸,同样要使用这一动作。
当你调用以下的方法:
public boolean setPageSize(Rectangle pageSize)
public boolean add(Watermark watermark)
public void removeWatermark()
public void setHeader(HeaderFooter header)
public void resetHeader()
public void setFooter(HeaderFooter footer)
public void resetFooter()
public void resetPageCount()
public void setPageCount(int pageN)
这些方法的结果只会出现在下一页(当这一页的初始化方法被调用时),这个可以参考例7,如果你想测试这一例子,你将需要watermark.jpg文件,结果是chap0107.pdf。
视图样式
对于pdf文件,你可能需要以下的方法设置视图的查看样式:
public void setViewerPreferences(int preferences)
在例8中,可参见以下方法:
writerA.setViewerPreferences(PdfWriter.PageLayoutTwoColumnLeft);
writerB.setViewerPreferences(PdfWriter.HideMenubar|PdfWriter.HideToolbar);
writerC.setViewerPreferences(PdfWriter.PageLayoutTwoColumnLeft|PdfWriter.PageModeFullScreen | PdfWriter.NonFullScreenPageModeUseThumbs);
正如你所看到的,这些参数可以设置为一些常量:
当文档被打开时,页面的规划将被用到(选择一种)
PdfWriter.PageLayoutSinglePage –一次显示一页
PdfWriter.PageLayoutOneColumn – 用一列显示所有页
PdfWriter.PageLayoutTwoColumnLeft – 用两列显示所有页,奇数页在左列
PdfWriter.PageLayoutTwoColumnRight - 用两列显示所有页,奇数页在右列
当文档打开时,文档的页面模式(选择一种)
PdfWriter.PageModeUseNone – 无文档大纲和文档缩略图
PdfWriter.PageModeUseOutlines – 文档大纲可见.
PdfWriter.PageModeUseThumbs – 缩略图可见
PdfWriter.PageModeFullScreen – 全屏模式,无菜单条,window控制,或是其他窗体
PdfWriter.HideToolbar – 用于设定当文档激活时,视图的应用程序工具栏是否可见
PdfWriter.HideMenubar -用于设定当文档激活时,视图的应用程序菜单条是否可见
PdfWriter.HideWindowUI – 用于设定在文档窗口中是否隐藏用户接口(例如滚动条和导航控制),只显示文档的内容。
PdfWriter.FitWindow – 用于设定文档的窗口是否适合显示的第一页大小
PdfWriter.CenterWindow – 用于设定文档的窗口是否处于屏幕的中央
文档的页面模式,定义了在一个存在的全屏模式下,文档应如何显示。这只有在页面模式是
PageModeFullScreen 的情况下才有意义.
PdfWriter.NonFullScreenPageModeUseNone -无文档大纲和文档缩略图
PdfWriter.NonFullScreenPageModeUseOutlines -文档大纲可见
PdfWriter.NonFullScreenPageModeUseThumbs -缩略图可见
注意:你只可以从PdfWriter这个类才可以调用这些方法。
加密
在你打开文档的另一件事情就是设置加密(也就是说:你想让pdf文件时加密的),为了达到这个目的,你需要使用下列的方法:
public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions);
strength是下列两个常量中的一个:
PdfWriter.STRENGTH40BITS: 40位
PdfWriter.STRENGTH128BITS: 128位 (只在 Acrobat Reader 5.0 或是更高的版本)
userPassword和ownerPassword可以是空或是0长度,在这种情况下ownerPassword被一个随机的字符串所取代。
Permissions设置为下列常量的或
PdfWriter.AllowPrinting
PdfWriter.AllowModifyContents
PdfWriter.AllowCopy
PdfWriter.AllowModifyAnnotations
PdfWriter.AllowFillIn
PdfWriter.AllowScreenReaders
PdfWriter.AllowAssembly
PdfWriter.AllowDegradedPrinting
这个功能显示在例9和例10
writer.setEncryption(PdfWriter.STRENGTH40BITS, null, null, PdfWriter.AllowCopy);chap0109.pdf可以不用密码打开,但是用户不可以打印、调整文档
writer.setEncryption(PdfWriter.STRENGTH128BITS, "userpass", "ownerpass", PdfWriter.AllowCopy | PdfWriter.AllowPrinting);但你打开chap0110.pdf时,你被要求提供密码(输入‘userpass’),因为加入了AllowPrinting-preference,你可以没有任何问题的打印文档。
测试步骤4:添加内容
在解释步骤1至3的不同例子中,