django, reportlab and basedoctemplate | simpledoctemplate

1,383 views
Skip to first unread message

Sven Richter

unread,
Mar 30, 2010, 12:08:53 PM3/30/10
to django-users
Hi everybody,

i am looking for a way to get BaseDocTemplate from the reportlab
library working, connected with a httpresponse.
I found the documentation for a simple reportlab page, using canvas.
But to me it seems, that i need more options than basic Canvas offers.
Like a page header or footer, tables continuing over pages etc.
I have not found a working example to use httpresponse:

response = HttpResponse(mimetype='application/pdf')
response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'

in conjunction with:

BaseDocTemplate('basedoc.pdf',showBoundary=1)

So if somebody could provide some working code, or a hint to
repository or an application with some working code, i'd really
appreciate that.


Greetings
Sven

Paulo Almeida

unread,
Mar 30, 2010, 12:56:19 PM3/30/10
to django...@googlegroups.com
I'm using Platypus (part of reportlab) to generate pdfs without micromanagement of Canvas elements. reportlab's documentation was very helpful to learn how to work with Paragraph, Table, Image, etc. Some code:

# views.py
@login_required
def view_pdf(request, experiment_id):
    experiment = get_object_or_404(Experiment.objects.filter(pk=experiment_id))
    response = HttpResponse(mimetype='application/pdf')
    filename = slugify(experiment.title) + '.pdf'
    response['Content-Disposition'] = 'filename=' + filename
    generate_pdf([experiment], response)
    return response

# functions.py
def generate_pdf(experiments, output):
    doc = SimpleDocTemplate(output, pagesize=A4)
    Document = []
    for experiment in experiments:
        Document.extend(pdf_elements(experiment))
    doc.build(Document)

pdf_elements is a function that adds bits and pieces... This is just an excerpt:

def pdf_elements(experiment):
    styles = getSampleStyleSheet()
    Document = [Paragraph(escape(experiment.title), styles["Title"])]
    Document.append(Spacer(1,50))
    date = unicode(experiment.date.strftime("%B %d, %Y"))
    Document.append(Paragraph("Acquired on " + date, styles["Normal"]))
    date_now = unicode(datetime.now().strftime("%B %d, %Y"))
    Document.append(Paragraph("PDF created on " + date_now, styles["Normal"]))
    Document.append(Spacer(1,10))
    return Document

Read the Platypus documentation for many more elements and options.

These are my reportlab imports:

from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, TableStyle
from reportlab.platypus import KeepTogether
from reportlab.platypus import Table as Platypus_Table
from reportlab.platypus import Image as Platypus_Image
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet

- Paulo



--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.


Sven Richter

unread,
Mar 30, 2010, 1:58:21 PM3/30/10
to django...@googlegroups.com
Great, thank you very much, this got me started. However, its not
working yet. This is the code i have right now:

def generate_pdf(request):


response = HttpResponse(mimetype='application/pdf')
response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'

styles = getSampleStyleSheet()
Document = [Paragraph('rd', styles["Title"])]
Document.append(Spacer(1,50))


date_now = unicode(datetime.now().strftime("%B %d, %Y"))
Document.append(Paragraph("PDF created on " + date_now, styles["Normal"]))
Document.append(Spacer(1,10))

doc.build(Document)
return response

But instead of showing the pdf i get the error:

Exception Type: IndexError
Exception Value: list index out of range

I cannot imagine what may be wrong there? From my point of view it
should work like that?


Greetings
Sven

HARRY POTTRER

unread,
Mar 30, 2010, 1:59:44 PM3/30/10
to Django users
On Mar 30, 12:08 pm, Sven Richter <sver...@googlemail.com> wrote:
>
> So if somebody could provide some working code, or a hint to
> repository or an application with some working code, i'd really
> appreciate that.
>
> Greetings
> Sven

You can look through my code: http://github.com/nbv4/flightloggin/blob/master/pdf/pdf.py

and an example of some output:

http://flightlogg.in/chris/print.pdf

palmeida

unread,
Mar 30, 2010, 2:21:09 PM3/30/10
to Django users
Is that all your code? I don't see a line like this (from my
generate_pdf function):

doc = SimpleDocTemplate(response, pagesize=A4)

That's what links the 'response' variable to the output of the
doc.build function. But I don't think that should be what's causing
the IndexError, because you don't assign doc to anything. It should
just complain that doc is not defined. For what it's worth, the pdf
generating part of your code works and generates a pdf (if you include
the 'doc = ...' line above)

- Paulo

> > On Tue, Mar 30, 2010 at 5:08 PM, Sven Richter <sver...@googlemail.com>

Sven Richter

unread,
Mar 30, 2010, 2:57:42 PM3/30/10
to django...@googlegroups.com
On Tue, Mar 30, 2010 at 8:21 PM, palmeida <igcbioin...@gmail.com> wrote:
> Is that all your code? I don't see a line like this (from my
> generate_pdf function):
>
> doc = SimpleDocTemplate(response, pagesize=A4)
I missed that one out of my example. You're right.

But it doesnt generate a pdf like that, it just complains about that IndexError.


Greetings
Sven

Paulo Almeida

unread,
Mar 30, 2010, 3:08:42 PM3/30/10
to django...@googlegroups.com
Ok, that is not easy to debug with so little information. Is the IndexError in views.py? Maybe there is a mistake in urls.py, caused by adding the url for the generate_pdf view?

- Paulo



Greetings
Sven

Sven Richter

unread,
Mar 30, 2010, 4:55:06 PM3/30/10
to django...@googlegroups.com
On Tue, Mar 30, 2010 at 9:08 PM, Paulo Almeida
<igcbioin...@gmail.com> wrote:
> Ok, that is not easy to debug with so little information. Is the IndexError
> in views.py? Maybe there is a mistake in urls.py, caused by adding the url
> for the generate_pdf view?

Hm, its indeed hard. I really dont know what that Error will tell me.
My Application is a very basic one. Up to now i do everything in the
admin interface. The only url defined is the one to view the pdf file:

urls.py:
urlpatterns = patterns('',
# Example:
# (r'^eiwomisa/', include('eiwomisa.foo.urls')),

# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation:
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),

# Uncomment the next line to enable the admin:
(r'^admin/', include(admin.site.urls)),
(r'^project/task/', include('project.task.urls')),
(r'^office/job/', include('office.job.urls')),
)

offic/job/urls.py:

from django.conf.urls.defaults import *

urlpatterns = patterns('office.job.views',
(r'/offer/generate/pdf/$', 'generate_pdf', '',
'office_job_generate_offer_pdf'),
)

and here is my views.py:

def generate_pdf(request):
response = HttpResponse(mimetype='application/pdf')
response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'

doc = BaseDocTemplate(filename=response,pagesize=A4)


styles = getSampleStyleSheet()
Document = [Paragraph('rd', styles["Title"])]
Document.append(Spacer(1,50))
date_now = unicode(datetime.now().strftime("%B %d, %Y"))
Document.append(Paragraph("PDF created on " + date_now, styles["Normal"]))
Document.append(Spacer(1,10))
doc.build(Document)

I have tried the same "setup" with the canvas.Canvas example from the
django documentation, and it worked. All i changed here is from canvas
to document.

Greetings
Sven

Sven Richter

unread,
Mar 30, 2010, 6:23:09 PM3/30/10
to django...@googlegroups.com
Hm, what makes me wonder is this one:
IndexError at /office/job//admin/job/offer/generate/pdf/
This is a url that is not accessible, cause it does not exist, at
least i never defined it in any urls.py.
Maybe thats the problem? Django tries to access a url which doesnt exist?


Greetings
Sven

Sven Richter

unread,
Mar 30, 2010, 6:52:16 PM3/30/10
to django...@googlegroups.com
Shame on me. The problem was that i mixed SimpleDocTemplate (which the
examples were based on), with BaseDocTemplate, which i used. And
BaseDocTemplate needs an extra PageTemplate defined. So this code
basically works:

def generate_pdf(request):
response = HttpResponse(mimetype='application/pdf')
response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'

template = PageTemplate('normal', [Frame(2.5*cm, 2.5*cm, 15*cm,
25*cm, id='F1')])
doc = BaseDocTemplate(filename=response,pagesize=A4,pageTemplates=template)

styles = getSampleStyleSheet()

Document = [Paragraph('rd', styles["Title"])]
Document.append(Spacer(1,50))

doc.build(Document)

return response

Thanks all for the help!
Sven

Paulo Almeida

unread,
Mar 30, 2010, 8:27:05 PM3/30/10
to django...@googlegroups.com
Cool, you're all set then. Documentation on Platypus should help you do what you want. I know it can do tables flow between pages, repeating the header in the beginning of each page if desired, and I'm sure there are ways of creating headers and footers, although I have never tried them.

Best,
Paulo

Reply all
Reply to author
Forward
0 new messages