Add report generation with PDF output and respiratory chart

This commit is contained in:
bolade
2025-09-23 21:31:15 +01:00
parent d7437ff975
commit 804b3fb10e
3 changed files with 182 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
from jinja2 import Environment, FileSystemLoader
from weasyprint import HTML
import matplotlib.pyplot as plt
import os
# 1. Generate a chart with matplotlib
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")
plt.legend()
plt.title("Respiratory Chart")
plt.savefig(chart_path)
plt.close()
# 2. Patient data (this would usually come from your DB)
patient_data = {
"name": "Keirstyn Moran",
"age": 34,
"height": 163,
"weight": 56
}
context = {
"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")
+105
View File
@@ -0,0 +1,105 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 8,
"id": "6eee3ddd",
"metadata": {},
"outputs": [],
"source": [
"import camelot\n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "d95cd8b1",
"metadata": {},
"outputs": [],
"source": [
"tables = camelot.read_pdf('data/KM6479696509 _ Keirstyn_Moran_SingleViewWithExplanation_2025-07-29.pdf')"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "759fd46e",
"metadata": {},
"outputs": [],
"source": [
"all_dfs = []\n",
"\n",
"# Append each table's dataframe to the list\n",
"for table in tables:\n",
" all_dfs.append(table.df)\n",
"\n",
"# Concatenate all dataframes into one\n",
"combined_df = pd.concat(all_dfs, ignore_index=True)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "e9c3b9f0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 0 1 2 3 \\\n",
"0 ← FM →\\nLow Fat\\nHigh Fat\\nBody Composition Ch... \n",
"1 \n",
"2 \n",
"3 \n",
"4 \n",
"5 \n",
"6 \n",
"\n",
" 4 5 \n",
"0 muscle mass in a coordinate system. A d... \n",
"1 \n",
"2 \n",
"3 \n",
"4 \n",
"5 \n",
"6 \n"
]
}
],
"source": [
"print(combined_df)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6bbc907f",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "report_generation",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
+39
View File
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Lung Report</title>
<!-- TailwindCSS via CDN -->
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-10 font-sans">
<div class="bg-black text-white p-4 rounded-lg mb-6">
<h1 class="text-2xl font-bold">Lung Analysis Report</h1>
</div>
<div class="grid grid-cols-2 gap-4 mb-6">
<div><b>Name:</b> {{ patient.name }}</div>
<div><b>Age:</b> {{ patient.age }}</div>
<div><b>Height:</b> {{ patient.height }} cm</div>
<div><b>Weight:</b> {{ patient.weight }} kg</div>
</div>
<div class="mb-6">
<h2 class="text-xl font-semibold mb-2">Lung Function</h2>
<div class="w-full h-6 bg-gradient-to-r from-red-500 via-yellow-300 to-green-400 relative">
<div class="absolute top-[-5px] left-1/2 transform -translate-x-1/2
w-0 h-0 border-l-[7px] border-r-[7px] border-b-[10px] border-black"></div>
</div>
</div>
<div class="bg-gray-100 p-4 rounded-lg mb-6">
<b>Indications:</b> {{ indications }}
</div>
<div>
<h2 class="text-xl font-semibold mb-2">Respiratory Chart</h2>
<img src="{{ chart_path }}" class="border rounded-lg shadow">
</div>
</body>
</html>