Add initial HTML structure for report generation

- Created page_1.html with layout including ISHP branding, main content, and dotted pattern.
- Developed page_2.html featuring a Table of Contents with sections for Lung Analysis, Cardio Metrics, Fuel Utilization, Local Muscle Activity, Training Recommendations, Next Steps, and Glossary.
- Added placeholder files for pages 3 to 19 to facilitate future content development.
This commit is contained in:
bolade
2025-09-24 08:35:29 +01:00
parent 804b3fb10e
commit 4753276778
24 changed files with 1784 additions and 113 deletions
+48 -32
View File
@@ -1,38 +1,54 @@
import pdfkit
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
from weasyprint import HTML
import matplotlib.pyplot as plt
import os
# 1. Generate a chart with matplotlib env = Environment(loader=FileSystemLoader("report_gen"))
os.makedirs("static/charts", exist_ok=True)
chart_path = "static/charts/resp_chart.png"
plt.plot([1, 2, 3, 4], [1, 4, 2, 5], label="Breath Volume") # Define templates and their unique contexts
plt.legend() pages = [
plt.title("Respiratory Chart") ("page_1.html", {"name": "John Doe", "surname": "Moran", "date": "July 29, 2025"}),
plt.savefig(chart_path) ("page_2.html", {"content": "This is page 2 content"}),
plt.close() ]
# 2. Patient data (this would usually come from your DB) # Render each template with its own context
patient_data = { html_pages = []
"name": "Keirstyn Moran", for tpl, ctx in pages:
"age": 34, template = env.get_template(tpl)
"height": 163, html_pages.append(template.render(ctx))
"weight": 56
# 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>
.page-break {{ page-break-after: always; }}
.page {{
height: 386mm;
}}
</style>
</head>
<body class="m-0 p-0">
{final_html}
</body>
</html>
"""
print(html_doc)
# Generate PDF
options = {
"page-size": "A4",
"encoding": "UTF-8",
"margin-top": "0mm",
"margin-bottom": "0mm",
"margin-left": "0mm",
"margin-right": "0mm",
"no-outline": None,
} }
pdfkit.from_string(html_doc, "multi_page_report.pdf", options=options)
context = { print("✅ PDF generated: multi_page_report.pdf")
"patient": patient_data,
"indications": "No Respiratory Capacity Limitation",
"chart_path": chart_path
}
# 3. Render Jinja2 template
env = Environment(loader=FileSystemLoader("templates"))
template = env.get_template("report.html")
html_out = template.render(context)
# 4. Generate PDF
HTML(string=html_out, base_url=".").write_pdf("lung_report.pdf")
print("✅ Report generated: lung_report.pdf")
Binary file not shown.
+580 -11
View File
File diff suppressed because one or more lines are too long
+815 -43
View File
File diff suppressed because one or more lines are too long
+104
View File
@@ -0,0 +1,104 @@
<div
class="w-full page bg-black text-white relative overflow-hidden"
style="height: 297mm"
>
<!-- ISHP Logo/Text -->
<div class="absolute top-8 left-8 z-20">
<h1 class="text-2xl font-bold tracking-wider">ISHP</h1>
</div>
<!-- Diagonal Cyan Stripe -->
<div class="absolute top-0 left-0 w-full h-full">
<div
class="absolute top-0 left-0 w-96 h-full bg-gradient-to-r from-cyan-300 to-cyan-400 transform -skew-x-12 origin-top-left"
></div>
</div>
<!-- Main Content Container -->
<div
class="relative z-10 flex flex-col justify-center items-end h-full pr-16"
>
<!-- BIO-PERFORMX Section -->
<div class="text-right mb-8">
<h1 class="text-6xl font-bold tracking-wider mb-2">BIO-PERFORMX</h1>
<p class="text-3xl italic font-light">Endurance</p>
</div>
<!-- Name and Date Section -->
<div class="text-right mt-16">
<h2 class="text-4xl font-bold tracking-wider mb-2">
{{ name|upper }}
</h2>
<h2 class="text-4xl font-bold tracking-wider mb-6">
{{ surname|upper }}
</h2>
<p class="text-xl italic underline">{{ date }}</p>
</div>
</div>
<!-- Dotted Pattern at Bottom -->
<div class="absolute bottom-0 left-0 w-full h-32 z-10">
<div class="grid grid-cols-20 gap-2 h-full items-end pb-8 pl-8">
<!-- First row of dots -->
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
</div>
<div class="grid grid-cols-20 gap-2 h-full items-end pb-4 pl-8">
<!-- Second row of dots -->
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
</div>
<div class="grid grid-cols-20 gap-2 h-full items-end pl-8">
<!-- Third row of dots -->
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
<div class="w-2 h-2 bg-white rounded-full"></div>
</div>
</div>
</div>
<style>
.grid-cols-20 {
grid-template-columns: repeat(20, minmax(0, 1fr));
}
</style>
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
+121
View File
@@ -0,0 +1,121 @@
<div class="bg-white w-full page m-0 p-0" style="height: 297mm">
<div class="px-16 py-20">
<!-- Table of Contents Header -->
<div class="mb-12">
<h1 class="text-4xl font-bold text-black mb-4 tracking-wide">
TABLE OF CONTENTS
</h1>
<div class="w-full h-1 bg-cyan-400"></div>
</div>
<!-- Table of Contents Items -->
<div class="space-y-6">
<!-- Lung Analysis -->
<div class="flex items-start bg-gray-200 rounded-lg">
<div
class="bg-black text-white text-2xl font-bold w-16 h-16 flex items-center justify-center rounded-lg mr-6"
>
3
</div>
<div class="flex-1 py-3">
<h2 class="text-2xl font-semibold text-black mb-1">
Lung Analysis
</h2>
<div class="space-y-1">
<p class="text-gray-600 text-sm">
Pulse Oximetry Assessment
</p>
<p class="text-gray-600 text-sm">
Spirometry Assessment
</p>
</div>
</div>
</div>
<!-- Cardio Metrics -->
<div class="flex items-start bg-gray-200 rounded-lg">
<div
class="bg-black text-white text-2xl font-bold w-16 h-16 flex items-center justify-center rounded-lg mr-6"
>
4
</div>
<div class="flex-1 py-3">
<h2 class="text-2xl font-semibold text-black mb-1">
Cardio Metrics
</h2>
<p class="text-gray-600 text-sm">
Active Metabolic Rate Assessment
</p>
</div>
</div>
<!-- Fuel Utilization -->
<div class="flex items-start bg-gray-200 rounded-lg">
<div
class="bg-black text-white text-2xl font-bold w-16 h-16 flex items-center justify-center rounded-lg mr-6"
>
5
</div>
<div class="flex-1 py-3">
<h2 class="text-2xl font-semibold text-black">
Fuel Utilization
</h2>
</div>
</div>
<!-- Local Muscle Activity -->
<div class="flex items-start bg-gray-200 rounded-lg">
<div
class="bg-black text-white text-2xl font-bold w-16 h-16 flex items-center justify-center rounded-lg mr-6"
>
9
</div>
<div class="flex-1 py-3">
<h2 class="text-2xl font-semibold text-black">
Local Muscle Activity
</h2>
</div>
</div>
<!-- Training Recommendations -->
<div class="flex items-start bg-gray-200 rounded-lg">
<div
class="bg-black text-white text-2xl font-bold w-16 h-16 flex items-center justify-center rounded-lg mr-6"
>
10
</div>
<div class="flex-1 py-3">
<h2 class="text-2xl font-semibold text-black">
Training Recommendations
</h2>
</div>
</div>
<!-- Next Steps -->
<div class="flex items-start bg-gray-200 rounded-lg">
<div
class="bg-black text-white text-2xl font-bold w-16 h-16 flex items-center justify-center rounded-lg mr-6"
>
12
</div>
<div class="flex-1 py-3">
<h2 class="text-2xl font-semibold text-black">
Next Steps
</h2>
</div>
</div>
<!-- Glossary -->
<div class="flex items-start bg-gray-200 rounded-lg">
<div
class="bg-black text-white text-2xl font-bold w-16 h-16 flex items-center justify-center rounded-lg mr-6"
>
13
</div>
<div class="flex-1 py-3">
<h2 class="text-2xl font-semibold text-black">Glossary</h2>
</div>
</div>
</div>
</div>
</div>
View File
View File
View File
View File
View File
View File
View File
+111 -22
View File
@@ -1,39 +1,128 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Lung Report</title> <link href="https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css" rel="stylesheet">
<!-- TailwindCSS via CDN -->
<script src="https://cdn.tailwindcss.com"></script>
</head> </head>
<body class="p-10 font-sans"> <body class="p-8">
<div class="bg-black text-white p-4 rounded-lg mb-6"> <div class="relative w-full h-screen bg-white overflow-hidden">
<h1 class="text-2xl font-bold">Lung Analysis Report</h1> <!-- Background Design -->
<div class="absolute inset-0">
<!-- Left side - White section with ISHP logo -->
<div
class="absolute left-0 top-0 w-1/3 h-full bg-white flex items-start justify-start p-8"
>
<div class="text-black font-bold text-4xl tracking-wider">ISHP</div>
</div> </div>
<div class="grid grid-cols-2 gap-4 mb-6"> <!-- Diagonal cyan divider -->
<div><b>Name:</b> {{ patient.name }}</div> <div class="absolute left-0 top-0 w-full h-full">
<div><b>Age:</b> {{ patient.age }}</div> <svg
<div><b>Height:</b> {{ patient.height }} cm</div> viewBox="0 0 100 100"
<div><b>Weight:</b> {{ patient.weight }} kg</div> class="w-full h-full"
preserveAspectRatio="none"
>
<polygon points="0,0 35,0 25,100 0,100" fill="#22d3ee" />
</svg>
</div> </div>
<div class="mb-6"> <!-- Right side - Black section -->
<h2 class="text-xl font-semibold mb-2">Lung Function</h2> <div class="absolute right-0 top-0 w-2/3 h-full bg-black">
<div class="w-full h-6 bg-gradient-to-r from-red-500 via-yellow-300 to-green-400 relative"> <!-- Dotted pattern at bottom -->
<div class="absolute top-[-5px] left-1/2 transform -translate-x-1/2 <div
w-0 h-0 border-l-[7px] border-r-[7px] border-b-[10px] border-black"></div> class="absolute bottom-0 left-0 w-full h-32 flex items-end justify-start pl-8 pb-8"
>
<div class="grid grid-cols-16 gap-2">
<!-- Creating dotted pattern -->
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
</div> </div>
</div> </div>
<div class="bg-gray-100 p-4 rounded-lg mb-6"> <!-- Additional rows of dots -->
<b>Indications:</b> {{ indications }} <div
class="absolute bottom-16 left-0 w-full h-8 flex items-center justify-start pl-8"
>
<div class="grid grid-cols-16 gap-2">
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
</div>
</div> </div>
<div> <div
<h2 class="text-xl font-semibold mb-2">Respiratory Chart</h2> class="absolute bottom-32 left-0 w-full h-8 flex items-center justify-start pl-8"
<img src="{{ chart_path }}" class="border rounded-lg shadow"> >
<div class="grid grid-cols-16 gap-2">
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
<div class="w-2 h-2 bg-white rounded-full opacity-60"></div>
</div>
</div>
</div>
</div>
<!-- Content -->
<div
class="relative z-10 h-full flex flex-col items-center justify-center text-white"
>
<!-- Main Title -->
<div class="text-center mb-8">
<h1 class="text-6xl font-bold tracking-wider mb-4">BIO-PERFORMX</h1>
<p class="text-2xl font-light italic">Endurance</p>
</div>
<!-- Patient Name -->
<div class="text-center mb-12">
<h2 class="text-4xl font-bold tracking-widest">John Doe</h2>
<h2 class="text-4xl font-bold tracking-widest">Moran</h2>
</div>
<!-- Date -->
<div class="text-center">
<p class="text-xl font-light italic underline">July 29, 2025</p>
</div>
</div>
</div> </div>
</body> </body>
</html> </html>