"weasyprint" pdf generator using HTML - in django
Published: 2022-03-20 17:46:36

**Why use weasyprint?**
Easy to use. Without a doubt, weasyprint is one of the easiest libraries to use when it comes to pdf generators.
Quick request. because of its simplicity, this library tends to convert HTML to pdf very quickly. (it varies depending on the tools you use in HTML, if you need to make many requests through links, there tends to be a longer conversion time)

**When not to use weasyprint?**
As I had said above, due to the simplicity of the library, newer styling features may not work properly, an example would be _flexbox_ as well as JS cannot be used in this generator either.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m4d0hg905id5336ktntm.png)

As in the title of this article, I will explain how to make a function to generate a pdf file from HTML, so let's start from the beginning.

First we need to go to the **_requirements.txt_** file and add the following code:

```
weasyprint==53.4
```

**If** your project is _Dockerized_ and linux is _alpine_, I recommend that you have the following lines of code in your **_Dockerfile_**:

```
RUN apk add --no-cache jpeg-dev zlib-dev git gcc musl-dev python3-dev postgresql-dev
RUN apk add py3-pip py3-pillow py3-cffi py3-brotli gcc musl-dev python3-dev pango
RUN apk add py3-pip gcc musl-dev python3-dev pango zlib-dev jpeg-dev openjpeg-dev g++ libffi-dev
RUN apk add --no-cache --virtual .build-deps build-base linux-headers
```

Now inside the file that we are going to create the function we will have to make the following imports:

```
# to get the current date and time
import datetime
# library import
from weasyprint import HTML
```

Now we can create our function containing the logic for our converter. Below is an example of how the function should be constructed:

```
def export_pdf(request, queryset):
    response = HttpResponse(content_type='aplication/pdf')
    response['Content-Disposition'] = 'attachment; filename=Expense' + \
        str(datetime.datetime.now())+'.pdf'
    response['Content-Transfer-Encoding'] = 'binary'

    query = Query.objects.get(pk=1) #your query with the database object information

    html_string = render_to_string(
        'pdf_template.html',{'templates': query,'total': 0})
    html = HTML(string=html_string) # .html file route

    result = html.write_pdf()

    with tempfile.NamedTemporaryFile(delete=True) as output:
        output.write(result)
        output.flush()

        output = open(output.name, 'rb')
        response.write(output.read())

    return response
```

With the function ready we can create our HTML file that will be converted. It's up to you where it will be created, the most appropriate thing is to create it inside the template folder inside the app. In the current case, the name of the created file was **pdf_template.html**.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oqooomi36188e030zlfn.png) 

To handle the information in your html file, weasyprint accepts resources like jinja to handle your queries.

References:

- https://weasyprint.org/
- https://jinja.palletsprojects.com/en/3.0.x/