Skip to content

Instantly share code, notes, and snippets.

@rms1000watt
Created July 21, 2016 18:45
Show Gist options
  • Save rms1000watt/c8b9a1bf9d9a9479d3883846a9bd27fb to your computer and use it in GitHub Desktop.
Save rms1000watt/c8b9a1bf9d9a9479d3883846a9bd27fb to your computer and use it in GitHub Desktop.
Generate HTML Report then convert HTML Report to PDF
# python generateHTML.py
# bash HTMLtoPDF.sh
import os
import math
pageInd = 1
PIXELS_PER_ROW = 9.4130434
# Includes header
MAX_ROWS_PER_PAGE = 80
tableRowStart = """
<tr>
"""
tableRowEnd = """</tr>"""
tableHeaderCellStart = """ <th>"""
tableHeaderCellEnd = """</th>
"""
tableCellStart = """ <td>"""
tableCellEnd = """</td>
"""
pageTemplate = """
<h4>*PAGE_TITLE*</h4>
<table>
*TABLE_HEADER*
*TABLE_CONTENT*
</table>
<p>*PAGE_NUMBER*</p>
<div style="height: *HEIGHT*px"></div>
"""
def main():
# pages here are actually sheets in xlsx
page1Title = 'Sheet 1 Title'
page1Data = []
page1Columns = ['FName', 'LName', 'ID']
page2Title = 'Sheet 2 Title'
page2Data = []
page2Columns = ['FName', 'LName', 'ID']
page3Title = 'Sheet 3 Title'
page3Data = []
page3Columns = ['FName', 'LName', 'ID', 'Age']
for i in range(2000):
page1Data.append(['John', 'Smith', str(i)])
page2Data.append(['Jack', 'Smith', str(i)])
page3Data.append(['Joe', 'Smith', str(i), '88'])
try:
templateFile = open('index.template.html', 'rb')
htmlFile = open('index.html', 'wb')
html = templateFile.read()
htmlContent = handleSheet(page1Title, page1Columns, page1Data)
htmlContent += handleSheet(page2Title, page2Columns, page2Data)
htmlContent += handleSheet(page3Title, page3Columns, page3Data)
html = html.replace('*CONTENT*', htmlContent)
htmlFile.write(html)
except Exception as e:
print 'Error generating HTML: ' + e.message
finally:
templateFile.close()
htmlFile.close()
def handleSheet(sheetTitle, columnNamesArr, dataArr):
htmlContent = ''
tableHeaderStr = tableRowStart
for cell in columnNamesArr:
tableHeaderStr += tableHeaderCellStart + cell + tableHeaderCellEnd
tableHeaderStr += tableRowEnd
# GOOD: tableHeaderStr
ind = 1
global pageInd
tableContentStr = ''
for row in dataArr:
rowStr = tableRowStart
for cell in row:
rowStr += tableCellStart + cell + tableCellEnd
rowStr += tableRowEnd
tableContentStr += rowStr
if ind == MAX_ROWS_PER_PAGE - 1:
htmlContent += pageTemplate.replace('*PAGE_TITLE*', sheetTitle).replace('*TABLE_HEADER*', tableHeaderStr).replace('*TABLE_CONTENT*', tableContentStr).replace('*PAGE_NUMBER*', str(pageInd)).replace("*HEIGHT*", str(0))
ind = 0
pageInd += 1
tableContentStr = ''
ind += 1
if ind != 1:
height = int(math.ceil((MAX_ROWS_PER_PAGE-ind+2)*PIXELS_PER_ROW))
htmlContent += pageTemplate.replace('*PAGE_TITLE*', sheetTitle).replace('*TABLE_HEADER*', tableHeaderStr).replace('*TABLE_CONTENT*', tableContentStr).replace('*PAGE_NUMBER*', str(pageInd)).replace("*HEIGHT*", str(height))
pageInd += 1
# print htmlContent
return htmlContent
if __name__ == '__main__':
main()
# cd to this directory
weasyprint index.html report.pdf
html {
font-family: 'Roboto', sans-serif;
}
h4 {
font-weight: 200;
text-align: center;
}
p {
font-size: 12px;
text-align: center;
}
table {
font-weight: 200;
width: 100%;
font-size: 8px;
text-align: center;
border-collapse: collapse;
}
table, td, th {
border: 1px solid black;
}
th {
background-color: #666;
color: white;
font-weight: 200;
}
tr:nth-child(even){background-color: #f2f2f2}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="index.css" />
<script>
var WebFontConfig = {
google: { families: [ 'Roboto:400,300,500:latin' ] }
};
(function() {
var wf = document.createElement('script');
wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
'://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
wf.type = 'text/javascript';
wf.async = 'true';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wf, s);
})();
</script>
</head>
<body>
*CONTENT*
</body>
</html>
brew install cairo pango gdk-pixbuf libxml2 libxslt libffi
sudo pip install weasyprint
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment