Spaces:
Runtime error
Runtime error
| 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) | |