5 Replies Latest reply on Dec 1, 2009 9:36 PM by marcio.dantas

    seam pdf - Page X of Y

    marcio.dantas

      Hi,


      i want to display in my pdf's footer generated by seam a Page X of Y text.


      The X value can be obtained by using the tag pageNumber. My problem is getting Y.


      I found this from iText:
      http://itextdocs.lowagie.com/tutorial/directcontent/pageevents/index.php


      I found other resources


      To work, I would have to catch the event of the document closing.
      Can this be done? Another ideas?


      Thanks

        • 1. Re: seam pdf - Page X of Y
          marcio.dantas

          Ignore the I found other resources!


          cheers

          • 2. Re: seam pdf - Page X of Y
            marcio.dantas

            Gentlemen,


            I found a way of doing the job. Don't know if is the best, but here it comes.


            My solution is based on the above link from iText (itext: page X of Y).


            To put it working with seam, I extended de UIDocument class, wich represents a seam pdf document.
            The encodeBegin method was overriden. In its new version, I call the former encodeBegin (required), set the page event listener in the pdf writer, and initialize the template and font that will be used to hold and print, respectively, the number of total pages at the onCloseDocument event.


            To use the new document in my pages I simply added a binding attribute to my template.
            Below, you'll find the code.


            New component:


            package br.gov.esaf.sgc.view;
            
            import java.io.IOException;
            
            import javax.faces.context.FacesContext;
            
            import org.jboss.seam.ScopeType;
            import org.jboss.seam.annotations.Name;
            import org.jboss.seam.annotations.Scope;
            import org.jboss.seam.pdf.ui.UIDocument;
            
            import com.lowagie.text.DocWriter;
            import com.lowagie.text.Document;
            import com.lowagie.text.DocumentException;
            import com.lowagie.text.ExceptionConverter;
            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;
            
            /**
             * PDF Document with "Page X of Y" footer.
             */
            @Name("documentoSeamPdf")
            @Scope(ScopeType.CONVERSATION)
            public class SeamPdfDocument extends UIDocument {
            
                /**
                 * Template que guarda o número total de páginas.
                 */
                private PdfTemplate templateTotalPaginas;
            
                /**
                 * A fonte que será usada.
                 * */
                private BaseFont fonte;
            
                /** {@inheritDoc} */
                @Override
                public void encodeBegin(FacesContext context) throws IOException {
                    // chama encode begin do componente pai
                    super.encodeBegin(context);
            
                    // customiza página usando listener
                    DocWriter writer = getWriter();
                    if (writer != null && writer instanceof PdfWriter) {
                        // recupera pdfwriter e seta listener
                        PdfWriter pdfWriter = (PdfWriter) writer;
                        pdfWriter.setPageEvent(new PdfDocumentEventListener());
            
                        // inicialização de template
                        templateTotalPaginas = pdfWriter.getDirectContent().createTemplate(100, 100);
                        templateTotalPaginas.setBoundingBox(new Rectangle(-20, -20, 100, 100));
            
                        // inicialização de fonte
                        try {
                            fonte = BaseFont.createFont("Helvetica", BaseFont.WINANSI, false);
                        } catch (IOException e) {
                            throw new ExceptionConverter(e);
                        } catch (DocumentException e) {
                            throw new ExceptionConverter(e);
                        }
                    }
            
                }
            
            
                /**
                 * Listener para eventos na criação da página PDF.
                 */
                private class PdfDocumentEventListener extends PdfPageEventHelper {
            
                    /** {@inheritDoc} */
                    @Override
                    public void onEndPage(PdfWriter writer, Document document) {
                        PdfContentByte cb = writer.getDirectContent();
                        cb.saveState();
            
                        // compose the footer
                        String text = "Page " + writer.getPageNumber() + " of ";
                        float textSize = fonte.getWidthPoint(text, 12);
                        float textBase = document.bottom() - 20;
                        cb.beginText();
                        cb.setFontAndSize(fonte, 12);
                        // for odd pagenumbers, show the footer at the left
                        if ((writer.getPageNumber() & 1) == 1) {
                            cb.setTextMatrix(document.left(), textBase);
                            cb.showText(text);
                            cb.endText();
                            cb
                                .addTemplate(templateTotalPaginas, document.left() + textSize,
                                    textBase);
                        // for even numbers, show the footer at the right
                        } else {
                            float adjust = fonte.getWidthPoint("0", 12);
                            cb.setTextMatrix(document.right() - textSize - adjust, textBase);
                            cb.showText(text);
                            cb.endText();
                            cb.addTemplate(templateTotalPaginas, document.right() - adjust, textBase);
                        }
                        cb.saveState();
                    }
            
                    /** {@inheritDoc} */
                    @Override
                    public void onCloseDocument(PdfWriter writer, Document document) {
                        templateTotalPaginas.beginText();
                        templateTotalPaginas.setFontAndSize(fonte, 12);
                        templateTotalPaginas.setTextMatrix(0, 0);
                        templateTotalPaginas.showText(Integer.toString(writer.getPageNumber() - 1));
                        templateTotalPaginas.endText();
                    }
                }
            }
            




            Usage on pages:


            <p:document 
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:rich="http://richfaces.org/rich"
                xmlns:a4j="http://richfaces.org/a4j"
                xmlns:p="http://jboss.com/products/seam/pdf" 
                binding="#{documentoSeamPdf}">





            • 3. Re: seam pdf - Page X of Y
              roben
              Hi Márcio,

              thanks for your code. I am too using it as an workarround for now.
              I'll open up a feature request for a <p:totalPages>-tag because i think this is essential especially for official documents!

              Greetings Robert
              • 4. Re: seam pdf - Page X of Y
                roben
                • 5. Re: seam pdf - Page X of Y
                  marcio.dantas

                  Thanks for the JIRA Robert. Let's see if something better than above appears.
                  cheers