C#导出PDF文件《二》

5. table.Cellspacing = 5;     我们设置了表格的间距,就是单元格和表格边界间的一定数量的空间,不同的单元格间使用了半数空间,具体代码见示例代码0506

Cell cell = new Cell("header");

cell.Header = true;

cell.Colspan = 3;

table.addCell(cell);

10. cell = new Cell("example cell with colspan 1 and rowspan 2");

cell.Rowspan = 2;

cell.BorderColor = new Color(255, 0, 0);

table.addCell(cell);

table.addCell("1.1");

15. table.addCell("2.1");

table.addCell("1.2");

table.addCell("2.2");

 table.addCell("cell test1");

cell = new Cell("big cell");

20. cell.Rowspan = 2;

cell.Colspan = 2;

cell.BackgroundColor = new Color(0xC0, 0xC0, 0xC0);

table.addCell(cell);

 table.addCell("cell test2");

 25. document.Add(table);

1.单元格间距和填距

在第4行中,我们设置了表格的填距,就是单元格边界和内容间一定数量的空间,在前面的示例中,我们看到文本紧贴边界,通过使用用特定的填距,就可以避免。

2.对齐方式

在示例代码0506中,我们也改变了单元格“big cell”的对齐方式: cell.HorizontalAlignment = Element.ALIGN_CENTER; cell.VerticalAlignment = Element.ALIGN_MIDDLE; 注:不能总是相信垂直对齐方式。

 3. 边框

如果我们象在第14行中那样添加了一个单元格,将使用默认的单元格布局(默认的布局可以SetDefalut方法改变),如果我们使用了Cell对象,我们可以控制每一个单元格的布局。 在第2和第三中,我们设置整个表格的边框宽度和边框颜色,我们在单元格上可以使用的方法,在12行中,每个单元格用“box”作为边界绘制(就象在HTML中),但是示例代码0507显示,我们在PDF中有大量更多可能。

4. 颜色

 在第22行中,你也能定义单元格的背景色,在示例代码0507中,我们不使用颜色只是用一定灰度填充。 u 行跨和列跨 最后,你也能设置单元格的行跨(11/20行)和列跨(8/21列)。通过这种方法可以将几个单元格合并成一个大的单元格。

5.备注

 第7行在PDF中没有意义,用于生成HTML,在HTML中并不是总能产生同样的布局,PDF表格有点象: header example cell with colspan 1 and rowspan 2 1.1 2.1 1.2 2.2 cell test1 big cell cell test2 

6. 表格分割

如果一个表格不能放在一页中,将自动被分割,示例代码0508显示了当一个表格到达页边时发生的情况,这将在下一节中解释。 大表格 跨越几页的表格将自动被分割成不同的部分。示例代码0509显示了一个跨越多页的报表。该报表有一个表头,如果你希望这个表头在每页都出现,你可以用endHeaders()方法标记表头区域的结束点,见示例代码0510。 为做这样的报表,建议设置单元格间距为0和仅使用指定的填距。 你可能已经注意到了,当一个表格被分割时,一些边界好象丢失了。这是因为单元格在前一页被完整地绘制了而不会传递给下一页。

7. 强行将一个表格或单元格布置到一页上

有有些情况下,你可能希望避免单元格或者整个表被拆分成两个部分,示例代码0511差不多和示例代码0508完全一样,但我们设置了参数TableHasToFit为true,看看示例代码0508和示例代码0511结果区别。在示例代码0512中我们修改了示例代码0510的CellsHaveToFit属性为true,比较两个示例产生结果的区别。

8.内存管理

当我们添加一个对象到文档时,该对象一有可能就写入了输出流,但当创建一个表格时,该Table对象一直保存着,对于真正的大表格,这将成为一个问题。 同样,当你正写一个HttpServletResponse对象到输出流时,浏览器也可能超时。这就是为什么你自己用fitsPage()方法控制表分割是有用的,示例代码0513告诉你如何做。

9.嵌套表格

有两种方法嵌套表格,第一种是利用insertTable方法明确地将一个表格插入到另外一个表格,示例代码0514显示了通过插入到其他表格的办法创建的5个表格。正如你看到的在前面两个表中,所有空的单元格自动得到分割,因为改变了原来的表格。如果一个单元格不空,列跨度和(或)行跨度将自动调整到新的位置,页面上第三个表格显示所有原表中列的相关宽度都得到了保护,第四个表格显示我们可以在插入了表格后添加其他单元格:该单元格自由地添加到下一个单元格中。

10.最后是一个深度嵌套的表格

当你使用insertTable方法时,插入表的宽度百分比不会被考虑,如果你希望插入表仅占单元格的80%(这是默认的宽度百分比),你不得不在单元格中绕排,见示例代码0515,这也是让一个表结合其他数据存放在同一个单元格中的唯一办法,见示例代码0516。

备注:你只能将一个表格插入到列跨度和行跨度均为1的单元格中。

11.表格偏移 当一个表格被添加到文档之前,以当前间距为准的新行将被添加(如前一个插入对象的间距)。有时因为前一个插入对象和当前表格间的间距过大或过小你并不希望这样做,如果你想改变这个空间,你不得不设置表格偏移,如示例代码0517。

12.表格的绝对位置 iTextSharp.text.Table是一个通过标准方法创建表格的相当简单的类,但有时你希望表格有一些特殊的行为,这种情况下你将使用更复杂的类com.lowagie.text.pdf.PdfPTable,示例代码0518是一个非常简单的例子,在第十章和十二章中将有一些更复杂的例子。

第六章 图片

1.Image对象

如果你学习过API,你可能已经注意到可以通过几种构造函数来创建图片,本手册中,我们将仅仅告诉你最简单的解决方案,如访问通过文件名或URL确定的图片生成的Image对象。 public static Image getInstance(Uri url) public static Image getInstance(string filename) Image是一个抽象类,故得到实例的方法将判断给出的图片的类别(GIF、Jpeg、PNG……)并返回对象的类别Gif、Jpeg、Png……,一些图片会被忽略,如果你想知道哪些图片会被忽略,请查阅FAQ(http://www.lowagie.com/iText/faq.html#images)。

 1.1 通过URL得到图片实例

这是添加一个图片最简单的办法,见示例代码0601,我们添加了一个WMF、一个Gif、一个Jpeg和一个PNG图片到文档中,使用4个URL得到: Image wmf = Image.getInstance(new URL("../examples/harbour.wmf")); Image gif = Image.getInstance(new URL("../examples/vonnegut.gif")); Image jpeg = Image.getInstance(new URL("../examples/myKids.jpg")); Image png = Image.getInstance(new URL("../examples/hitchcock.png"));

备注:许多PDF库在插入一个图片前都将其解压缩并转换成位图格式,下面是几个我为什么不这样做的原因: 这将导致PDF文件增大,这样产生的PDF文件尺寸是不同图片文件尺寸总和的数十倍。 面临一个法律问题:LZW算法受专利保护,所以不允许使用这种算法来解压缩GIF等文件。

1.2 通过文件名得到图片实例

 通过简单地改变图片引用路径将示例代码0601改成示例代码0602: Image gif = Image.getInstance("vonnegut.gif"); Image jpeg = Image.getInstance("myKids.jpg"); Image png = Image.getInstance("hitchcock.png"); 同示例代码0601的区别只是该图象从本地获取而已,另外一个例子见示例代码0603。

1.3 图片的位置

1.3.1对齐方式

通过下面方法设置图片的对齐方式: Alignment = Image.RIGHT Alignment = Image.MIDDLE Alignment = Image.LEFT 参见示例代码0604。 我们将Vonnegut的图片放在右边,小孩的图片放在中间,hitchcock的图片放在左边。

1.3.2 图片和文本

另外,你还可以指定文本相对图片的环绕方式: Alignment = Image.RIGHT | Image.TEXTWRAP Alignment = Image.MIDDLE Alignment = Image.LEFT | Image.UNDERLYING 见示例代码0506,文字在Vonnegut图片的左侧,并不在我小孩的图处环绕,且排在Hitchcock图片的上面。 说明:该功能尚有一些BUG。

1.3.3绝对位置

当制作PDF文件时,你可能用到该方法: public void setAbsolutePosition(int absoluteX, int absoluteY) 将一个图片放要页面上一个绝对位置的代码见示例代码0606,我们在不同的坐标处添加了两幅图片,这里使用给定的坐标将图片放在了左下角,通过将图片的宽度和高度作为X和Y坐标将设置第一个图片,坐标的2倍设置第二个图片。

1.4缩放和旋转图片

1.4.1 缩放

有几种办法可以缩放图片: public void scaleAbsolute(int newWidth, int newHeight) public void scalePercent(int percent) public void scalePercent(int percentX, int percentY) public void scaleToFit(int fitWidth, int fitHeight) 小孩的图片大小为194×202象素,如果你想让图片小一些,你可以通过scaleAbsolute(97, 101)进行缩放,使用scalePercent(50)也能到达同样的效果。 还可以通过scaleAbsolute(194, 101)来减小,所以这些例子都放在了示例代码0607中。 

1.4.2对分辨率的影响

如果一个图片不经任何缩放,其分辨率(resolution)为72,如果该图片缩放比例为50%,则分辨率为144,如果有更低的缩放比,则分辨率将更大,因为象素相同但尺寸变得更小了。使用72/300=24%的比例放置一个300dpi的图片,例:你用300dpi扫描了一个5×5英寸的图片,图片结果为1500×1500象素(5×300),当你用24%(72/300=0.24)的比例将该图片放置到PDF文件中时,PDF中的图片将为5×5英寸1500X1500象素300dpi,该图片将始终为1500X1500象素而不管尺寸如何。

1.4.3旋转

可以通过下面的方法旋转图片 public void setRotation(double r) 详见示例代码0608。 原始图片数据 到目前为止,所有例子中使用的图片均来自地本地磁盘或者某个网站,但也可能使用包含图片信息的数组来得到图片的实例: public static Image getInstance(byte[] img) 该方法同前面方法的效果相同,返回一个新的Gif,Jpeg或者Png类别的Image对象。 在示例代码0609中,我们添加一个从一个Jpeg文件中读入到字节数组中的图片,很明显,使用其他getInstance方法得到实例更优越,但这仅仅是一个例子,该getInstance方法在动态创建那些根本不存在的图片时非常有用。 该例子也演示了如何创建和使用一个原始图片。 public static Image getInstance(int width, int height, int components, int bpc, byte data[]) 本例中创建了一个100×100象素的图片,因为每个象素用RGB描述,所以图片大小为100×100×3字节。 System.Drawing.Bitmap 示例代码0610是一个比较高级的话题,理由如下: 首次使用到了System.Drawing.Bitmap类。该类在.net框架中,可以使用更多类型的图片,如TIFF、GIF,而这些图片在iText中均不支持,你可以检查一下.net框架看看你需要的图片格式是否得到支持。

 前面的例子中,还有一些事情要注意:当添加一个图片时不会出现什么问题,文字始终浮于图片上面,本例中,我们希望图片浮在文字上面。这也是为什么我们将使用iTextSharp.text.pdf.PdfContentByte类的原因(见第十章)。 你将发现使用的图片为透明的gif格式,你可以到http://itextsharp.sourceforge.net/examples/h.gif下载得到。 TIFF和CCITT 示例代码0611也是一个比较高级的话题,例中转换一个TIFF文件到PDF文件。 u 图片遮罩 示例代码0613在,我们创建了一个用作遮罩的图片 3C 7E E7 C3 C3 E7 7E 3C 该图片尺寸为8×8象素,每组一个字节,使用makeMask()方法可以转换成遮罩。 byte maskr[] = {(byte)0x3c, (byte)0x7e, (byte)0xe7, (byte)0xc3, (byte)0xc3, (byte)0xe7, (byte)0x7e, (byte)0x3c}; Image mask = Image.getInstance(8, 8, 1, 1, maskr); mask.makeMask(); mask.setInvertMask(true); 我们可以用该遮罩直接遮住其他图片的一部分。 PdfContentByte cb = writer.DirectContent; Image image = Image.getInstance("vonnegut.gif"); image.ImageMask = mask; 或者我们将该遮罩用于模板遮罪中。 PdfContentByte cb = writer.DirectContent; cb.setRGBColorFill(255, 0, 0); cb.addImage(mask, mask.scaledWidth() * 8, 0, 0, mask.scaledHeight() * 8, 100, 400); 关于ContentByte对象更多信息请参见第十章。

1.5图片和其他对象

1.5.1 图片在块中

有时,可以方便地将图片置于块中,通过一定偏移将一个图片置于块中: Chunk ck = new Chunk(img, 0, -5); 具体代码见示例代码0614,我们可以添加该特殊图片块到短句、表格等,本例中的图片请到http://itextsharp.sourceforge.net/examples/pngnow.png下载。

 1.5.2 图片在表格中

 你可以将图片添加到单元格中,但有两个副作用: l 表格的宽度是确定,当图片超出单元格的宽度时,将自动缩小。 l 你不能进行文字绕排和为图片添加下划线。 参见示例代码0615。

1.5.3图片链接注释

如果你希望得到一个可点击的图片,或者想添加链接注释到图片上,你需要创建一个Annotation对象,并添加到图片上,你不需要指定位置(你可以使用0,0,0,0),该位置会内部更新以适合该图片。 gif.Annotation = new Annotation(0, 0, 0, 0, "Chap1102b.pdf", 3); jpeg.Annotation = new Annotation("picture", "These are my children", 0, 0, 0, 0); 参加示例代码0616。 第二部分 其他文档格式

第七章 XML和 (X)HTML

本章主要介绍了如何利用iText控件生成XLM文档和(X)HTML文档,但我们对这些并不感兴趣,故只介绍本章中提到的将XML转为PDF。 在第一章中,我们通过5步生产一个PDF文件,为了将一个XML文件转换为PDF文件,只需重写第3和第4步,第5步由解析器自动处理。 //第3步:创建一个解析器并设置文档句柄: iTextHandler h = new iTextHandler(document); //第4步,转换该文档: h.Parse("Chap0701.xml"); 示例代码见示例代码0702

第八章 RTF文件 RTF包

RTF包是基于iText包扩展出来的,允许iText除生成PDF文件外还可以输出RTF文件,除了一些在RTF包中不支持的特性外,大多数PDF文件特性都可以使用。 创建一个RTF文档 创建一个RTF文档和创建一个PDF文档方法是一样的,都是这基本的5步,唯一的区别是第2步中用RtfWriter代替了PdfWriter,见示例代码0801。

 第1步 创建一个the iTextSharp.text.Document对象的实例: Document document = new Document();

第2步 创建一个document的RtfWriter将document写入你选择的输出流: RtfWriter.getInstance(document, new FileStream("Chap0801.rtf"), FileMode.Create);

第3步 打开document: document.Open();

第4步 添加内容到document document.Add(new Paragraph("Hello World"));

第5步 关闭document document.Close(); 关于如何创建其他对象并添加到document中,请参见其他章节的内容。

不支持的特性 水印 阅读器参数 加密 内嵌字体 块间距 段落右缩排 列表右缩排 无圆点符号列表 嵌套表格 除JPEG和PNG的其他图片 RTF中扩展的页眉和页脚 写入RTF时无法在开始新页前通过setHeader方法改变文档的页眉或页脚,这里有两个办法来解决这个问题。 利用“Chapters”,添加一个新“chapter”到文档前,使用setHeader或setFooter,你可以在不同的“Chapters”中使用不同的页眉或页脚,见示例代码0802。 使用RtfHeaderFooters类。该类允许你设置4个页眉或页脚,并指定在哪页出现。你当然可以结合Chapter创建4个不同的页眉或页脚,见示例代码0803。

u 使用RtfHeaderFooters类

第1步创建一个RtfHeaderFooters类: RtfHeaderFooters headers = new RtfHeaderFooters();

第2步添加HeaderFooter对象 headers.Add(RtfHeaderFooters.LEFT_PAGES, new HeaderFooter(new Phrase("This header is only on left hand pages"))); headers.Add(RtfHeaderFooters.RIGHT_PAGES, new HeaderFooter(new Phrase("This header is only on right hand pages")));

第3步如同使用页眉页脚一样使用RtfHeaderFooters document.Header = headers; 使用RtfHeaderFooters.add(...)的常量: FIRST_PAGE: 在你文档的第一页使用该页眉或页脚。你将使用rtfWriter.HasTitlePage = true来完成 LEFT_PAGES: 所有左边页均使用该页眉或页脚 RIGHT_PAGES: 所有右边页均使用该页眉或页脚 ALL_PAGES: 所有页均使用该页眉或页脚,只有和FIRST_PAGE 结合使用才有意义。

 有一件事非常重要:如果你使用LEFT_PAGES或者RIGHT_PAGES来设置页眉或页脚,再使用ALL_PAGES,页眉和页脚均不会起作用。 表格效果见示例代码0804。

 第三部分 iText的高级应用

第九章 字体

本章原文讲了许多字体的使用技巧,但就是没有讲如何使用中文,因此,意义不大,再说,如果不支持中文,前面的也就白翻译了,因此,根据原文讲到的一些知识,我摸索出汉字的使用方法,自己写了本章内容,应该算是“原创”了吧^_^(哎呀!谁拿鸡蛋扔我……)。

 Windows中一般都是使用TrueType字体,每个中文版Windows操作系统均默认安装了宋体、仿宋、黑体和楷体四种字体,你还可以安装其他第三方字体,如安装了Office 2000后,会自动安装华文行楷等字体,比较奇怪的是,在PDF文件中插入了一种本计算机才有的字体,在打开PDF文件的计算机上虽然没有该字体,但仍然能正常显示!这有别于Word文件,Word文件将当前计算机中没有的字体一律用宋体代替,这大概是意外收获吧。

字体文件一般保存在windir\Fonts目录中,扩展名为TTF,还有扩展名为TTC的字体文件,也是TrueType字体,不过是一个集合,也就是里面有多种字体。下面列出windows2000简体中文版四种标准字体的文件名称: SIMSUN.TTC:宋体和新宋体 SIMKAI.TTF:楷体 SIMHEI.TTF:黑体 SIMFANG.TTF:仿宋体 TrueType字体应用 按下面的方法写入黑体字文字,大小为32磅:

 BaseFont bfHei = BaseFont.createFont(@"c:\winnt\fonts\SIMHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); Font font = new Font(bfHei, 32); String text = "这是黑体字测试!"; document.Add(new Paragraph(text, font));

不要管BaseFont.createFont方法第二、三个参数的意思,依葫芦画瓢就行了,第一个参数显示就是字体文件存放的位置。 后面的代码都非常好理解,不再赘述。 TruType字体集合的应用 字体集合的使用同上面差不多,只是在在createFont方中要指定使用哪种字体。如: BaseFont bfSun=BaseFont.createFont(@"c:\winnt\fonts\SIMSUN.TTC,1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); font = new Font(bfSun, 16); text = "这是字体集合中的新宋体测试!"; document.Add(new Paragraph(text, font)); 不难看出,在使用BaseFont.createFont方法时,第一个参数@"c:\winnt\fonts\SIMSUN.TTC,1"中多了一个“,1”,表示使用序号为1字体,序号为0的字体为宋体。 毕竟我们不是做排版软件,有了上面的办法就基本上够用了,真正很复杂的PDF文件制作,不妨做成XML文件(最简单的办法就是用Word排版,然后另存为web页了),然后按第七章的办法转换。 代码见示例代码0901。

 第十章 图象和文本的绝对位置

pdfContentByte 到目前为止,我们已经使用了简单的iText,我们已经添加了文本、图片、段落、章节、列表、表格等,没有涉及到布局问题。Itext分割文本到每页中,并将每个单词、句子、段落布置到页面上,但有时我们并不需要这种自动格式,有时我们希望将一些图象或者文本放置在某页的指定位置,为实现该功能,我们将使用PdfContentByte类。 为代替第一章,仅用PdfWriter类的getInstance方法是不够的,你必须真实地拥有一个PdfWriter对象,你可以通过在使用Writer对象中使用getDirectContent()方来得到该对象。例: PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("test.pdf")); PdfContentByte cb = writer.DirectContent; 说明:当你添加高级对象(如表格)时,两个PdfContentByte对象将被内部使用:一个用于文本,一个用用于图象(如边界或单元格背景)。文本绘制浮于图象的上面。 当你通过getDirectContent()方法直接使用PdfContentByte对象时,你所添加的所有对象都将浮于文本和图象。如果你想避免这种情况和希望添加内容在图象或文本的背后,你需要使用用getDirectContentUnder()方。

一句话,当一页完成时,4层的重叠遵照如下顺序: 1、 通过getDirectContentUnder()得到的PdfContentByte 2、 包含图象或高级对象的内部PdfContentByte 3、 病文本或高级对象的内部PdfContentByte 4、 通过getDirectContent()得到的PdfContentByte 简单图形

在示例代码1001中,绘制了一些简单图形,我们使用了诸如moveTo和lineTo方法来在移动到页面上当前位置然后画一条直线到其他位置。我们使用了诸如setLineWidth和setLineDash方法来改变直线的外观,如: cb.LineWidth = 10f; cb.moveTo(100, 700); cb.lineTo(200, 800); cb.stroke(); 说明:当你改变诸如颜色、线宽等属性时,只有你在调用stroke方法时才起作用。在例中绘制三角形时,我们设置颜色为绿色,在使用stroke方法前我们改变颜色为红色,则绘制三角形的结果为为红色而不是绿色,该例中还有矩形、圆等使用方法。 文本 当你想将文本写入ContentByte中时,你必须使用方法beginText()和endText,你也必须设置字体和尺寸。就象图形示例中一样,还有许多方法用于写入和放置文本,但你最需要的是方法showTextAligned和方法showText配合setTextMatrix。 例1: BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); cb.beginText(); cb.setFontAndSize(bf, 12); cb.showTextAligned(PdfContentByte.ALIGN_CENTER, text + "This text is centered", 250, 700, 0); cb.endText(); 例2: BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); cb.beginText(); cb.setFontAndSize(bf, 12); cb.setTextMatrix(100, 400); cb.showText("Text at position 100,400."); cb.endText(); 请参见示例代码1002。 模板(Form xObjects) 当我们在第四章讨论页眉和页脚时,我们定义了一小块添加到每一页的信息,实际上,该小块信息写到了文件的每一个新页上。这并不是最经济的解决方案,更好的办法是将该信息作为一个Form Xobject仅在文档中添加一次,在其可见位置重复出现。我达到该目的,我们将使用模板。

u 创建一个PdfTemplate u 创建PdfTemplate的最好方法是调用PdfContentByte对象中的createTemplate方法: PdfContentByte-object: PdfTemplate template = cb.createTemplate(500, 200); 这样,该模板的宽度为500,高度为200。 通过该模板我们可以做象PdfContentByte同样的事情 template.moveTo(0, 200); template.lineTo(500, 0); template.stroke(); template.beginText(); BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); template.setFontAndSize(bf, 12); template.setTextMatrix(100, 100); template.showText("Text at the position 100,100 (relative to the template!)"); template.endText(); u 添加一个模板到文档 通过象下面一样在绝对位置添加一个模板: cb.addTemplate(template, 0, 400); 你还可以做一些有趣的事情,如缩放或旋转他们: //将模板旋转90度 cb.addTemplate(template, 0, 1, -1, 0, 500, 200); // 缩放模板为50% cb.addTemplate(template, .5f, 0, 0, .5f, 100, 400); //缩放模板为200% cb.addTemplate(template, 2, 0, 0, 2, -200, 400); 具体演示见示例代码1003。

 u 第几页共几页 在一些情况下,你希望插入一些你在写本页时外壳无法知道的信息到文本中去,如:在一篇文档的第一页,你并不知道该文档共有几页。只能在完成了整个文档时才知道总的页数。当使用模板时,该问题就不存在了。在示例代码0103中,我们在添加模板到ContentByte前添加了一些信息到模板中,这是没有必要的。我们可以在任何时候添加信息到模板,因为iText添加Form Xobject是在PDF结束的地方(当通过close方法关闭该文档时调用)。示例代码1004显示了首先创建4页然后添加总到页数,该例非常简单和有用。

分栏 在本章以前,你已经掌握了如何将文本放在一个绝对位置,这种情况下,我们要确定文本的开始坐标。如果我们想知道文本的结束位置,我们得做一些计算工作。 现在我们要加一些文本到一个矩形框的内部,希望文本到达右边界时自动换行。超出矩形部分将不显示,可以通过ColumnText类实现。

举个例子: 为显示一个指定的短句在坐标(100, 300)和(200, 500)间的矩形内居中,我们使用下面的代码: PdfContentByte cb = writer.DirectContent; ColumnText ct = new ColumnText(cb); ct.setSimpleColumn(phrase, 60, 300, 100, 500, 15, Element.ALIGN_CENTER); ct.go();

通过查看示例代码1005,你会立即发现通过该方法可以可以画一些复杂的表格而无须Table对象。 另一个例子: 没有必要一次性将文本全部添加进去,你可以先定义一个矩形,然后添加一些文本,最后用go方法显示分栏。 PdfContentByte cb = writer.DirectContent; ColumnText ct = new ColumnText(cb); ct.setSim7pleColumn(60, 300, 100, 500, 15, Element.ALIGN_CENTER); ct.addText(phrase1); ct.addText(phrase2); ct.addText(phrase3); ct.go(); 详见示例代码1006。

多栏 当然,如果文本超出了矩形范围,我们并不想丢失这些多出的文本,或许我们想将这些文本显示到其他栏中。这就是为什么我们要查看go方法返回值的原因。如果返回标识为“NO_MORE_COLUMN”,表示该栏中没有足够的空间存放该文本,如果所有的文本均显示出来,标识将为“NO_MORE_TEXT”。 请参见示例代码1007。 不规则栏 定义一个非矩形的区域来显示栏也是可能的,通过使用setColumns方法,我们为文本定义了一个左右边界。 float[] left = {70,790, 70,60}; float[] right = {300,790, 300,700, 240,700, 240,590, 300,590, 300,106, 270,60}; ct.setColumns(left, right); 左边界是一条直线,而右边界是不规则的。该函数的结果可以导致一些非常有意思的布局,见示例代码1008,本例中你将用到一个名为caesar_coin.jpg的图片: PdfTable 在第5章中,我们简要地讲述了PdfPTable对象,现在我们将讨论该对象更多的的特性。

你可以用3种不同的方法创建PdfTable: PdfPTable(float[] relativeWidths); PdfPTable(int numColumns); PdfPTable(PdfPTable table);

你可以给该表设置更多的参数,如表宽度、列宽度、水平对齐方式等,你可以通过下面的办法添加单元格: public void addCell(PdfPCell cell); public void addCell(PdfPTable table); public void addCell(Phrase phrase); public void addCell(String text); 除了单元格填距和和间距,这些方法同Table对象非常类似。这些参数对每个单元格个体进行了设置,当然,你可以设置单元格的默认值,为改变单元格的默认值,使用getDefaultCell()和调用一个或更多的类PdfPCell的方法(你可以设置对齐方式、间距、边框、颜色甚至最低高度)。 注:通过PdfPTable,你能改变一个单元格的列跨度,但不能改变行跨度!在PdfPTable内部是一些独立的行,要让它支持行跨度更改需要对PdfPTable对象进行很大的调整,不要期望在近期内实现,你可以用嵌套表来解决这些问题。 你可以象第5章一样将一个PdfPTable添加到当前文档中,但你也可以添加一个表在当前页中的绝对位置: public float writeSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas); 参数rowStart是你想开始的行的数目,参数rowEnd是你想显示的最后的行(如果你想显示所有的行,用-1),xPos和yPos是表格的坐标,canvas是一个PdfContentByte对象。

在示例代码1009中,我们添加了一个表在(100,600)处: table.writeSelectedRows(0, -1, 100, 600, writer.DirectContent); 使用PdfPTable,你不能设置行跨度和(或)来跨度(怎么和上面的有点矛盾?)你可以使用嵌套表来解决,见示例代码1010。 最后,示例代码1011和示例代码1012展示了PdfTable可以和templates 和 columns一起使用,在示例代码1012中将用到cover.png图片如下: 颜色(SpotColors)和图案(Patterns) 颜色(spotcolors)的使用见示例代码1013,示例代码1014和示例代码1015演示了图案(patterns)的使用方法。

第十一章 本地和异地转向、目标和概要 本地转向

有时你需要一个允许读者从文档的一个地方跳转到另外一个地方的链接,你可以通过类Chunk的setLocalGoto 和setLocalDestination两个方法实现,例: Chunk localgoto = new Chunk("this word", FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL, new Color(0, 0, 255))).setLocalGoto("test"); Chunk destination = new Chunk("local destination", FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL, new Color(0, 255, 0))).setLocalDestination("test");

见示例代码1101。

异地转向 在第3章中,我们演示了一个锚点如何转向到其他URL,一个锚点通过不同的字体、风格和颜色,可以包含不同的Chunks,在iText的高级应用中,下面定义链接到URL的其他方法: Chunk chunk = new Chunk("anchor", FontFactory.getFont(FontFactory.HELVETICA, 12)).setAnchor(new URL("http://www.lowagie.com/iText/")); u 转到PDF文档中的指定位置 如果你在文档中指定了一个目的地,你可以从另外一个文档跳转到这里,为实现该功能,你可以使用方法: setRemoteGoto: Chunk chunk = new Chunk("jump", FontFactory.getFont(FontFactory.HELVETICA, 12, Font.ITALIC)).setRemoteGoto("test.pdf", "test")); test.pdf是另外一个pdf文件,”test”是该文件的一个目的地。 跳转到另一个PDF文件指定页 使用方法setRemoteGoto,用页码参数代替名称参数,可以非常容易地跳转定另外一个文档的指定页: chunk = new Chunk("jump", FontFactory.getFont(FontFactory.HELVETICA, 12, Font.ITALIC)).setRemoteGoto("test.pdf", 3)); 见示例代码1102 u 启动一个应用程序 可以使用下面的方法启动一个应用程序: public PdfAction(String application, String parameters, String operation, String defaultDir) 如果application为“c:/winnt/notepad.exe”(其余参数可以为null),你可以通过PDF文件中的链接来启动记事本程序。 u 文件和URL 如果你想跳转到其他文档或URL,你需要通过下面的构造函数之一创建一个: PdfAction(String filename, String name); PdfAction(String filename, int page); PdfAction(URL url); PdfAction(String url); 前面两个构造函数允许你跳转到文件的指定位置或页码,后两个构造函数允许你跳转到其他URL上。 其余部分略。

 第十二章 页面和表格事件 略

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值