I have a python file that generates an HTML page (and a PDF) using jinja2 like this.
import pandas as pd
import requests
from jinja2 import Environment, FileSystemLoader
from weasyprint import HTML
# Stuff to get dataframe...
# Generate PDF and csv
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template("template.html")
template_vars = {"title" : "Something...",
"vulnerabilities_table": df.to_html(index=False)}
html_out = template.render(template_vars)
HTML(string=html_out).write_pdf("report_styled.pdf", stylesheets=["style.css"])
It uses the following template.html
<!DOCTYPE html>
{% block layout_style %}
<style> @page { size: letter landscape; margin: 2cm; } </style>
{% endblock %}
<html>
<head lang="en">
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<img src="static/images/Logo.png" style="height: 100; width: 300; float:inline-start">
<h2>{{ title }}</h2>
{{ vulnerabilities_table }}
</body>
</html>
The problem is that the image is not rendering at all (but the rest does). I guess it's because I'm not using Flask
<img src="static/images/Logo.png" style="height: 100; width: 300; float:inline-start">
My image is in the folder static/images/Logo.png. What did I do wrong ?
The problem is not about Flask. It's about weasyprint
converting html page (it's actually html string in your case) to PDF. For weasyprint
HTML
class to fetch the img
source (static/images/Logo.png), you need to put the full local file path as file:///path/to/folder/static/images/Logo/png
.
What you can do is, in template.html
:
<img src="{{ image_path }}" style="height: 100; width: 300; float:inline-start">
In python code:
import os
this_folder = os.path.dirname(os.path.abspath(__file__))
template_vars = {"title" : "Something...",
"vulnerabilities_table": "hello world",
"image_path": 'file://' + os.path.join(this_folder, 'static', 'images', 'Logo.png' )}
html_out = template.render(template_vars)
HTML(string=html_out).write_pdf("report_styled.pdf", stylesheets=["style.css"])