|
| 1 | +#-*- coding: utf-8 -*- |
| 2 | +from django.conf import settings |
| 3 | +from django.http import HttpResponse |
| 4 | +from django.template.context import Context |
| 5 | +from django.template.loader import get_template |
| 6 | +from xhtml2pdf import pisa # TODO: Change this when the lib changes. |
| 7 | +import StringIO |
| 8 | +import os |
| 9 | + |
| 10 | +#=============================================================================== |
| 11 | +# HELPERS |
| 12 | +#=============================================================================== |
| 13 | +class UnsupportedMediaPathException(Exception): |
| 14 | + pass |
| 15 | + |
| 16 | +def fetch_resources(uri, rel): |
| 17 | + """ |
| 18 | + Callback to allow xhtml2pdf/reportlab to retrieve Images,Stylesheets, etc. |
| 19 | + `uri` is the href attribute from the html link element. |
| 20 | + `rel` gives a relative path, but it's not used here. |
| 21 | +
|
| 22 | + """ |
| 23 | + if uri.startswith(settings.MEDIA_URL): |
| 24 | + path = os.path.join(settings.MEDIA_ROOT, |
| 25 | + uri.replace(settings.MEDIA_URL, "")) |
| 26 | + elif uri.startswith(settings.STATIC_URL): |
| 27 | + path = os.path.join(settings.STATIC_ROOT, |
| 28 | + uri.replace(settings.STATIC_URL, "")) |
| 29 | + else: |
| 30 | + raise UnsupportedMediaPathException( |
| 31 | + 'media urls must start with %s or %s' % ( |
| 32 | + settings.MEDIA_ROOT, settings.STATIC_ROOT)) |
| 33 | + return path |
| 34 | + |
| 35 | +def generate_pdf_template_object(template_object, file_object, context): |
| 36 | + """ |
| 37 | + Inner function to pass template objects directly instead of passing a filename |
| 38 | + """ |
| 39 | + html = template_object.render(Context(context)) |
| 40 | + pisa.CreatePDF(html.encode("UTF-8"), file_object , encoding='UTF-8', |
| 41 | + link_callback=fetch_resources) |
| 42 | + return file_object |
| 43 | + |
| 44 | +#=============================================================================== |
| 45 | +# Main |
| 46 | +#=============================================================================== |
| 47 | + |
| 48 | +def generate_pdf(template_name, file_object=None, context=None): # pragma: no cover |
| 49 | + """ |
| 50 | + Uses the xhtml2pdf library to render a PDF to the passed file_object, from the |
| 51 | + given template name. |
| 52 | + |
| 53 | + This returns the passed-in file object, filled with the actual PDF data. |
| 54 | + In case the passed in file object is none, it will return a StringIO instance. |
| 55 | + |
| 56 | + """ |
| 57 | + if not file_object: |
| 58 | + file_object = StringIO.StringIO() |
| 59 | + if not context: |
| 60 | + context = {} |
| 61 | + tmpl = get_template(template_name) |
| 62 | + generate_pdf_template_object(tmpl, file_object, context) |
| 63 | + return file_object |
0 commit comments