pie pdfpageeventhelper pagina page number headers example encabezado java itext

java - pdfpageeventhelper - ¿Cómo agregar el número total de páginas en cada página con iText?



itext pagination example (10)

¿Cómo agregar el número total de páginas en cada página con iText?


  1. Procese primero la salida de un PdfWriter a un PdfWriter con un recuento de páginas ficticias.
  2. Cree un PdfReader desde ese bytestream , llamando a PdfReader.getNumberOfPages para obtener el recuento real de páginas.
  3. Vuelva a crear la salida de PDF, sabiendo cuál será el recuento de páginas, cambiando el pie de página en consecuencia.

Es complicado, pero no hay una manera fácil de saber el recuento de páginas sin un enfoque de dos pasos. Consulte el código de ejemplo para obtener detalles sobre la manipulación de archivos PDF.


¡Aquí está una función práctica! (Basado en el enfoque de Milhous) (esto utiliza la versión 4.1.6.0 de itext)

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


Aquí está el código que utilicé. No se agrega mucho a la sobrecarga para escribir las páginas en la salida.

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


Como lo indican las otras respuestas, primero deberá crear el pdf, luego ver cuántas páginas contiene el pdf que creó y luego agregar el pie de página a cada página. La clase ideal para hacer esto es PdfStamper, cuyo propósito es agregar elementos adicionales a un pdf existente / páginas pdf existentes.

Aquí hay un ejemplo elaborado basado en el ejemplo de 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();


De una rápida búsqueda en la web para recordarme esto; echa un vistazo a

Example

Los métodos relevantes son onEndPage() para producir la "X" y onCloseDocument() para producir la "Y" una vez que llegas al final del documento.


Este es el código Rama convertido en Java (al menos parte de él)

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


Este es un fragmento de tu código:

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

Y el código de numeración:

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

Este código se encontró aquí: http://blog.abelsky.com/2014/01/22/adding-page-number-to-itext-generated-pdf/ . Muchas gracias andy722


Intente esto porque también estaba sufriendo de esto y también he creado una nueva biblioteca, así que, después de muchos problemas, obtuve el resultado, solo intenté aplicar la lógica dos veces, como he mencionado en los comentarios.

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



Puede crear una clase que herede de PdfPageEventHelper luego anular estas dos funciones como esta:

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

Luego, después de eso, simplemente establezca el valor de su pdfwriter PageEvent siguiente manera:

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