How to export plotly graphs along with other HTML content into pdf?

Viewed 2031

I have tried 3 libraries for converting HTML to PDF ie xhtml2pdf, weasyprint & wkhtmltopdf.

My HTML has plotly graphs included in it, they are offline plots ie. graphs generated from plotly.offline.plots

When I load the same HTML in browser the graphs and other HTML content render well but when its converted to PDF using any one of the libraries mentioned above, the HTML content renders well but Graph becomes blank inside PDF.

from plotly.graph_objs import Scatter
from plotly.offline import plot

fig = plot([Scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])], output_type='div')

I pass this fig into Django template and render it as

{{ fig|safe }}

Used the xhtml2pdf, weasyprint & wkhtmltopdf to convert the HTML into PDF but none of them displayed the graphs.

What am I missing in my code ? Can any one tell me will any of the HTML to PDF conversion libraries render the Plotly graphs in the PDF ?

1 Answers

I had the same issue, eventually just saved figure to image file then loaded image into template then rendered using weasyprint (Seems to mess the styling up less than the other solutions).

See below link on how to save figure to image.

https://plotly.com/python/static-image-export/

Other useful links:

https://weasyprint.readthedocs.io/en/latest/features.html#html

https://weasyprint.org/samples/

view.py's pdf rendering part:

    html_string = render_to_string('management/report_template.html', context)
    html = HTML(string=html_string, base_url=request.build_absolute_uri())
    result = html.write_pdf(presentational_hints=True)

    # Creating http response
    response = HttpResponse(content_type='application/pdf;')
    response['Content-Disposition'] = 'inline; filename=report.pdf'
    response['Content-Transfer-Encoding'] = 'binary'
    with tempfile.NamedTemporaryFile(delete=True) as output:
        output.write(result)
        output.flush()
        output = open(output.name, 'rb')
        response.write(output.read())

    return response

base_url=request.build_absolute_uri() will allow for relative URLs in the HTML file. presentational_hints=True For the HTML styles to show on the PDF.

Related