Created
March 9, 2018 15:38
-
-
Save blakebjorn/de24417bb032c71c3901a82c79bcf926 to your computer and use it in GitHub Desktop.
pdf generation with jinja2 and html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd | |
import jinja2 | |
import pdfkit | |
from random import getrandbits, randint | |
# pdfkit is just a wrapper for whktmltopdf. you need to install wkhtml and have it on the path | |
# alternatively, you can move wkhtmltoimage.exe, wkhtmltopdf.exe and wkhtmltox.dll into the working directory | |
# Create some data | |
def random_hex(length=10): | |
return '%0x' % getrandbits(length * 4) | |
df = pd.DataFrame([{"number":randint(0,100), | |
"name":random_hex(15), | |
"data1":random_hex(5), | |
"data2":random_hex(5), | |
"data3":random_hex(5)} for i in range(10)])[['number','name','data1','data2','data3']] | |
# Don't include the dataframe index in the html output, | |
# add the appropriate css class, and don't draw the border. | |
dfhtml = df.to_html(index=False, classes="table-title", border=False) | |
# Load the template | |
env = jinja2.Environment(loader=jinja2.FileSystemLoader(".")) | |
template = env.get_template("tableTemplate.html") | |
# pass df, title, message to the template. | |
html_out = template.render(df=dfhtml, | |
title="Jinja2 Example", | |
message="This is an example text input") | |
# write the html to file | |
with open("output.html", 'wb') as file_: | |
file_.write(html_out.encode("utf-8")) | |
# write the pdf to file | |
pdfkit.from_string(html_out, output_path="output.pdf", css=["template.css"]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link rel="stylesheet" type="text/css" href="template.css"/> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"/> | |
<title>{{title}}</title> | |
<meta name="viewport" content="initial-scale=1.0; maximum-scale=1.0; width=device-width;"> | |
</head> | |
<body> | |
<div class="table-title" align="center"> | |
<h4>{{ title }}</h4> | |
<p style="font-weight: bold">templating example.</p> | |
</div> | |
<div align="center"> | |
{{ df }} | |
</div> | |
<p align="center">{{ message }}</p> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*** Most of this CSS is unused in the exaple **/ | |
@import url(https://fonts.googleapis.com/css?family=Roboto:400,500,700,300,100); | |
body { | |
background-color: #ffffff; | |
font-family: "Roboto", helvetica, arial, sans-serif; | |
font-size: 22px; | |
font-weight: 400; | |
text-rendering: optimizeLegibility; | |
} | |
h4 { | |
margin-bottom: 0px; | |
margin-top: 5px; | |
} | |
hr { | |
height:2px; | |
visibility:hidden; | |
line-spacing:0px; | |
} | |
div.table-title { | |
display: block; | |
margin: auto; | |
max-width: 600px; | |
padding:5px; | |
width: 100%; | |
} | |
.table-title h3 { | |
color: #000000; | |
font-size: 30px; | |
font-weight: 400; | |
font-style:normal; | |
font-family: "Roboto", helvetica, arial, sans-serif; | |
text-shadow: -1px -1px 1px rgba(0, 0, 0, 0.1); | |
text-transform:uppercase; | |
} | |
/*** Table Styles **/ | |
.table-fill { | |
background: white; | |
border-radius:3px; | |
border-collapse: collapse; | |
border-bottom:2px solid #C1C3D1; | |
border-right:2px solid #C1C3D1; | |
border-left:2px solid #C1C3D1; | |
height: 320px; | |
margin: auto; | |
max-width: 600px; | |
padding:5px; | |
width: 100%; | |
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); | |
animation: float 5s infinite; | |
} | |
th { | |
color:#D5DDE5; | |
background:#1b1e24; | |
border-bottom:2px solid #1b1e24; | |
border-top:2px solid #1b1e24; | |
border-right: 1px solid #343a45; | |
font-size:23px; | |
font-weight: 300; | |
padding:12px; | |
text-align:left; | |
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); | |
vertical-align:middle; | |
white-space: pre; | |
} | |
th:first-child { | |
border-top-left-radius:3px; | |
border-left: 2px solid #1b1e24; | |
} | |
th:last-child { | |
border-top-right-radius:3px; | |
border-right: 2px solid #1b1e24; | |
} | |
tr { | |
border-top: 1px solid #C1C3D1; | |
border-bottom-: 1px solid #C1C3D1; | |
color:#000000; /*#666B85*/ | |
font-size:16px; | |
font-weight: normal; | |
text-shadow: 0 1px 1px rgba(256, 256, 256, 0.1); | |
white-space: pre; | |
} | |
tr:hover td { | |
background:#4E5066; | |
color:#FFFFFF; | |
border-top: 1px solid #22262e; | |
border-bottom: 1px solid #22262e; | |
} | |
tr:first-child { | |
border-top:none; | |
} | |
tr:last-child { | |
border-bottom:none; | |
} | |
tr:nth-child(odd) td { | |
background:#EBEBEB; | |
} | |
tr:nth-child(odd):hover td { | |
background:#4E5066; | |
} | |
tr:last-child td:first-child { | |
border-bottom-left-radius:3px; | |
} | |
tr:last-child td:last-child { | |
border-bottom-right-radius:3px; | |
} | |
td { | |
background:#FFFFFF; | |
padding:20px; | |
text-align:left; | |
vertical-align:middle; | |
font-weight:450; | |
font-size:20px; | |
text-shadow: -1px -1px 1px rgba(0, 0, 0, 0.1); | |
border-right: 1px solid #C1C3D1; | |
white-space: nowrap; | |
} | |
td:last-child { | |
border-right: 0px; | |
} | |
th.text-left { | |
text-align: left; | |
} | |
th.text-center { | |
text-align: center; | |
} | |
th.text-right { | |
text-align: right; | |
} | |
td.text-left { | |
text-align: left; | |
} | |
td.text-left-top { | |
vertical-align: top; | |
text-align: left; | |
} | |
td.text-center { | |
text-align: center; | |
} | |
td.text-right { | |
text-align: right; | |
} | |
footer { | |
page-break-after: always; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment