`
reymont
  • 浏览: 526389 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

itext pdftemplate使用

    博客分类:
  • PDF
 
阅读更多

在开发系统时,需要在PDF上写入总页数。于是在网上搜索到

 

iText加入页码

 

这篇文章。但是仍然不知道PdfTemplate是什么使用的。

 

在Itext in action 2006版 第14章刚好有个这个例子(14.2.3 PageXofY)

 

/* chapter14/PageXofY.java */


import java.io.FileOutputStream;
import java.io.IOException;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.ExceptionConverter;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfPageEventHelper;
import com.lowagie.text.pdf.PdfTemplate;
import com.lowagie.text.pdf.PdfWriter;

/**
 * This example was written by Bruno Lowagie. It is part of the book 'iText in
 * Action' by Manning Publications. 
 * ISBN: 1932394796
 * http://itext.ugent.be/itext-in-action/ 
 * http://www.manning.com/lowagie/
 */

public class PageXofY extends PdfPageEventHelper {

	/** The PdfTemplate that contains the total number of pages. */
	protected PdfTemplate total;

	/** The font that will be used. */
	protected BaseFont helv;

	/**
	 * @see com.lowagie.text.pdf.PdfPageEvent#onOpenDocument(com.lowagie.text.pdf.PdfWriter,
	 *      com.lowagie.text.Document)
	 */
	public void onOpenDocument(PdfWriter writer, Document document) {
		total = writer.getDirectContent().createTemplate(100, 100);
		total.setBoundingBox(new Rectangle(-20, -20, 100, 100));
		try {
			helv = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI,
					BaseFont.NOT_EMBEDDED);
		} catch (Exception e) {
			throw new ExceptionConverter(e);
		}
	}

	/**
	 * @see com.lowagie.text.pdf.PdfPageEvent#onEndPage(com.lowagie.text.pdf.PdfWriter,
	 *      com.lowagie.text.Document)
	 */
	public void onEndPage(PdfWriter writer, Document document) {
		PdfContentByte cb = writer.getDirectContent();
		cb.saveState();
		String text = "Page " + writer.getPageNumber() + " of ";
		float textBase = document.bottom() - 20;
		float textSize = helv.getWidthPoint(text, 12);
		cb.beginText();
		cb.setFontAndSize(helv, 12);
		if ((writer.getPageNumber() % 2) == 1) {
			cb.setTextMatrix(document.left(), textBase);
			cb.showText(text);
			cb.endText();
			cb.addTemplate(total, document.left() + textSize, textBase);
		}
		// for even numbers, show the footer at the right
		else {
			float adjust = helv.getWidthPoint("0", 12);
			cb.setTextMatrix(document.right() - textSize - adjust, textBase);
			cb.showText(text);
			cb.endText();
			cb.addTemplate(total, document.right() - adjust, textBase);
		}
		cb.restoreState();
	}

	/**
	 * @see com.lowagie.text.pdf.PdfPageEvent#onCloseDocument(com.lowagie.text.pdf.PdfWriter,
	 *      com.lowagie.text.Document)
	 */
	public void onCloseDocument(PdfWriter writer, Document document) {
		total.beginText();
		total.setFontAndSize(helv, 12);
		total.setTextMatrix(0, 0);
		total.showText(String.valueOf(writer.getPageNumber() - 1));
		total.endText();
	}

	/**
	 * Generates a file with a header and a footer.
	 * 
	 * @param args
	 *            no arguments needed here
	 */
	public static void main(String[] args) {
		System.out.println("Chapter 14: Page X of Y Example");
		System.out.println("-> Creates a PDF file with page numbers.");
		System.out.println("-> jars needed: iText.jar");
		System.out.println("-> files generated in /results subdirectory:");
		System.out.println("   page_numbers.pdf");
		// step 1: creation of a document-object
		Document document = new Document();
		try {
			// step 2:
			PdfWriter writer = PdfWriter.getInstance(document,
					new FileOutputStream("resource/page_numbers.pdf"));
			writer.setViewerPreferences(PdfWriter.PageLayoutTwoColumnLeft);
			writer.setPageEvent(new PageXofY());
			document.setMargins(36, 36, 36, 54);
			// step 3:
			document.open();
			Paragraph p = new Paragraph();
			// step 4: we grab the ContentByte and do some stuff with it
			for (int k = 1; k <= 30; ++k) {
				p.add(new Phrase("Quick brown fox jumps over the lazy dog. "));
			}
			p.setAlignment(Element.ALIGN_JUSTIFIED);
			for (int k = 1; k <= 12; ++k) {
				document.add(p);
			}
		} catch (DocumentException de) {
			System.err.println(de.getMessage());
		} catch (IOException ioe) {
			System.err.println(ioe.getMessage());
		}
		document.close();
	}
}

 

那么我们一起看看这个PdfTemplate到底是怎么用的。

 

PdfTemplate

查看一下API,PdfTemplate继承自PdfContentByte,PdfContentByte大家如果使用itext应该比较熟悉。一般来说,PdfContentByte仅仅作为内部使用,通过它你可以使用原生的pdf 语法来生产pdf。而PdfTemplate只不过是基于PdfContentByte,实现了XObject。

 

 

com.lowagie.text.pdf.PdfContentByte

 

PdfContentByte is an object containing the user positioned text and graphic contents of a page. It knows how to apply the proper font encoding.

 

那么XObject是什么呢?

 

PS:下载链接

 

http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference13.pdf

 

 

根据pdf reference v1.3 4.7小节描述:

An external object (commonly called an XObject) is a graphics object whose con-
tents are defined by a self-contained content stream, separate from the content
stream in which it is used. There are three types of external object:
• An  image XObject (Section 4.8.4, “Image Dictionaries”) represents a sampled
visual image such as a photograph.
• A form XObject (Section 4.9, “Form XObjects”) is a self-contained description
of an arbitrary sequence of graphics objects.
• A PostScript XObject (Section 4.10, “PostScript XObjects”) contains a fragment
of code expressed in the PostScript page description language.

 

一共就有三种XObject。而PdfTemplate就是Form XObject的实现。

 

Form XObject

Form XObject在pdf reference v1.3 4.9小节。

 

A form XObject is a self-contained description of any sequence of graphics objects
(including path objects, text objects, and sampled images), defined as a PDF
content stream. It may be painted multiple times—either on several pages or at
several locations on the same page—and will produce the same output each time,
subject only to the graphics state at the time it is invoked. Not only is this shared
definition economical to represent in the PDF file, but under suitable circum-
stances, the PDF viewer can optimize execution by caching the results of render-
ing the form XObject for repeated reuse.

 

PdfTemplate

 

现在我们的重头戏来了。让我们回到Itext in action 2006 10.4.2小节 。其实我们可以把PdfTemplate当成一个截图工具。如下:创建了一个宽100pt,高100pt的PdfTemplate

 

protected PdfTemplate total;
total = writer.getDirectContent().createTemplate(100, 100);

PdfPageEventHelper

PageXofY是继承自PdfPageEventHelper的,它覆盖了helper的三个方法onCloseDocument,onEndPage,onOpenDocument

 

public class PageXofY extends PdfPageEventHelper
 
方法
功能
onCloseDocument Called when the document is closed.
onEndPage

Called when a page is finished, just before being written to the document.

onOpenDocument Called when the document is opened.

 

PageXofY

在PageXofY中使用了onOpenDocument创建了PdfTemplate,初始化了BaseFont。

在PageXofY中使用了onEndPage将onOpenDocument创建的PdfTemplate固定在某个位置。

 

cb.addTemplate(total, document.left() + textSize, textBase);

cb.addTemplate(total, document.right() - adjust, textBase);

 在PageXofY中使用了onCloseDocument将最终的页数写入到PdfTemplate。在关闭document前那一页就是总页数。通过writer.getPageNumber-1获得。

 

total.showText(String.valueOf(writer.getPageNumber() - 1));
 

在main函数中,通过writer设置event。

 

writer.setPageEvent(new PageXofY());

 

那么,writer每写一页就会调用onEndPage一次。那么如果你只需要在第一页写总页数,那么onEndPage就可以这样改写:

 

		public void onEndPage(PdfWriter writer, Document document) {
			try {			
				if(writer.getPageNumber()==1){
					tpl = writer.getDirectContent().createTemplate(100, 100);
					tpl.setBoundingBox(new Rectangle(-20, -20, 100, 100));
					PdfContentByte cb = writer.getDirectContent();
					cb.addTemplate(tpl, document.right()-100, document.top()-15);
				}
				logger.info("Success add SanitationContainer image title");
			} catch (DocumentException e) {
				logger.error("Fail to add SanitationContainer image title");
				e.printStackTrace();
			} 
		}
 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics