Reportlab, Platypus and tables

1,931 views
Skip to first unread message

Felix Penetrante

unread,
May 28, 2015, 1:16:55 AM5/28/15
to web...@googlegroups.com
I have just started using Reportlab for my app's pdf report needs and I can't find examples on how to control the table appearance (i.e. border, alignment, color, etc).  I already scoured through the web2py's documentation but it has a minimal example and is of no help on my table needs.  Is there any web resource out there that has a sample code snippet on the use of tables in Reportlab with platypus?  Or better yet can anyone provide a proper and comprehensive example on use of Reportlab platypus? 

Many thanks.


“This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail by mistake and delete this e-mail from your system. E-mail transmission cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message, which arise as a result of e-mail transmission. If verification is required please request a hard-copy version.” Bicol University, Legazpi City, Philippines.
“This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail by mistake and delete this e-mail from your system. E-mail transmission cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message, which arise as a result of e-mail transmission. If verification is required please request a hard-copy version.” Bicol University, Legazpi City, Philippines.

Jason (spot) Brower

unread,
May 28, 2015, 1:40:33 AM5/28/15
to web...@googlegroups.com

Pdf reporting can take a lot of work. Is this for a single page report or many pages. How are formated? And do you have an examole report in pdf format?


--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Johann Spies

unread,
May 28, 2015, 3:41:49 AM5/28/15
to web...@googlegroups.com
On 28 May 2015 at 07:40, Jason (spot) Brower <enco...@gmail.com> wrote:

Pdf reporting can take a lot of work. Is this for a single page report or many pages. How are formated? And do you have an examole report in pdf format?



I have used it once and it works.  Here is the code as example:

In the controller:

from reportlab.platypus import *
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.rl_config import defaultPageSize
from reportlab.lib.units import inch, mm
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.lib import colors
from cgi import escape
from reportlab.lib.pagesizes import inch, A4, landscape
from reportlab.pdfgen import canvas

def doccenter_pdf():
#    import pdb
#    pdb.set_trace()

    query = request.vars.query
    data = db(query).select(db.doccenter.doc_nr,
                            db.doccenter_location.location,
                            db.doccenter.author, db.doccenter.title,
                            db.doccenter.institution,
                            db.doccenter.reference, db.doccenter.source,
                            db.doccenter.publication_date,
                            db.doccenter.keywords,
                            db.doccenter.anual_report,
                            db.doccenter_category.category,
                            orderby = db.doccenter.publication_date | db.doccenter.author)
   
    title = T('Doccenter search result')
    styles = getSampleStyleSheet()
    tmpfilename = os.path.join(request.folder, 'private', str(uuid4()))


    normalStyle = styles['Normal']

    cols = [('doccenter', 'doc_nr'),
            ('doccenter_location', 'location') ,
            ('doccenter', 'author') ,
            ('doccenter', 'title'),
            ('doccenter', 'institution'),
            ('doccenter', 'reference'),
            ('doccenter', 'source'),
            ('doccenter', 'publication_date'),
            ('doccenter', 'keywords'),
            ('doccenter', 'anual_report'),
            ('doccenter_category', 'category')]

    hds = ['doc_nr', 'location', 'author', 'title', 'institution',
           'reference', 'source', 'date',
            'keywords', 'anual_report', 'category']


    headings = [Paragraph('''
    <para align=left spaceb=3><b>%s</b> </para>''' % ' '.join(c.split('_')).capitalize(),
                          styles["BodyText"]) for c in hds]

    lst = [headings]
    for item in data:
     
        rec = []
        for ikey in cols:
            #import pdb; pdb.set_trace()
            rec.append(par_from_item(item[ikey[0]][ikey[1]], styles))

        lst.append(rec)


    elements = []
    elements.append(Paragraph(escape(title), styles['Title']))


    # First the top row, with all the text centered and in Times-Bold,
    # and one line above, one line below.
    ts = [('ALIGN', (1, 1), (-1, -1), 'CENTER'),
          ('LINEABOVE', (0, 0), (-1, 0), 1, colors.purple),
          ('LINEBELOW', (0, 0), (-1, 0), 1, colors.purple),
          ('FONT', (0, 0), (-1, 0), 'Times-Bold'),

          # The bottom row has one line above, and three lines below of
          # various colors and spacing.
          ('LINEABOVE', (0, -1), (-1, -1), 1, colors.purple),
          ('LINEBELOW', (0, -1), (-1, -1), 0.5, colors.purple,
           1, None, None, 4, 1),
          ('LINEBELOW', (0, -1), (-1, -1), 1, colors.red),
          ('FONT', (0, -1), (-1, -1), 'Times-Bold')]

    #  Alternate row background
    for i, _ in enumerate(lst):
        if odd(i):
            ts.append(("BACKGROUND", (0, i), (-1, i), colors.cyan))
    t = Table(lst, style = ts)
    # Adjust column width
    t._argW[3] = 1.8 * inch
    t._argW[5] = 1.0 * inch
    t._argW[0] = 1.0 * inch

    t.setStyle(TableStyle())

    elements.append(t)

    doc = SimpleDocTemplate(tmpfilename, pagesize = landscape(A4))
    doc.build(elements, canvasmaker = NumberedCanvas)
    pdf = open(tmpfilename, "rb").read()
    os.unlink(tmpfilename)
    response.headers['Content-Type'] = 'application/pdf'
    return pdf

As you can see there was a lot of work and experimenting involved.

Regards
Johann
--
Because experiencing your loyal love is better than life itself,
my lips will praise you.  (Psalm 63:3)

Johann Spies

unread,
May 28, 2015, 3:44:06 AM5/28/15
to web...@googlegroups.com
Sorry I ommitted one import:

import os

Jason (spot) Brower

unread,
May 28, 2015, 4:08:49 AM5/28/15
to web...@googlegroups.com

I don't think this is a web2py issue. But you should be able to change the table settles quite easily using the documentation on tables in reportlab. Chapter 7 covers tables.


On Thu, May 28, 2015, 10:44 Johann Spies <johann...@gmail.com> wrote:
Sorry I ommitted one import:

import os

--
reportlab-userguide-1.pdf

Felix Penetrante

unread,
Jun 1, 2015, 2:04:21 PM6/1/15
to web...@googlegroups.com
Thanks for sharing your code.  It gave me a clue on how to append tables in the pdf file. 

I also found a web post (http://www.blog.pythonlibrary.org/2010/09/21/reportlab-tables-creating-tables-in-pdfs-with-python/) that elaborates the use and manipulation of table styles.  I incorporated the aforementioned link to the code already provided in the web2py reference manual on Reportlab and it worked perfectly.

Here is the controller function:

def get_me_a_pdf():

    from reportlab.platypus import *
    from reportlab.lib.styles import getSampleStyleSheet
    from reportlab.rl_config import defaultPageSize
    from reportlab.lib.units import inch, mm
    from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
    from reportlab.lib import colors
    from uuid import uuid4
    from cgi import escape
    import os

    title = "This The Doc Title"
    heading = "First Paragraph"
    text = 'bla '* 100

    styles = getSampleStyleSheet()
    tmpfilename=os.path.join(request.folder,'private',str(uuid4()))
    doc = SimpleDocTemplate(tmpfilename)
    story = []
    story.append(Paragraph(escape(title),styles["Title"]))
    story.append(Paragraph(escape(heading),styles["Heading2"]))
    story.append(Paragraph(escape(text),styles["Normal"]))
    story.append(Spacer(1,0.5*inch))
   
    data= [['00', '01', '02', '03', '04'],
       ['10', '11', '12', '13', '14'],
       ['20', '21', '22', '23', '24'],
       ['30', '31', '32', '33', '34']]
    t=Table(data)
    t.setStyle(TableStyle([('BACKGROUND',(1,1),(-2,-2),colors.green),
                           ('TEXTCOLOR',(0,0),(1,-1),colors.red)]))
    story.append(t)

    story.append(Spacer(1,0.5*inch))
   
    data= [['00', '01', '02', '03', '04'],
       ['10', '11', '12', '13', '14'],
       ['20', '21', '22', '23', '24'],
       ['30', '31', '32', '33', '34']]
    t=Table(data,5*[0.4*inch], 4*[0.4*inch])
    t.setStyle(TableStyle([('ALIGN',(1,1),(-2,-2),'RIGHT'),
                       ('TEXTCOLOR',(1,1),(-2,-2),colors.red),
                       ('VALIGN',(0,0),(0,-1),'TOP'),
                       ('TEXTCOLOR',(0,0),(0,-1),colors.blue),
                       ('ALIGN',(0,-1),(-1,-1),'CENTER'),
                       ('VALIGN',(0,-1),(-1,-1),'MIDDLE'),
                       ('TEXTCOLOR',(0,-1),(-1,-1),colors.green),
                       ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
                       ('BOX', (0,0), (-1,-1), 0.25, colors.black),
                       ]))
 
    story.append(t)
   
    doc.build(story)
    data = open(tmpfilename,"rb").read()

    os.unlink(tmpfilename)
    response.headers['Content-Type']='application/pdf'
    return data
=====================================================================

Indeed it's a lot of work, but at least it worked. :)
Reply all
Reply to author
Forward
0 new messages