I'm starting with Django and I working with HTML and I would like to convert to pdf. I have this view wich I get the data registered in my DB by id:
def contrato(request, id):
return render(request,'contrato\contrato.html', {'asociado': get_queryset(id)})
This renders me the following html, it is something simple:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CPS</title>
</head>
<body>
<h1>Contrato de Prestación de Servicios</h1>
<div>
<ul>
{% for dato in asociado %}
<li>Función/Título: {{ dato.job_title }}</li>
<li>nombre completo: {{ dato.first_name }} {{ dato.last_name }}</li>
<li>Email: {{ dato.email }}</li>
<li>RFC: {{ dato.rfc }}</li>
<li>CURP: {{ dato.curp }}</li>
<li>Clabe: {{ dato.interbank_key }}</li>
<li>País: {{ dato.country }}</li>
<li>Status: {{ dato.status }}</li>
<li>Creado: {{dato.created}}</li>
{% endfor %}
</ul>
</div>
</body>
</html>
How can I convert this html to pdf with the registered data to download. I have only achieved an empty pdf (without the data) or only with the H1 header.
I will appreciate any help!
CodePudding user response:
You can use wkhtml2pdf, which will need a HTML document and will generate a pdf file,then return to the generated file to the user, something like this
def contrato(request, id):
HTML = render(request,'contrato\contrato.html', {'asociado': get_queryset(id)}).content
f = open("/tmp/report.html","w")
f.write(HTML)
f.close()
import subprocess
subprocess.run("wkhtml2pdf /tmp/report.html /tmp/report.pdf")
return FileStream(open("/tmp/report.pdf","rb"), as_attachment=True)
CodePudding user response:
Doing this without an external library is going to be pretty complicated and involves transpiling the HTML to PDF.
Instead, you'll probably want to use a library like xhtml2pdf.
First pip install xhtml2pdf
. Then update your controller function:
from xhtml2pdf import pisa
# ...
def contrato(request, id):
if request.path_info.split('.')[-1] == "pdf"
return render_pdf(request, 'contrato/contrato.html', {'asociado': get_queryset(id)})
return render(request, 'contrato\contrato.html', {'asociado': get_queryset(id)})
def render_pdf(request, template_path, context)
filename = f'{template_path.split('.')[0]}.pdf'
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = f'attachment; filename="{filename}"'
template = get_template(template_path)
html = template.render(context)
pisa_status = pisa.CreatePDF(html, dest=response)
if pisa_status.err:
return HttpResponse(f'We had some errors <pre>{html}</pre>')
return response
For more advanced use cases, you'll probably want to refer to the documentation linked above.