如何使用iText在每个页面上添加总页数?

如何使用iText在每个页面上添加总页数?

  1. 首先使用虚拟页面计数将PdfWriter的输出处理为bytestream
  2. 从该bytestream创建PdfReader ,调用PdfReader.getNumberOfPages以获取实际的页数。
  3. 重新创建PDF输出,知道页数是多少,相应地更改页脚。

这很麻烦,但没有简单的方法可以在没有两遍方法的情况下知道页数。 有关操作PDF的详细信息,请参阅示例代码 。

您可以创建一个inheritance自PdfPageEventHelper的类,然后覆盖这两个函数,如下所示:

 Imports System.Collections.Generic Imports System.Text Imports iTextSharp.text.pdf Imports iTextSharp.text Namespace PDF_EnteteEtPiedDePage Public Class EnteteEtPiedDePage Inherits PdfPageEventHelper ' This is the contentbyte object of the writer Private cb As PdfContentByte ' we will put the final number of pages in a template Private template As PdfTemplate ' this is the BaseFont we are going to use for the header / footer Private bf As BaseFont = Nothing ' This keeps track of the creation time Private PrintTime As DateTime = DateTime.Now ' we override the onOpenDocument method Public Overrides Sub OnOpenDocument(writer As PdfWriter, document As Document) Try PrintTime = DateTime.Now bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED) cb = writer.DirectContent template = cb.CreateTemplate(50, 50) Catch de As DocumentException Catch ioe As System.IO.IOException End Try End Sub Public Overrides Sub OnStartPage(writer As PdfWriter, document As Document) MyBase.OnStartPage(writer, document) Dim pageSize As Rectangle = document.PageSize End Sub Public Overrides Sub OnEndPage(writer As PdfWriter, document As Document) MyBase.OnEndPage(writer, document) Dim pageN As Integer = writer.PageNumber Dim text As [String] = "Page " & pageN & " de " Dim len As Single = bf.GetWidthPoint(text, 8) Dim pageSize As Rectangle = document.PageSize cb.SetRGBColorFill(100, 100, 100) cb.BeginText() cb.SetFontAndSize(bf, 8) cb.SetTextMatrix(pageSize.GetLeft(40), pageSize.GetBottom(30)) cb.ShowText(text) cb.EndText() cb.AddTemplate(template, pageSize.GetLeft(40) + len, pageSize.GetBottom(30)) cb.BeginText() cb.SetFontAndSize(bf, 8) cb.ShowTextAligned(PdfContentByte.ALIGN_RIGHT, "Imprimé le : " & PrintTime.ToShortDateString() & " à " & PrintTime.ToShortTimeString, pageSize.GetRight(40), pageSize.GetBottom(30), 0) cb.EndText() End Sub Public Overrides Sub OnCloseDocument(writer As PdfWriter, document As Document) MyBase.OnCloseDocument(writer, document) template.BeginText() template.SetFontAndSize(bf, 8) template.SetTextMatrix(0, 0) template.ShowText("" & Convert.ToString((writer.PageNumber - 1))) template.EndText() End Sub End Class End Namespace 

之后,只需设置pdfwriter PageEvent的值,如下所示:

 Dim PageEventHandler = New EnteteEtPiedDePage() aPdfWriter.PageEvent = PageEventHandler 

不再搜索,这是解决方案。 如果他们删除此链接,我会将代码发布到我的网站并托管链接。

iText页码示例

这是我使用的代码。 将页面写入输出不会增加太多开销。

 outputStream = new ByteArrayOutputStream(); output = new DataOutputStream(outputStream); document = new Document(); writer = PdfWriter.getInstance(document, output); document.open(); contentByte = writer.getDirectContent(); ....add stuff document.close(); writer.close(); byte[] output = outputStream.toByteArray(); PdfReader reader = new PdfReader(output); //reset the output outputStream = new ByteArrayOutputStream(); output = new DataOutputStream(outputStream); document = new Document(); writer = PdfWriter.getInstance(document, output); document.open(); PdfStamper stamper = new PdfStamper(reader, outputStream); //add the pages for (int i = 1; i <= pageCount; i++) { contentByte = stamper.getOverContent(i); addParagraph("Page " + i + " of " + pageCount, new Point(500, 30), boldTextFont); // my own paragraph font } stamper.close(); 

通过快速的网络搜索提醒自己这一点; 看一眼

一旦你到达文档的末尾,相关的方法是onEndPage()产生“X”和onCloseDocument()以产生“Y”。

这是一个方便的function! (基于Milhous的方法)(这使用了itext版本4.1.6.0)

 public static byte[] AddPageNumbers(byte[] pdf) { PdfReader reader = new PdfReader(pdf); var Pages = reader.NumberOfPages; MemoryStream ms = new MemoryStream(); PdfStamper stamper = new PdfStamper(reader, ms); for (int i = 1; i <= Pages; i++) { PdfContentByte overContent; Font Signature = FontFactory.GetFont("Calibiri", 9, iTextSharp.text.Font.NORMAL, Color.BLACK); overContent = stamper.GetOverContent(i); var helv = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED); overContent.SaveState(); overContent.BeginText(); overContent.SetFontAndSize(helv, 10.0f); overContent.SetTextMatrix(PageSize.LETTER.Width / 2 - 20, PageSize.LETTER.Height - (PageSize.LETTER.Height - 20)); overContent.ShowText("Page " + (i) + " of " + Pages); overContent.EndText(); overContent.RestoreState(); } stamper.Close(); return ms.ToArray(); } 

试试这个,因为我也遭受了这个,我也新建这个库所以经过很多麻烦我得到的结果只是尝试应用逻辑两次,如我在评论中提到的。

 class PdfReportServlet extends HttpServlet { public static int total = 0; public static int getTotal() { return total; } public static void setTotal(int total) { PdfReportServlet .total = total; } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String reportFor = request.getParameter("report"); if(!"".equals(reportFor)) { if(reportFor.equals("pdf")) { /* from here logic starts */ response.setContentType("application/pdf"); Document document = new Document(PageSize.LETTER.rotate()); try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); PdfWriter pdfWriter = PdfWriter.getInstance(document, bos); PdfReport pdfReport = new PdfReport(); pdfWriter.setPageEvent(pdfReport); document.open(); String id = request.getParameter("id"); DettagliFamigliaPDFReport.generatePDFReport(document,id); document.close(); /* * now again give new references to Document and PdfWriter classes. */ document = new Document(PageSize.LETTER.rotate()); pdfWriter = PdfWriter.getInstance(document, response.getOutputStream()); PDFReport.setTotalPages(getTotal());/*##PAGES_TOTAL here i set total Pages which i get from above logic */ PdfReport pdfReport = new PdfReport(); pdfWriter.setPageEvent(pdfReport); document.open(); id = request.getParameter("id"); PDFReport.generatePDFReport(document,id); document.close(); } catch(DocumentException de){ de.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } } } /* Here below i write the class inherits the PdfPageEventHelper class and also having generatePDFReport() method. */ public class PDFReport extends PdfPageEventHelper { public static PdfTemplate template; public static int totalPages=0; public static int getTotalPages() { return totalPages; } public static void setTotalPages(int totalPages) { DettagliFamigliaPDFReport.totalPages = totalPages; } public static void generatePDFReport(Document document,String id) { // here your data to write on page of pdf. } @Override public void onOpenDocument(PdfWriter writer, Document doc) { template = writer.getDirectContent().createTemplate(100, 100); } int totalPage = 0; @Override public void onCloseDocument(PdfWriter writer, Document doc) { totalPage = writer.getPageNumber() - 1;/* at the end this method calls and you will get total number of pages.*/ PdfReportServlet.setTotal(totalPage); /* while first time logic of servlet executes then i set the total pages to servlet's variable using this logic. and second time servlet's logic is executing i passed totalPages to this class variable where i marked ##PAGES_TOTAL */ } @Override public void onStartPage(PdfWriter writer, Document doc) { // Here i write header logic when each time page starts. } @Override`enter code here` public void onEndPage(PdfWriter writer, Document doc) { Rectangle rect = writer.getPageSize(); float width = rect.getWidth()/2; DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); Date date = new Date(); String footerOne = "This document is printed on date "+dateFormat.format(date)+" - Page. "+writer.getPageNumber()+" of "+getTotalPages(); Paragraph paraOne = new Paragraph(footerOne); Font fontFooter = new Font(); fontFooter.setSize(8); fontFooter.setColor(Color.gray); paraOne.setFont(fontFooter); Phrase footerPhraseOne = new Phrase(paraOne); ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, footerPhraseOne, width, 30, 0); } } 

这是您的代码片段:

 final PdfWriter writer = PdfWriter.getInstance(document, outputStream); writer.setPageEvent(new PageStamper()); 

编号代码:

 import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; import com.itextpdf.tool.xml.*; import com.itextpdf.tool.xml.css.*; import java.io.IOException; /** * Adds page number to al the pages except the first. */ public class PageStamper extends PdfPageEventHelper { private static final Logger logger = Logger.getLogger(PageStamper.class); @Override public void onEndPage(PdfWriter writer, Document document) { final int currentPageNumber = writer.getCurrentPageNumber(); if (currentPageNumber == 1) { return; } try { final Rectangle pageSize = document.getPageSize(); final PdfContentByte directContent = writer.getDirectContent(); directContent.setColorFill(BaseColor.GRAY); directContent.setFontAndSize(BaseFont.createFont(), 10); directContent.setTextMatrix(pageSize.getRight(40), pageSize.getBottom(30)); directContent.showText(String.valueOf(currentPageNumber)); } catch (DocumentException | IOException e) { logger.error("PDF generation error", e); } } } 

此代码可在此处找到: http : //blog.abelsky.com/2014/01/22/adding-page-number-to-itext-generated-pdf/ 。 非常感谢你,andy722

正如其他答案所示,您首先需要创建pdf,然后查看您创建的pdf包含的页数,然后将页脚添加到每个页面。 执行此操作的理想类是PdfStamper,其目的是向现有pdf /现有pdf页面添加其他元素。

以下是基于Milhous示例的精心设计示例:

 Font smallFont = FontFactory.getFont("Arial", 9, Font.NORMAL); ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream(); Document document = new Document(PageSize.A4, 70, 70, 40, 40); PdfWriter pdfWriter = PdfWriter.getInstance(document, pdfOutputStream); document.open(); //CREATE PDF HERE - ADD CONTENT TO DOCUMENT document.close(); int pageCount = pdfWriter.getPageNumber()-1; byte[] pdfAsBytes = pdfOutputStream.toByteArray(); //add footer PdfReader reader = new PdfReader(pdfAsBytes); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); DataOutputStream output = new DataOutputStream(outputStream); document = new Document(); document.open(); PdfStamper stamper = new PdfStamper(reader, output); for (int i = 1; i <= pageCount; i++) { ColumnText.showTextAligned(stamper.getOverContent(i), Element.ALIGN_CENTER, new Phrase(i+"/" + pageCount, smallFont), 550, 30, 0); } stamper.close(); byte[] finalPdfAsBytes = outputStream.toByteArray(); 

这是用Java编译的Rama代码(至少是它的一部分)

 public class test extends PdfPageEventHelper{ private int _pg = 0; private BaseFont font; @Override public void onEndPage(PdfWriter writer, Document document) { _pg++; PdfContentByte cb = writer.getDirectContent(); cb.beginText(); try { Rectangle pageSize = document.getPageSize(); cb.setFontAndSize(font, 8); cb.setTextMatrix(pageSize.getLeft(40), pageSize.getBottom(15)); String s = "Page " + _pg + "/"; cb.showText(s); cb.addTemplate(template, pageSize.getLeft(40) + font.getWidthPoint(s, 8), pageSize.getBottom(15)); } catch (Exception exc) { logger.warn("got Exception : " + exc.getMessage()); } cb.endText(); } @Override public void onOpenDocument(PdfWriter writer, Document document) { super.onOpenDocument(writer, document); template = writer.getDirectContent().createTemplate(50, 50); try { font = BaseFont.createFont(BaseFont.COURIER, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED); } catch (Exception exc) { logger.warn("got Exception : " + exc.getMessage()); } } @Override public void onCloseDocument(PdfWriter writer, Document document) { super.onCloseDocument(writer, document); template.beginText(); try { template.setFontAndSize(font, 8); template.setTextMatrix(0f, 0f); template.showText("" + (writer.getPageNumber() - 1)); } catch (Exception ex) { logger.error(ex); } template.endText(); } }