html2pdf.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. # -*- coding: utf-8 -*-
  2. import os
  3. import re
  4. from xhtml2pdf import pisa
  5. from tempfile import NamedTemporaryFile
  6. from django.conf import settings
  7. from django.template import loader, Context
  8. from django.core.files import File
  9. def link_callback(uri, rel):
  10. """
  11. # Convert HTML URIs to absolute system paths so xhtml2pdf can access
  12. # those resources
  13. """
  14. sUrl = settings.STATIC_URL # Typically /static/
  15. sRoot = settings.STATIC_ROOT # Typically /home/userX/project_static/
  16. mUrl = settings.MEDIA_URL # Typically /static/media/
  17. mRoot = settings.MEDIA_ROOT # Typically /home/userX/project_static/media/
  18. projectDir = settings.PROJECT_PATH # Typically /home/userX/project/
  19. # convert URIs to absolute system paths
  20. if uri.startswith(mUrl):
  21. path = os.path.join(mRoot, uri.replace(mUrl, ""))
  22. elif uri.startswith(sUrl):
  23. path = os.path.join(sRoot, uri.replace(sUrl, ""))
  24. # If file doesn't exist try to find it in app static folder
  25. # This case occur in developpement env
  26. if not os.path.isfile(path):
  27. app_search = re.search(r'^(%s|%s)(.*)/.*' % (sUrl, mUrl), uri)
  28. app = app_search.group(2)
  29. path = os.path.join(projectDir, app, uri[1:])
  30. # make sure that file exists
  31. if not os.path.isfile(path):
  32. raise Exception(
  33. 'media URI must start with %s or %s' %
  34. (sUrl, mUrl))
  35. return path
  36. def render_as_pdf(template, context):
  37. """
  38. Génére le template indiqué avec les données du context en HTML et le
  39. converti en PDF via le module xhtml2pdf.
  40. Renvoi un objet de type File
  41. """
  42. template = loader.get_template(template)
  43. html = template.render(Context(context))
  44. file = NamedTemporaryFile()
  45. pisaStatus = pisa.CreatePDF(html, dest=file, link_callback=link_callback)
  46. file.flush()
  47. return File(open(file.name))