S
S
Sergey Nizhny Novgorod2016-11-15 03:32:17
Django
Sergey Nizhny Novgorod, 2016-11-15 03:32:17

How to render generated html page to pdf in Django?

I can’t find an adequate solution for translating html to pdf on django for 3 days so that it looks adequate.
1) Solution on API pdfcrowd

def pdf(request):
    if request.POST:
        chatvs = Competirors.objects.get(id = int(request.POST.get('competitor', '')))
        staff = Manager.objects.get(id = int(request.POST.get('manager', '')))

        business = Field.objects.get(id = int(request.POST.get('filed', '')))

        business = business.link.all().order_by('?')[0:3]
        
        context = {
            "chatvs" : chatvs,
            "staff" : staff,
            "business" : business,
        }

        tmpl = get_template('marketing/pdf.html', )
        html = tmpl.render(context)        
        
        # create an API client instance
        client = pdfcrowd.Client()
        
        # convert a web page and store the generated PDF to a variable
        pdf = client.convertHtml(html)
        
         # set HTTP response headers
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="log.pdf"'
        response["Cache-Control"] = "max-age=0"
        response["Accept-Ranges"] = "none"

        # send the generated PDF
        response.write(pdf)
        return response

Knocks out all css/static objects - it turns out poorly. In the end it doesn't work.
2) Solution on reportlab - in fact, you have to draw the entire pdf file with a canvas. A normal solution, but in my case it is not suitable, since I need a solution for generating a large number of different pdfs.
3) The decision on Pisa - but it is no more. The service was closed, the packages were removed, and the creators are now doing another thing.
4) Solution on PDFKit/wkhtmltopdf - they accept url/file/string for their work - but I still haven't found a way how to pass the render page to them so that it processes it and saves it to pdf.
def pdf(request):
    if request.POST:
        chatvs = Competirors.objects.get(id = int(request.POST.get('competitor', '')))
        staff = Manager.objects.get(id = int(request.POST.get('manager', '')))

        business = Field.objects.get(id = int(request.POST.get('filed', '')))

        business = business.link.all().order_by('?')[0:3]
        
        context = {
            "chatvs" : chatvs,
            "staff" : staff,
            "business" : business,
        }

        tmpl = get_template('marketing/pdf.html', )
        html = tmpl.render(context) 

        #Как-то тут надо прикрутить pdfkit?

===
Is there a way to make method 4 work, or am I missing something else?

Answer the question

In order to leave comments, you need to log in

4 answer(s)
S
Sergey Gornostaev, 2016-11-15
@sergey-gornostaev

Last year on one of my projects I ran into this problem. I shoveled a lot and came to the conclusion that there is not a single library that would render HTML to PDF with 100% accuracy. As a result, I used xhtml2pdf (the successor of Pisa), killing a lot of time studying the features of its work. I think it's worth looking in the direction of the xhtml2pdf successor - WeasyPrint .

Z
zelsky, 2016-11-15
@zelsky

But you can prescribe styles for print and generate PDFs using these styles. Did I understand you right?

A
Alexey Evtifiev, 2016-11-24
@evtifiev

Good afternoon everyone, about 3 years ago, I also had to solve such a problem, I solved it using xhtml2pdf. How things are now with this package, I can not say.

from django.template.loader import get_template
from django.template import Context, RequestContext
import xhtml2pdf.pisa as pisa
import cStringIO as StringIO
import cgi

def render_to_pdf(template_src, context_dict, name_file):
    template = get_template(template_src)
    context = Context(context_dict)
    html = template.render(context)
    result = StringIO.StringIO()
    pdf = pisa.CreatePDF(StringIO.StringIO(html.encode("UTF-8")), result, encoding='UTF-8')
    if not pdf.err:
        # return http.HttpResponse(result.getvalue(), mimetype='application/pdf')
        response = HttpResponse(result.getvalue(), content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="' + name_file + '.pdf"'
        return response

    return http.HttpResponse(('We had some errors<pre>%s</pre>' % cgi.escape(html)))

def ajax_post(request, slug):
    if request.POST:
        query_text = request.POST["data"].encode("UTF-8")
        title = Document.objects.get(slug=slug).title

        return render_to_pdf('documents/entries1.html', {
            'pagesize': 'A4',
            'title': title,
            'test': query_text
        }, slug)
    else:
        return redirect('documents-create', slug=slug)

Template parent pdf.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>My Title</title>
        <style type="text/css">
            @page {
                size: {{ pagesize }};
                margin: 1cm;
                @frame footer {
                    -pdf-frame-content: footerContent;
                    bottom: 0cm;
                    margin-left: 9cm;
                    margin-right: 9cm;
                    height: 1cm;
                }
            }
            @font-face {
                font-family: "Open Sans";
                src: url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Regular-webfont.eot?#iefix") format("embedded-opentype"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Regular-webfont.woff") format("woff"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Regular-webfont.ttf") format("truetype"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Regular-webfont.svg#svgFontName") format("svg");
            }
            @font-face {
                font-family: "Open Sans";
                font-weight: 600;
                src: url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Semibold-webfont.eot?#iefix") format("embedded-opentype"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Semibold-webfont.woff") format("woff"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Semibold-webfont.ttf") format("truetype"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Semibold-webfont.svg#svgFontName") format("svg");
            }
            @font-face {
                font-family: "Open Sans";
                font-weight: bold;
                src: url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Bold-webfont.eot?#iefix") format("embedded-opentype"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Bold-webfont.woff") format("woff"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Bold-webfont.ttf") format("truetype"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Bold-webfont.svg#svgFontName") format("svg");
            }
            @font-face {
                font-family: "Open Sans Light";
                src: url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Light-webfont.eot?#iefix") format("embedded-opentype"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Light-webfont.woff") format("woff"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Light-webfont.ttf") format("truetype"), url("//mozorg.cdn.mozilla.net/media/fonts/OpenSans-Light-webfont.svg#svgFontName") format("svg");
            }
            body {
                color: #484848;
                font-family: 'Open Sans',Arial,Helvetica,sans-serif;
                font-size: 14px;
                text-align: left;
                line-height: 1.5em;
}

        </style>
    </head>
    <body>
        <div>
            {{ mylist|safe }}
        </div>
        <div id="footerContent">
            {%block page_foot%}
                Page <pdf:pagenumber>
            {%endblock%}
        </div>
    </body>
</html>

The template to which we pass the data entries1.html
{% extends "pdf.html" %}

{% block title %}{{ title }}{% endblock %}

{% block content %}
      {{ test|safe }}
{% endblock %}

{%block page_foot%}
    я страница {{block.super}}
{%endblock%}

A
Alexey Busov, 2018-02-27
@alex-busov

I liked this package: https://github.com/incuna/django-wkhtmltopdf

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question