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"Abstract

{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"{key}:", styles)) items.extend([Paragraph(f"• {v}", styles) for v in value]) else: items.append(Paragraph(f"• {key}: {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)