How to generate Dyanamic no of pages using PDFBOX

2.4k views Asked by At

I have to generate a pdf file depending on some input .Each time the code runs , the input length may vary , so how can I add pages to the document dynamically depending on my input content .

public class pdfproject
     {
      static int lineno=768;
      public static void main (String[] args) throws Exception 
       {
        PDDocument doc= new PDDocument();
        PDPage page = new PDPage();
        doc.addPage(page);
        PDPageContentStream cos = new PDPageContentStream(doc, page);
        for(int i=0;i<2000;i++)
         {           
           renderText("hello"+i,cos,60);
         }
        cos.close();
        doc.save("test.pdf");
        doc.close();
     }

       static void renderText(String Info,PDPageContentStream cos,int marginwidth) throws Exception
    {
         lineno-=12;    
         System.out.print("lineno="+lineno);
         PDFont fontPlain = PDType1Font.HELVETICA;
         cos.beginText();
         cos.setFont(fontPlain, 10);
         cos.moveTextPositionByAmount(marginwidth,lineno);
         cos.drawString(Info);
         cos.endText();
     }
     }

How do i ensure that the content is rendered on the next page by adding a new page dynamically when there is no space on the current page ?

1

There are 1 answers

2
mkl On BEST ANSWER

Pdfbox does not include any automatic layouting support. Thus, you have to keep track of how full a page is, and you have to close the current page, create a new one, reset fill indicators, etc

This obviously should not be done in static members in some project class but instead in some dedicated class and its instance members. E.g.

public class PdfRenderingSimple implements AutoCloseable
{
    //
    // rendering
    //
    public void renderText(String Info, int marginwidth) throws IOException
    {
        if (content == null || textRenderingLineY < 12)
            newPage();

        textRenderingLineY-=12;    
        System.out.print("lineno=" + textRenderingLineY);
        PDFont fontPlain = PDType1Font.HELVETICA;
        content.beginText();
        content.setFont(fontPlain, 10);
        content.moveTextPositionByAmount(marginwidth, textRenderingLineY);
        content.drawString(Info);
        content.endText();
    }

    //
    // constructor
    //
    public PdfRenderingSimple(PDDocument doc)
    {
        this.doc = doc;
    }

    //
    // AutoCloseable implementation
    //
    /**
     * Closes the current page
     */
    @Override
    public void close() throws IOException
    {
        if (content != null)
        {
            content.close();
            content = null;
        }
    }

    //
    // helper methods
    //
    void newPage() throws IOException
    {
        close();

        PDPage page = new PDPage();
        doc.addPage(page);
        content = new PDPageContentStream(doc, page);
        content.setNonStrokingColor(Color.BLACK);

        textRenderingLineY = 768;
    }

    //
    // members
    //
    final PDDocument doc;

    private PDPageContentStream content = null;
    private int textRenderingLineY = 0;
}

(PdfRenderingSimple.java)

You can use it like this

PDDocument doc = new PDDocument();

PdfRenderingSimple renderer = new PdfRenderingSimple(doc);
for (int i = 0; i < 2000; i++)
{
    renderer.renderText("hello" + i, 60);
}
renderer.close();

doc.save(new File("renderSimple.pdf"));
doc.close();

(RenderSimple.java)

For more specialized rendering support you will implement improved rendering classes, e.g. PdfRenderingEndorsementAlternative.java from this answer.