Search code examples
python-3.xwebflaskweasyprint

WeaseyPrint Formats a PDF incorrectly


I'm trying to create a PDF from a HTML file which I also want to pass variables into for a JINJA template to pick it up. At the moment I've been trying to use weasyprint to do so with:

from weasyprint import HTML, CSS

css = CSS(string='@page { size: A3; margin: 0cm }')
html = HTML('/home/templates/pdf_test.html')

html.write_pdf('test.pdf', stylesheets=[css])

How would I then refactor this to send variables to the HTML so before the PDF is created? I'm using flask for my framework and the HTML contains JINJA templates.


Solution

  • This solution might be slightly convoluted, but it works so i'll add it here for anyone who reads this...

    
    from weasyprint import HTML
    
    @leads.route("/create-quote/<int:lead_id>", methods=['GET', 'POST'])
    def generate_pdf(lead_id):
        post = Quote.query.get_or_404(lead_id)
        html_template = render_template('leads/pdf_test.html', post=post)
        HTML(string=html_template).\
            write_pdf('DESTINATION_OF_FILE/{}_quote.pdf'.format(post.business_name),
                      stylesheets=['PATH_TO_CSS_FOR_PDF'])
        flash('Your quote email has been generate! Please see var/b2b/quotes', 'success')
        return redirect(url_for('main.dashboard'))
    

    So we query the table for the data we want to populate the pdf - post = Quote.query.get_or_404(lead_id)

    We then render the HTML passing post as an argument in since my jinja is {{ post.[variable] }}

    Using WeaseyPrint we can create a HTML object passing in the populated HTML and the CSS for the PDF.

    There might be a better way to do this, please feel free to post a better solution, but this dynamically creates PDF's based off a HTML template.