itext pdftemplate使用

在开发系统时,需要在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
 
方法
功能
onCloseDocumentCalled when the document is closed.
onEndPage

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

onOpenDocumentCalled 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();
			} 
		}
 

 

 

 

 

 

 

 

 

 

 

使用iText库可以轻松实现使用模板生成PDF并插入图片的功能。首先,你需要准备好一个样板PDF文件作为模板。然后,你可以使用iText库中的相关类和方法来加载这个样板PDF文件,并在指定位置插入图片。 首先,你需要导入iText库的相关依赖。然后,通过创建一个PdfReader对象来加载样板PDF文件。接下来,你可以通过创建一个PdfStamper对象,并使用该对象的getOverContent方法来获取PDF页面的内容,以便在指定位置插入图片。 在插入图片之前,你需要通过创建一个Image对象来加载你要插入的图片文件。然后,你可以使用PdfContentByte类的addImage方法将图片插入到PDF文件中。 以下是一个简单的示例代码,演示了如何使用iText使用模板生成PDF并插入图片的过程: ```java import com.itextpdf.text.DocumentException; import com.itextpdf.text.Image; import com.itextpdf.text.pdf.*; import java.io.FileOutputStream; import java.io.IOException; public class PdfGenerator { public static void main(String[] args) { try { // 加载样板PDF文件 PdfReader reader = new PdfReader("template.pdf"); // 创建PdfStamper对象,并指定输出文件 PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("output.pdf")); // 获取第一页内容 PdfContentByte content = stamper.getOverContent(1); // 加载要插入的图片 Image image = Image.getInstance("image.jpg"); // 设置图片位置和大小 image.setAbsolutePosition(100, 100); image.scaleAbsolute(200, 200); // 将图片插入到PDF文件中 content.addImage(image); // 关闭PdfStamper对象 stamper.close(); // 关闭PdfReader对象 reader.close(); System.out.println("PDF生成成功!"); } catch (IOException | DocumentException e) { e.printStackTrace(); } } } ``` 在上述示例代码中,你需要将"template.pdf"替换为你的样板PDF文件的路径,"output.pdf"替换为生成的PDF文件的输出路径,"image.jpg"替换为你要插入的图片文件的路径。通过运行这个代码,你将会生成一个新的PDF文件,其中包含了插入的图片。 希望这个例子对你有所帮助!如果你还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值