9

I need help with attaching img file in pdfs. We use the WeasyPrint lib for generating pdf from html.

in html connect img file like this

<img src="1.png" alt="">
<img src="2.png" alt="">
<img src="3.png" alt="">

but it is not working. I don't see the image.

Ron
  • 22,128
  • 31
  • 108
  • 206
User34
  • 375
  • 1
  • 4
  • 15

2 Answers2

12

use static for path of the image file

  {% load static %}
    <img src="{% static 'images/static.jpg' %}" alt="">

and pass base_url in HTML class in views.py

pdf_file = HTML(string=rendered_html, base_url=request.build_absolute_uri())

html file

<!DOCTYPE html>
<html lang="en">
{% load static %}
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div>
        <img src="{% static 'images/static.jpg' %}" alt="">
    </div>
</body>
</html>

views.py

from django.template.loader import get_template
from weasyprint import HTML, CSS
from django.conf import settings
from django.http import HttpResponse


def generate_pdf(request):
    html_template = get_template('latest/html_pdf.html')
    user = request.user
    rendered_html = html_template.render().encode(encoding="UTF-8")
    pdf_file = HTML(string=rendered_html, base_url=request.build_absolute_uri()).write_pdf(stylesheets=[CSS(settings.STATIC_ROOT +  '/css/generate_html.css')])



    http_response = HttpResponse(pdf_file, content_type='application/pdf')
    http_response['Content-Disposition'] = 'filename="generate_html.pdf"'

    return http_response
Thameem
  • 3,426
  • 4
  • 26
  • 32
  • NameError: global name 'request' is not defined – quant Jul 12 '18 at 06:11
  • you have to call this file inside any function in views.py file because you will have request instance only in the views.py file. otherwise you have to use some third party packages or something else – Thameem Jul 23 '18 at 16:11
  • 2
    If you just want to make sure images are included in pure python and your not doing anything with django or templates, all you need is the `base_url` which can just be `.` if your working locally – Geoff Williams Sep 06 '18 at 06:54
  • It doesn't work in every case: Weasyprint will fetch the url but when the remote image is password protected or simply requires authentication Weasyprint won't be able to download the image! – Eric Aug 04 '19 at 00:00
1

In case of sending emails with pdf attached, it's possible to pass path from view to function dedicated to emails. views.py

[...]
path = request.build_absolute_uri()          # build absolute path
order_confirmation.delay(order.id, path)     # pass to func
[...]

tasks.py

@app.task
def order_confirmation(order_id, path):       # receive path
    order = Order.objects.get(id=order_id)
    subject = f"Order nr. {order.id}"
    email_from = settings.EMAIL
    email_to = order.get_email
    message = (...)
    email = EmailMessage(subject, message, email_from, [email_to])
    html = render_to_string('pdf.html', {'order' : order, 'company': company})
    out = BytesIO()
    stylesheets=[weasyprint.CSS(settings.STATIC_ROOT + '/css/pdf.css')]
    weasyprint.HTML(string=html, base_url=path).write_pdf(out, stylesheets=stylesheets)      # use here
    email.attach(f'order_{order.id}.pdf',
        out.getvalue(),
        'application/pdf')
    email.send()

ImustAdmit
  • 388
  • 4
  • 14