Backend-healthcare / app /utils /pdf_process.py
msi
Fix: moved large
3876d7b
raw
history blame
8.09 kB
from reportlab.platypus import Frame, NextPageTemplate, PageTemplate, BaseDocTemplate, Paragraph, Image, Spacer,Paragraph
from reportlab.lib.units import cm
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.enums import TA_JUSTIFY
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from datetime import datetime
def generate_pdf_report(disease_info, filename="report.pdf")->None:
"""Generates a scientific article-style PDF report with two-column layout and a logo."""
# Custom styles
styles = getSampleStyleSheet()
# Add custom styles
styles.add(ParagraphStyle(
name='TitleStyle',
parent=styles['Heading1'],
fontSize=16,
leading=20,
alignment=1, # Center
spaceAfter=20,
textColor=colors.darkblue
))
styles.add(ParagraphStyle(
name='AuthorStyle',
parent=styles['Heading3'],
fontSize=10,
leading=12,
alignment=1,
spaceAfter=20,
textColor=colors.darkgrey
))
styles.add(ParagraphStyle(
name='AbstractStyle',
parent=styles['BodyText'],
fontSize=10,
leading=12,
alignment=TA_JUSTIFY,
backColor=colors.lightgrey,
borderPadding=5,
spaceAfter=20
))
styles.add(ParagraphStyle(
name='SectionHeader',
parent=styles['Heading2'],
fontSize=12,
leading=14,
spaceBefore=15,
spaceAfter=10,
textColor=colors.darkblue,
underlineWidth=1,
underlineColor=colors.darkblue,
underlineOffset=-5
))
styles.add(ParagraphStyle(
name='LeftColumn',
parent=styles['BodyText'],
fontSize=10,
leading=12,
alignment=TA_JUSTIFY,
leftIndent=0,
rightIndent=5,
spaceAfter=7
))
styles.add(ParagraphStyle(
name='RightColumn',
parent=styles['BodyText'],
fontSize=10,
leading=12,
alignment=TA_JUSTIFY,
leftIndent=5,
rightIndent=0,
spaceAfter=7
))
styles.add(ParagraphStyle(
name='BulletPoint',
parent=styles['BodyText'],
fontSize=10,
leading=12,
leftIndent=15,
bulletIndent=0,
spaceAfter=3,
bulletFontName='Symbol',
bulletFontSize=8
))
styles.add(ParagraphStyle(
name='Reference',
parent=styles['Italic'],
fontSize=8,
leading=10,
textColor=colors.darkgrey,
spaceBefore=15
))
# Create document with two columns
class TwoColumnDocTemplate(BaseDocTemplate):
def __init__(self, filename, **kw):
BaseDocTemplate.__init__(self, filename, **kw)
# Calculate column widths
page_width = self.pagesize[0] - 2*self.leftMargin
col_width = (page_width - 1*cm) / 2 # 1cm gutter
# First page template with title
first_page = PageTemplate(id='FirstPage',
frames=[
Frame(self.leftMargin, self.bottomMargin,
col_width, self.height,
id='leftCol'),
Frame(self.leftMargin + col_width + 1*cm,
self.bottomMargin,
col_width, self.height,
id='rightCol')
])
self.addPageTemplates(first_page)
# Other pages template
other_pages = PageTemplate(id='OtherPages',
frames=[
Frame(self.leftMargin, self.bottomMargin,
col_width, self.height,
id='leftCol2'),
Frame(self.leftMargin + col_width + 1*cm,
self.bottomMargin,
col_width, self.height,
id='rightCol2')
])
self.addPageTemplates(other_pages)
doc = TwoColumnDocTemplate(filename,
pagesize=letter,
leftMargin=2*cm,
rightMargin=2*cm,
topMargin=2*cm,
bottomMargin=2*cm)
story = []
# Add logo at the top (centered)
try:
logo = Image('app/data/logo_platform.jpg', width=6*cm, height=2*cm)
logo.hAlign = 'CENTER'
story.append(logo)
story.append(Spacer(1, 0.3*cm))
except Exception as e:
pass # If logo not found, skip
# Title and authors
title = Paragraph(disease_info.get('Title', 'Medical Condition Report'), styles['TitleStyle'])
authors = Paragraph("Generated by AIHealthCheck AI Assistant", styles['AuthorStyle'])
date = Paragraph(datetime.now().strftime("%B %d, %Y"), styles['AuthorStyle'])
story.append(title)
story.append(authors)
story.append(date)
story.append(NextPageTemplate('OtherPages')) # Switch to two-column layout
# Abstract
abstract_text = f"<b>Abstract</b><br/><br/>{disease_info.get('Overview', 'No overview available.')}"
abstract = Paragraph(abstract_text, styles['AbstractStyle'])
story.append(abstract)
# Function to format content
def format_content(text, styles):
if not text:
return []
# If it's a list, return each item as a bullet paragraph
if isinstance(text, list):
return [Paragraph(f"• {item}", styles) for item in text]
# If it's a dict, render each key-value pair
if isinstance(text, dict):
items = []
for key, value in text.items():
if isinstance(value, list):
items.append(Paragraph(f"<b>{key}:</b>", styles))
items.extend([Paragraph(f"• {v}", styles) for v in value])
else:
items.append(Paragraph(f"• <b>{key}:</b> {value}", styles))
return items
# Otherwise, treat it as a simple paragraph
return [Paragraph(text, styles)]
# Organize content into left and right columns
left_column_content = [
('Symptoms', disease_info.get('Symptoms')),
('Causes', disease_info.get('Causes')),
('Risk Factors', disease_info.get('Risk factors')),
('Complications', disease_info.get('Complications'))
]
right_column_content = [
('Diagnosis', disease_info.get('Diagnosis')),
('Treatment', disease_info.get('Treatment')),
('Prevention', disease_info.get('Prevention')),
('When to See a Doctor', disease_info.get('When to see a doctor')),
('Lifestyle and Home Remedies', disease_info.get('Lifestyle and home remedies'))
]
# Add left column content
for section, content in left_column_content:
if content:
story.append(Paragraph(section, styles['SectionHeader']))
formatted = format_content(content, styles['LeftColumn'])
if isinstance(formatted, list):
story.extend(formatted)
else:
story.append(formatted)
# Switch to right column
story.append(NextPageTemplate('OtherPages'))
# Add right column content
for section, content in right_column_content:
if content:
story.append(Paragraph(section, styles['SectionHeader']))
formatted = format_content(content, styles['RightColumn'])
if isinstance(formatted, list):
story.extend(formatted)
else:
story.append(formatted)
# Add references
story.append(Paragraph("Medical Recommendations", styles['SectionHeader']))
story.append(Paragraph(disease_info.get('Medical Recommendation', 'No medical recommendations available.'), styles['LeftColumn']))
story.append(Paragraph("References", styles['SectionHeader']))
story.append(Paragraph("1. Mayo Clinic Medical References", styles['Reference']))
# Build the PDF
doc.build(story)