2025-09-23 21:31:15 +01:00
|
|
|
from jinja2 import Environment, FileSystemLoader
|
2025-09-26 16:37:46 +01:00
|
|
|
from playwright.sync_api import sync_playwright
|
2025-09-23 21:31:15 +01:00
|
|
|
|
2025-09-26 16:37:46 +01:00
|
|
|
from context import context_list
|
2025-09-23 21:31:15 +01:00
|
|
|
|
2025-09-26 16:37:46 +01:00
|
|
|
env = Environment(loader=FileSystemLoader("report_gen"))
|
2025-09-24 10:36:38 +01:00
|
|
|
|
2025-09-24 08:35:29 +01:00
|
|
|
html_pages = []
|
2025-09-26 16:37:46 +01:00
|
|
|
|
2025-09-26 21:42:02 +01:00
|
|
|
header_context = {
|
|
|
|
|
"patient_name": "Keirstyn Moran",
|
|
|
|
|
"age": 34,
|
|
|
|
|
"height": "5'4\"",
|
|
|
|
|
"weight": "123lbs",
|
|
|
|
|
"focus": "Endurance",
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-26 22:32:39 +01:00
|
|
|
footer_context = [
|
|
|
|
|
{
|
|
|
|
|
"contact_email": "info@ishplabs.com ",
|
|
|
|
|
"website": "www.ishplabs.com",
|
|
|
|
|
"social": "@ishplabs",
|
|
|
|
|
"page_number": i + 1,
|
|
|
|
|
}
|
|
|
|
|
for i in range(len(context_list))
|
|
|
|
|
]
|
2025-09-26 21:42:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
header_html = env.get_template("header.html").render(header_context)
|
2025-09-26 22:32:39 +01:00
|
|
|
footer_html_list = [
|
|
|
|
|
env.get_template("footer.html").render(context) for context in footer_context
|
|
|
|
|
]
|
2025-09-26 21:42:02 +01:00
|
|
|
|
2025-09-26 16:37:46 +01:00
|
|
|
for i, context in enumerate(context_list):
|
2025-09-26 21:42:02 +01:00
|
|
|
template = env.get_template(f"page_{i + 1}.html").render(context)
|
|
|
|
|
|
|
|
|
|
if (i + 1) > 2:
|
|
|
|
|
full_html = f"""
|
|
|
|
|
<div class="page flex flex-col justify-between">
|
|
|
|
|
<div>
|
|
|
|
|
{header_html}
|
|
|
|
|
</div>
|
|
|
|
|
<main class="flex-grow p-4">
|
|
|
|
|
{template}
|
|
|
|
|
</main>
|
|
|
|
|
<div class="border-t text-center text-sm text-gray-600">
|
|
|
|
|
{footer_html_list[i]}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
"""
|
|
|
|
|
html_pages.append(full_html)
|
|
|
|
|
else:
|
|
|
|
|
html_pages.append(template)
|
2025-09-23 21:31:15 +01:00
|
|
|
|
2025-09-24 08:35:29 +01:00
|
|
|
# Combine with page breaks
|
|
|
|
|
final_html = "<div class='page-break'></div>".join(html_pages)
|
|
|
|
|
# Wrap in full HTML document
|
|
|
|
|
html_doc = f"""
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="utf-8">
|
|
|
|
|
<link href="https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css" rel="stylesheet">
|
|
|
|
|
<style>
|
2025-09-24 10:36:38 +01:00
|
|
|
html, body {{
|
|
|
|
|
height: 100%;
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 0;
|
|
|
|
|
}}
|
2025-09-24 08:35:29 +01:00
|
|
|
.page-break {{ page-break-after: always; }}
|
|
|
|
|
.page {{
|
2025-09-26 21:42:02 +01:00
|
|
|
height: 100vh;
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}}
|
|
|
|
|
.page main {{
|
|
|
|
|
flex: 1;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}}
|
|
|
|
|
/* Reset margins and padding everywhere */
|
|
|
|
|
* {{
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 0;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}}
|
|
|
|
|
/* Prevent images from being too large */
|
|
|
|
|
img {{
|
|
|
|
|
max-height: 200px;
|
|
|
|
|
object-fit: contain;
|
2025-09-24 08:35:29 +01:00
|
|
|
}}
|
2025-09-26 22:32:39 +01:00
|
|
|
/* Larger images for specific charts */
|
|
|
|
|
.chart-large {{
|
|
|
|
|
max-height: 500px !important;
|
|
|
|
|
}}
|
2025-09-24 08:35:29 +01:00
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body class="m-0 p-0">
|
|
|
|
|
{final_html}
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
"""
|
2025-09-23 21:31:15 +01:00
|
|
|
|
2025-09-26 16:37:46 +01:00
|
|
|
|
2025-09-24 08:35:29 +01:00
|
|
|
# Generate PDF
|
2025-09-26 16:37:46 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def html_string_to_pdf(html_content, pdf_path):
|
|
|
|
|
with sync_playwright() as p:
|
|
|
|
|
browser = p.chromium.launch()
|
|
|
|
|
page = browser.new_page()
|
|
|
|
|
|
|
|
|
|
# Set the HTML directly
|
|
|
|
|
page.set_content(html_content)
|
|
|
|
|
|
|
|
|
|
# Export to PDF
|
|
|
|
|
page.pdf(path=pdf_path, format="A4", print_background=True)
|
|
|
|
|
|
|
|
|
|
browser.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
html_string_to_pdf(html_doc, "multi_page_report.pdf")
|
|
|
|
|
# pdfkit.from_string(html_doc, "truth_report.pdf", options=options)
|
2025-09-23 21:31:15 +01:00
|
|
|
|
2025-09-24 08:35:29 +01:00
|
|
|
print("✅ PDF generated: multi_page_report.pdf")
|