Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3351812
  • 博文数量: 530
  • 博客积分: 13360
  • 博客等级: 上将
  • 技术积分: 5473
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-13 13:32
文章分类

全部博文(530)

文章存档

2017年(1)

2015年(2)

2013年(24)

2012年(20)

2011年(97)

2010年(240)

2009年(117)

2008年(12)

2007年(8)

2006年(9)

分类: Java

2011-12-31 11:37:03

1.概述
       iText5中并没有之前版本HeaderFooter对象设置页眉和页脚,可以利用PdfPageEventHelper来完成页眉页脚的设置工作。PdfPageEventHelper中包含以下事件处理器。
       onOpenDocument() — 当打开一个文档时触发,可以用于初始化文档的全局变量。
       onStartPage() — 当一个页面初始化时触发,可用于初始化页面的设置参数,但是注意这个函数触发时,该页面并没有创建好,不用利用这个函数添加内容,最好利用onEndPage()处理页面的初始化。
       onEndPage() — 在创建一个新页面完成但写入内容之前触发,是添加页眉、页脚、水印等最佳时机。
       onCloseDocument() — 在文档关闭之前触发,可以用于释放一些资源。

2.重载PdfPageEventHelper类
       定义一个类HeaderFooter,继承了父类PdfPageEventHelper
       在文档的每个页面中,必须定义一个Ractangle矩形,其中参数为art,这样在HeaderFooter类中就可以通过这个矩形,获取文档的边框位置,从而设置页眉和页脚。
代码如下:
  1. import com.itextpdf.text.Document;
  2. import com.itextpdf.text.Element;
  3. import com.itextpdf.text.Phrase;
  4. import com.itextpdf.text.Rectangle;
  5. import com.itextpdf.text.pdf.ColumnText;
  6. import com.itextpdf.text.pdf.PdfPageEventHelper;
  7. import com.itextpdf.text.pdf.PdfWriter;

  8. public class HeaderFooter extends PdfPageEventHelper{
  9.     public void onEndPage (PdfWriter writer, Document document) {
  10.         Rectangle rect = writer.getBoxSize("art");
  11.         switch(writer.getPageNumber() % 2) {
  12.         case 0:
  13.             ColumnText.showTextAligned(writer.getDirectContent(),
  14.                     Element.ALIGN_RIGHT, new Phrase("even header"),
  15.                     rect.getRight(), rect.getTop(), 0);
  16.             break;
  17.         case 1:
  18.             ColumnText.showTextAligned(writer.getDirectContent(),
  19.                     Element.ALIGN_LEFT, new Phrase("odd header"),
  20.                     rect.getLeft(), rect.getTop(), 0);
  21.             break;
  22.         }
  23.         ColumnText.showTextAligned(writer.getDirectContent(),
  24.                 Element.ALIGN_CENTER, new Phrase(String.format("page %d", writer.getPageNumber())),
  25.                 (rect.getLeft() + rect.getRight()) / 2, rect.getBottom() - 18, 0);
  26.     }
  27. }
调用代码如下
  1. import com.itext.HeaderFooter;
  2. import com.itextpdf.text.pdf.PdfPageEventHelper;
  3. import com.itextpdf.text.pdf.PdfWriter;
  4. import com.itextpdf.text.pdf.ColumnText;
  5. import com.itextpdf.text.*;
  6. import java.io.FileOutputStream;

  7. public class HeaderAndFooterDemo {
        public static void main(String[] args){
  8.         Document document = new Document(PageSize.A4, 50, 50, 50, 50);
  9.         try{
  10.             PdfWriter writer=PdfWriter.getInstance(document,
  11.                     new FileOutputStream("C:\\testHeaderAndFooter.pdf") );
  12.             Rectangle rect = new Rectangle(36, 54, 559, 788);
  13.             rect.setBorderColor(BaseColor.BLACK);
  14.             writer.setBoxSize("art", rect);
  15.             HeaderFooter header=new HeaderFooter();

  16.             writer.setPageEvent(header);
  17.             document.open();

  18.             document.newPage();
  19.             Paragraph par = new Paragraph("first paragraph");
  20.             document.add(par);

  21.             document.newPage();
  22.             Paragraph par2 = new Paragraph("second paragraph");
  23.             document.add(par2);

  24.             document.close();
  25.         }catch(Exception e){
  26.             e.printStackTrace();
  27.         }
  28.     }
  29. }

3. 解决第X页/共Y页问题
       我们通过PdfWriter中的getPageNumber()函数获取当前是第几页,但是没有办法获取文档共多少页。
        我们可以利用XObject对象,iText仅在调用释放模板方法后才将PdfTemplate写入到OutputStream中,否则对象将一直保存在内存中,直到关闭文档。
       我们可以给第1个页面添加template,直到最后一个页面才将内容写入到这个模板。
  1. import com.itextpdf.text.Document;
  2. import com.itextpdf.text.DocumentException;
  3. import com.itextpdf.text.Element;
  4. import com.itextpdf.text.ExceptionConverter;
  5. import com.itextpdf.text.Image;
  6. import com.itextpdf.text.Phrase;
  7. import com.itextpdf.text.Rectangle;
  8. import com.itextpdf.text.pdf.ColumnText;
  9. import com.itextpdf.text.pdf.PdfPCell;
  10. import com.itextpdf.text.pdf.PdfPTable;
  11. import com.itextpdf.text.pdf.PdfPageEventHelper;
  12. import com.itextpdf.text.pdf.PdfTemplate;
  13. import com.itextpdf.text.pdf.PdfWriter;

  14. public class TableHeader extends PdfPageEventHelper{
  15.     String header;
  16.     PdfTemplate total;
  17.     
  18.     public void setHeader(String header){
  19.      this.header=header;
  20.     }
  21.     
  22.     public void onOpenDocument(PdfWriter writer,Document document){
  23.         total = writer.getDirectContent().createTemplate(30,16);
  24.     }
  25.     
  26.     public void onEndPage (PdfWriter writer, Document document) {
  27.      PdfPTable table = new PdfPTable(3);
  28.      try{
  29.      table.setWidths(new int[]{24,24,2});
  30.      table.setTotalWidth(527);
  31.      table.setLockedWidth(true);
  32.      table.getDefaultCell().setFixedHeight(20);
  33.      table.getDefaultCell().setBorder(Rectangle.BOTTOM);

  34.      table.addCell(header);
  35.      table.getDefaultCell().setHorizontalAlignment(
  36.      Element.ALIGN_RIGHT);
  37.      table.addCell(String.format("page %d of",writer.getPageNumber()));
  38.      PdfPCell cell = new PdfPCell(Image.getInstance(total));
  39.      cell.setBorder(Rectangle.BOTTOM);
  40.      table.addCell(cell);
  41.      table.writeSelectedRows(0,-1,34,803,writer.getDirectContent());

  42.      }
  43.      catch(DocumentException de){
  44.      throw new ExceptionConverter(de);
  45.      }
  46.     }
  47.     
  48.     public void onCloseDocument(PdfWriter writer,Document document){
  49.         ColumnText.showTextAligned(total,Element.ALIGN_LEFT,new Phrase(String.valueOf(writer.getPageNumber()-1)),2,2,0);
  50.     
  51.     }
  52. }
调用代码如上面HeaderAndFooterDemo.java所示。


参考文献
1.Adding page events to PdfWriter (iText 5).
2iText5参考.
阅读(16750) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

nihaodsdwerwer_wew2015-09-08 18:09:52

感谢楼主,但是添加页眉,最好还是在onStartPage()的方法内添加,图片作为头部也没有问题,页脚最好还是按照楼主说的来办