在开发系统时,需要在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();
- }
- }
/* 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。
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);
protected PdfTemplate total; total = writer.getDirectContent().createTemplate(100, 100);
PdfPageEventHelper
PageXofY是继承自PdfPageEventHelper的,它覆盖了helper的三个方法onCloseDocument,onEndPage,onOpenDocument
- public class PageXofY extends PdfPageEventHelper
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);
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));
total.showText(String.valueOf(writer.getPageNumber() - 1));
在main函数中,通过writer设置event。
- writer.setPageEvent(new PageXofY());
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();
- }
- }
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(); } }
相关推荐
在这个场景中,我们将探讨如何使用iTextPDF来根据模板生成包含表单、表格、条形码和二维码的PDF文档。以下是一个详细的步骤和知识点介绍: 1. **引入iTextPDF库** 首先,你需要在你的项目中添加iTextPDF依赖。如果...
页眉和页脚可以通过自定义PdfPHeaderFooter实现,而水印则可以使用PdfTemplate和ColumnText在每一页上绘制。 ```java public void addHeaderAndFooter(PdfDocument pdfDoc) { PdfPage page = pdfDoc.getPage(1); ...
5. **PdfTemplate** 和 **ColumnText**:前者用于创建自定义的可重用元素,后者用于在PDF页面上排列多列文本。 6. **Image** 类:用于插入图像到PDF文档中,支持多种格式。 7. **AcroFields** 和 **...
1. iText相关的jar:这可能包括`itextpdf.jar`,这是iText的主要库,包含了创建和操作PDF的基本功能。 2. Freemarker的jar:例如`freemarker.jar`,这是Freemarker模板引擎的核心库。 3. XMLWorker的jar:例如`...
import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.*; public class PdfGenerator { public static void main(String[] args) throws Exception { // 加载模板 PdfReader reader = new Pdf...
<artifactId>itextpdf <version>5.x.x</version> <!-- 替换为实际版本号 --> ``` 确保使用的版本与项目兼容,并已正确导入。 4. **操作PDF** - **读取模板**:使用`PdfReader`类读取PDF模板文件,创建`...
官方提供了详细的下载和安装指南([访问链接](https://developers.itextpdf.com/itext7/download-and-install-information/))。 - 如果是Java项目,还可以通过Maven依赖进行集成。 #### 四、关键步骤解析 ##### ...
同时,注意版权问题,因为Itext对PDF的一些高级功能有授权限制,商业使用时需购买相应许可证。 总结起来,"Velocity+Itext导出PDF"是一种高效且灵活的方式,可以将动态数据和预定义的模板结合,生成高质量的PDF文档...
在标题中提到的"itext_itext_pdf编辑_",我们可以推断出这个话题主要关注的是如何使用iText库进行PDF文档的操作。iText 2.17是该库的一个版本,它提供了丰富的API和功能,使得开发者可以方便地在PDF文档中添加文本、...
`PdfTemplate`和`Canvas`类则提供了低级别的绘图功能,可以绘制自定义图形和线条。 对于更高级的应用,例如表单处理,iText的`PdfFormXObject`和`AcroFields`类可以帮助你创建和填写交互式PDF表单。你可以获取和...
<groupId>com.itextpdf</groupId> <artifactId>itext7-core <version>7.x.x <groupId>org.freemarker <artifactId>freemarker <version>2.x.x ``` 请替换`x.x.x`为最新版本号。 步骤二:创建...
该项目实现了使用IText将html文件转为pdf文件功能。 步骤: (1):将字体文件按代码中写的路径放到磁盘对应位置。 (2):将template.html文件按代码中路径放到磁盘对应位置。 (3):直接运行HtmlToPdfUtilForCss...
《使用iTextPDF5创建合同模板的实战指南》 在IT行业中,生成PDF文档是常见的需求,尤其是在处理法律文件、报告或合同等正式文档时。iText是一个强大的Java库,专门用于生成和处理PDF文档。本篇文章将深入探讨如何...
1. 加载PDF模板文件,获取AcroFields对象:`PdfReader reader = new PdfReader("template.pdf"); AcroFields fields = reader.getAcroFields();` 2. 查找表单字段:`String fieldName = "你的表单字段名";` 3. 填充...
本示例将探讨如何使用C#编程语言,结合iText7库,来创建符合规范的电子发票PDF文件。iText7是一个功能强大的PDF处理库,支持多种编程语言,包括.NET平台。 首先,`packages.config`文件列出了项目依赖的NuGet包,...
3. 加载PDF模板:使用`com.itextpdf.text.pdf.PdfReader`读取保存的PDF模板,并通过`com.itextpdf.text.pdf.PdfStamper`创建一个可写入的PDF对象,这将用于填充模板。 4. 填充表单字段:利用`PdfStamper....
<artifactId>itextpdf <version>5.x.x</version> <!-- 使用合适的版本 --> <groupId>org.apache.velocity <artifactId>velocity <version>1.x.x</version> <!-- 使用合适的版本 --> ``` 然后,创建一个...
# 本项目主要介绍 1. itextpdf(CreatePdf) ...对于不会HTML的制作,熟悉**itextpdf**的,完全可以使用PdfTemplate,该方法其实就是将itextpdf中PDF的元素逆解析 5. xdocreport 复杂word动态生成上功能很强大
在与 Velocity 结合使用时,iText 可以接受由 Velocity 渲染的模板,将动态数据填充到预先设计好的PDF模板中,生成具有个性化内容的PDF文件。 **Velocity** 是Apache软件基金会的一个项目,是一个Java模板引擎。它...
本篇文章将深入探讨如何在PDF中实现这一功能,主要使用iText库,这是一个强大的Java和.NET PDF处理库。 首先,我们需要了解iText库的基本概念。iText是一个开源项目,它提供了创建、修改和操作PDF文档的能力。通过...