Python3 Django -> HTML a PDF

Hay muchas formas diferentes de generar archivos PDF desde una página web de django en python2. El más limpio, probablemente, es pisa y reportlab. Estos no funcionan para python3 sin embargo.

Hasta ahora, el único método con el que he tenido éxito es renderizar la plantilla, escribirla en un archivo y luego usar wkhtmltopdf a través de subprocess.popen. Esto funciona bien, pero no carga ninguno de mis archivos estáticos, como css e imágenes.

¿Hay soluciones adecuadas? ¿Puede wkhtmltopdf leer mis archivos estáticos desde la línea de comandos, de alguna manera, o hay una biblioteca como pisa / reportlab, que soporta python3?

No he podido encontrar una biblioteca así

Podrías usar Weasyprint . Podrías fácilmente renderizar directamente.

Podrías hacer algo así:

html = HTML(string=htmlstring) main_doc = html.render() pdf = main_doc.write_pdf() return HttpResponse(pdf, content_type='application/pdf') 

Para representar su vista de Django a HTML, simplemente puede usar el acceso directo render_to_string(self.template_name, context, context_instance=RequestContext(self.request))

Tenga en cuenta que, al usar Esto con un servidor web síncrono / servidor WSGI, TODAS las solicitudes se bloquearán hasta que se presente el PDF. Así que considere utilizar un trabajador ASYNC.

Busqué en Weasyprint, wkhtmltopdf e incluso LaTeX, pero todos tienen dependencias binarias externas que son difíciles de implementar en servicios como Heroku.

La mejor combinación que encontré hasta ahora que funciona en Django en Python 3 es usar Reportlab (ahora funciona en Python 3) + xhtml2pdf . xhtml2pdf solo ha agregado recientemente el soporte beta de Python 3, por lo que necesita instalarlo con:

 pip install --pre xhtml2pdf 

Si tiene estos dos instalados, puede usar xhtml2pdf directamente o instalar el paquete django-easy-pdf que proporciona una vista de plantilla para heredar y una plantilla y estilo de ejemplo de base para que pueda comenzar rápidamente. Siga sus instrucciones de inicio rápido y puede preparar rápidamente algo como una vista detallada que se representa en PDF como:

 class InvoicePDFView(PDFTemplateView): template_name = "invoice_pdf.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) myinstance = get_object_or_404(MyModel, pk=context['pk']) context['myinstance'] = myinstance return context 

Y en tus urls.py agregarías algo como:

 url(r'invoice/(?P[^/]+)/$', InvoicePDFView.as_view(), name='invoice') 

He probado pydf en Python3, está funcionando bien.

 pip install python-pdf 

Para python2 use pip install python-pdf==0.30.0

Documentación https://github.com/tutorcruncher/pydf

wkhtmltopdf requiere

  • CSS para estar en línea
  • Los archivos estáticos estarán presentes localmente en el servidor.
  • las URL del archivo estático para que sean rutas del sistema operativo, por ejemplo: /home/ubuntu/project/project/static/file_name