If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!

Appy framework offers pod, a library that allows to easily generate documents whose content is dynamic.

First of all download it from https://launchpad.net/appy and install it to your python environment (just copy appy folder to dist-packages/site-packages)

 

Let's assume for example we have a simple db table containings informations about some persons as follows:

 

db.define_table('persons',
    Field('name','string'),
    Field('surname','string'),
    Field('adress','string', required=False))

 

Now, we want to create a report which lists all these persons.

 

First of all we need to create a template file to generate our report, we can easily set up a nice template using openoffice/libreoffice writer.

Our template will be very simple, just a table with a column for each field of the table and a row for each person, let's create a table with 3 columns and 2 rows and set the fields description in the first row.

The template needs to be informed that we need to repeat the second row for each person, in the Insert menu->Comment

do row for p in persons

Now we just have to set the variables names in the second row, in the Edit menu->Modifications->Record and add respectively: p.name, p.surname, p.adress.

The only thing to remember is that template variables and python code variables must have the same names!

Let's see what we have to do in our python code; in our controller:

 

import os
import uuid
import subprocess   
from appy.pod.renderer import Renderer   

def createReport():
    persons = []
    for person in db().select(db.persons.ALL):
        persons.append(dict(name=person.name,
                            surname=person.surname,
                            adress=person.adress))            
    # Report creation               
    template_file = os.path.join(request.folder, 'private', 'template.odt')
    tmp_uuid = uuid.uuid4()        
    output_file_odt = "/var/tmp/%s.odt"%tmp_uuid
    output_file_pdf = "/var/tmp/%s.pdf"%tmp_uuid                                                            
    beingPaidForIt = True     
    renderer = Renderer(template_file, locals(), output_file_odt)
    renderer.run()                          
    subprocess.Popen("libreoffice --headless --invisible --convert-to pdf %s --outdir %s "%(output_file_odt, "/var/tmp") ,shell=True)                                                     
    while True:
        if os.path.exists(output_file_pdf):
            break
    data = open(output_file_pdf, "rb").read()                 
    for file in [output_file_odt, output_file_pdf]:
        os.unlink(file)                                                                                                                                                                                                                      
    response.headers['Content-Type'] = 'application/pdf'
    response.headers['Content-Disposition'] = 'attachment; filename=PersonsListing.pdf'
    return data                                                             

 

Appy pod creates an odt file but we want to send to the browser the pdf, so we call libreoffice via server mode to convert the odt to pdf file, when it's done we delete both files and then we send back the pdf report.

 

Hope this helps!

 

 

Here the Template file

 

 

 

 

Related slices

Comments (0)


Hosting graciously provided by:
Python Anywhere