html2pdf.py 2.1 KB

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