Skip to content

Instantly share code, notes, and snippets.

@waylan
Last active Jun 30, 2021
Embed
What would you like to do?
An HTML to PDF script using Weasyprint.
from weasyprint import HTML, CSS
HTML_TEMPLATE = """
<html>
<head>
</head>
<body>
{body}
</body>
</html>
"""
CSS_TEMPLATE = """
@page {{
@top-left {{
content: "{header_left_content}";
display: block;
text-align: left;
vertical-align: middle;
width: 33%;
{header_left_style}
}}
@top-center {{
content: "{header_center_content}";
display: block;
text-align: center;
vertical-align: middle;
width: 33%;
{header_center_style}
}}
@top-right {{
content: "{header_right_content}";
display: block;
text-align: right;
vertical-align: middle;
width: 33%;
{header_right_style}
}}
@bottom-left {{
content: "{footer_left_content}";
display: block;
text-align: left;
vertical-align: middle;
width: 33%;
{footer_left_style}
}}
@bottom-center {{
content: "{footer_center_content}";
display: block;
text-align: center;
vertical-align: middle;
width: 33%;
{footer_center_style}
}}
@bottom-right {{
content: "{footer_right_content}";
display: block;
text-align: right;
vertical-align: middle;
width: 33%;
{footer_right_style}
}}
}}
"""
positions = ('left', 'center', 'right')
def html2pdf(src, outfile, headers=None, footers=None, styles='', header_styles=None, footer_styles=None):
''' Export an HTML fragment to a PDF. '''
css_context = dict(zip([f'header_{pos}_content' for pos in positions], headers or ('', '', '')))
css_context.update(zip([f'footer_{pos}_content' for pos in positions], footers or ('', '', '')))
css_context.update(zip([f'header_{pos}_style' for pos in positions], header_styles or ('', '', '')))
css_context.update(zip([f'footer_{pos}_style' for pos in positions], footer_styles or ('', '', '')))
html = HTML(string=HTML_TEMPLATE.format(body=src))
html.write_pdf(outfile, stylesheets=[
CSS(string=styles),
CSS(string=CSS_TEMPLATE.format(**css_context))
])
if __name__ == '__main__':
html2pdf(
src='<p>The body</p>',
outfile='example.pdf',
styles='p {color: green;}',
headers=('top left', 'top center', 'top right'),
footers=('bottom left', 'bottom center', 'bottom right'),
footer_styles=('', 'color: red;', '')
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment