Прикрепить файл img в формате PDF Django Weasyprint

Привет, друзья

Я хочу попросить вас о помощи.

Мне нужна помощь с прикреплением файла img в формате pdf, мы используем WeasyPrint для создания pdf из html.

Я не знаю, куда добавить base_url=request.build_absolute_uri() в tasks.py. Где в файле tasks.py?

Теперь вместо изображений пустое место.

Я стараюсь изо всех сил, но у меня не получается. Пожалуйста, помогите.

html-файл

<!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>

tasks.py

from celery import task
from django.shortcuts import get_object_or_404
from oferty.models import Order
from django.template.loader import render_to_string
from django.core.mail import EmailMultiAlternatives
from django.conf import settings
import weasyprint
from weasyprint import default_url_fetcher, HTML
from io import BytesIO

@task
def order_created(order_id):
    """
    Task to send an e-mail notification when an order is successfully created.
    """
    order = Oferta.objects.get(id=order_id)
    subject = 'xxx nr {}'.format(order.id)
    html_content = '<p><strong>Hallow, {}!</p></strong><br><p>
    email = EmailMultiAlternatives(subject,
                                   html_content,'[email protected]',
                                   [order.email])

    # generation PDF.
    html = render_to_string('order/order/pdf.html', {'order': order})
    out = BytesIO()
    stylesheets = [weasyprint.CSS(settings.STATIC_ROOT + 'css/pdf.css')]

    weasyprint.HTML(string=html).write_pdf(out,
                                           stylesheets=stylesheets)
    # attach PDF.
    email.attach('order_{}.pdf'.format(order.id),
                 out.getvalue(),
                 'application/pdf')

    email.attach_alternative(html_content, "text/html")
    email.send()

буду признателен за вашу помощь


person Kuba    schedule 23.06.2017    source источник


Ответы (1)


Я решил эту проблему, закодировав изображение в base64 и отправив его в шаблон через контекст, а затем отрендерив с помощью CSS. Вы можете указать свое определение uri непосредственно перед использованием HTML

Итак, моя задача такова:

    from django.template.loader import get_template
    from weasyprint import HTML

    with open("path/to/image.png", "rb") as image_file:
        encoded_string = base64.b64encode(image_file.read())               

    context = {..., "img":encoded_string , ...}

    html_template = get_template('my_template_to_PDF.html')  
    html = html_template.render(context).encode(encoding="UTF-8")
    uri = request.build_absolute_uri()
    pdf_file = HTML(string=html,base_url=uri,encoding="UTF-8").write_pdf('path/to/output.pdf')

Шаблон:

<style>
...
div.image {
  width:150px;
  height:50px;
  background-image:url(data:image/png;base64,{{img}});
}
...
</style>
...
<div class = 'image'></div>
...

Надеюсь, поможет!

person Alex    schedule 23.06.2017
comment
фантастика! дайте мне знать, если есть какое-либо удобство при использовании вашего метода. - person Lemayzeur; 15.02.2018
comment
Спасибо за ваше решение. Изображения не отображались в режиме weasyprint. Я только что добавил encoded_string.decode() перед отправкой в ​​контекст. - person Clément Warneys; 04.12.2019