Showing posts with label total page number. Show all posts
Showing posts with label total page number. Show all posts

Monday, November 12, 2012

How To Render Total Pagenumber In Pdf's With Reportlab

Here is my way to render pdf-files with a "totalPagenumber" option:

Note: The pdf is rendered twice. This may cause problems on low-performance machines or for very big files.

The idea is to pass the number of pages from the first rendering to the second.
To do this I use this function:

from pyPdf import PdfFileReader

def genPdf(renderPageNumber=True):
    filename = pdfWriter()
    if renderPageNumber:
        pdfFile = pdfFileReader(open(filename,'rb'))
        filename = pdfWriter(' / %d'%pdfFile.numPages)

To get the number of pages of a pdf file you need the pyPdf package!

The pdfWriter function generates the pdf file:

from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.rl_config import defaultPageSize
from reportlab.lib.units import inch

def pdfWriter( totalPages='' ):

    filename = 'test.pdf'
    PAGE_HEIGHT=defaultPageSize[1]
    PAGE_WIDTH=defaultPageSize[0]
    styles = getSampleStyleSheet()
    Title = "Hello world"
    pageinfo = "platypus example"

    def myFirstPage(canvas, doc):
        canvas.saveState()
        canvas.setFont('Times-Bold',16)
        canvas.drawCentredString(PAGE_WIDTH/2.0, PAGE_HEIGHT-108, Title)
        canvas.setFont('Times-Roman',9)
        canvas.drawString(inch, 0.75 * inch,"%s: Page %d%s" % (pageinfo, doc.page, totalPages) )
        canvas.restoreState()

    def myLaterPages(canvas, doc):
        canvas.saveState()
        canvas.setFont('Times-Roman', 9)
        canvas.drawString(inch, 0.75 * inch,"%s: Page %d%s" % (pageinfo, doc.page, totalPages) )
        canvas.restoreState()

    doc = SimpleDocTemplate(filename)
    Story = [Spacer(1,2*inch)]
    style = styles["Normal"]
    for i in range(100):
        bogustext = ("Paragraph number %s. " % i) *20
        p = Paragraph(bogustext, style)
        Story.append(p)
        Story.append(Spacer(1,0.2*inch))
    doc.build(Story, onFirstPage=myFirstPage, onLaterPages=myLaterPages)
    return filename

The pdf rendering is done by the ReportLab Toolkit.

To return the pdf as responce in a django app, I use a function like this, where i render the pdf into a cStringIO. The output I add to the response in the view.