Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django ReportLab: using Drawing object to create PDF and return via Httpresponse

In ReportLab, Drawing object can be written into different renderers, e.g

d = shapes.Drawing(400, 400)
renderPDF.drawToFile(d, 'test.pdf')

and in Django, Canvas object can be sent via httpresponse, e.g.:

response = HttpResponse(mimetype='application/pdf')
response['Content-Disposition'] = 'filename=test.pdf'
c = canvas.Canvas(response)

in my case, my problem is that I have a reportLab script using Drawing object which saves to local file system. I now put it in Django views, and wondering whether there is a way to not save to local file system but instead sent back to client.

I hope I describe this question clearly.

Thanks for any advice!

updates

it turns out there is a function in renderPDF:

renderPDF.draw(drawing, canvas, x, y)

which can render drawing() object in the given canvas.

like image 215
Simon Avatar asked Mar 23 '12 22:03

Simon


2 Answers

Using ReportLab in Django without saving to disk is actually pretty easy. There are even examples in the DjangoDocs (https://docs.djangoproject.com/en/dev/howto/outputting-pdf)

The trick basically boils down to using a "file like object" instead of an actual file. Most people use StringIO for this.

You could do it pretty simply with

from cStringIO import StringIO

def some_view(request):
    filename = 'test.pdf'

    # Make your response and prep to attach
    response = HttpResponse(mimetype='application/pdf')
    response['Content-Disposition'] = 'attachment; filename=%s.pdf' % (filename)
    tmp = StringIO()

    # Create a canvas to write on
    p = canvas.Canvas(tmp)
    # With someone on
    p.drawString(100, 100, "Hello world")

    # Close the PDF object cleanly.
    p.showPage()
    p.save()

    # Get the data out and close the buffer cleanly
    pdf = tmp.getvalue()
    tmp.close()

    # Get StringIO's body and write it out to the response.
    response.write(pdf)
    return response
like image 159
achew22 Avatar answered Nov 14 '22 23:11

achew22


it turns out there is a function in renderPDF:

renderPDF.draw(drawing, canvas, x, y) which can render drawing() object in the given canvas.

like image 43
Simon Avatar answered Nov 15 '22 00:11

Simon