102 lines
3.3 KiB
Python
102 lines
3.3 KiB
Python
|
|
from reportlab.lib import colors
|
||
|
|
from reportlab.lib.pagesizes import letter
|
||
|
|
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
||
|
|
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
|
||
|
|
from reportlab.lib.enums import TA_CENTER, TA_LEFT
|
||
|
|
from io import BytesIO
|
||
|
|
|
||
|
|
|
||
|
|
def create_pdf(data, output_filename=None):
|
||
|
|
try:
|
||
|
|
# Create a BytesIO buffer to store the PDF
|
||
|
|
buffer = BytesIO()
|
||
|
|
|
||
|
|
# Create the PDF document using the buffer
|
||
|
|
doc = SimpleDocTemplate(buffer, pagesize=letter)
|
||
|
|
styles = getSampleStyleSheet()
|
||
|
|
|
||
|
|
# All content will use the same font size
|
||
|
|
STANDARD_FONT_SIZE = 12
|
||
|
|
|
||
|
|
# Create custom styles with consistent font size
|
||
|
|
styles.add(ParagraphStyle(
|
||
|
|
name='ThemeTitle',
|
||
|
|
fontSize=STANDARD_FONT_SIZE,
|
||
|
|
alignment=TA_CENTER,
|
||
|
|
spaceAfter=15,
|
||
|
|
fontName='Helvetica-Bold', # Bold style
|
||
|
|
leading=14 # Line spacing (1.0)
|
||
|
|
))
|
||
|
|
|
||
|
|
styles.add(ParagraphStyle(
|
||
|
|
name='QuestionTitle',
|
||
|
|
fontSize=STANDARD_FONT_SIZE,
|
||
|
|
alignment=TA_LEFT,
|
||
|
|
spaceAfter=10,
|
||
|
|
fontName='Helvetica-Bold',
|
||
|
|
leading=14,
|
||
|
|
textColor=colors.black
|
||
|
|
))
|
||
|
|
|
||
|
|
styles.add(ParagraphStyle(
|
||
|
|
name='SectionTitle',
|
||
|
|
fontSize=STANDARD_FONT_SIZE,
|
||
|
|
alignment=TA_LEFT,
|
||
|
|
spaceAfter=4,
|
||
|
|
fontName='Helvetica-Bold',
|
||
|
|
leading=14
|
||
|
|
))
|
||
|
|
|
||
|
|
styles.add(ParagraphStyle(
|
||
|
|
name='NormalText',
|
||
|
|
fontSize=STANDARD_FONT_SIZE,
|
||
|
|
alignment=TA_LEFT,
|
||
|
|
spaceAfter=2,
|
||
|
|
leftIndent=20,
|
||
|
|
leading=14,
|
||
|
|
fontName='Helvetica' # Regular font
|
||
|
|
))
|
||
|
|
|
||
|
|
# Build the document content
|
||
|
|
story = []
|
||
|
|
|
||
|
|
# Add theme title on first page
|
||
|
|
if data:
|
||
|
|
theme_title = data.get('theme_title', 'No Title Provided')
|
||
|
|
story.append(Paragraph(f"THEME: {theme_title.upper()}", styles['ThemeTitle']))
|
||
|
|
story.append(Spacer(1, 10))
|
||
|
|
|
||
|
|
# Process each question data
|
||
|
|
for i, item in enumerate(data if isinstance(data, list) else [data]):
|
||
|
|
story.append(Paragraph(f"<b>{item['question']}</b>", styles['QuestionTitle']))
|
||
|
|
|
||
|
|
# Add each section with proper handling
|
||
|
|
sections = ['Situation', 'Task', 'Action', 'Results and Transitions', 'Personal Lessons',
|
||
|
|
'Observations of Others', 'Professional Connection']
|
||
|
|
for section in sections:
|
||
|
|
story.append(Paragraph(f"{section}:", styles['SectionTitle']))
|
||
|
|
for point in item.get(section, []):
|
||
|
|
story.append(Paragraph(f"• {point}", styles['NormalText']))
|
||
|
|
|
||
|
|
# Add a page break after each question except the last one
|
||
|
|
if i < len(data) - 1:
|
||
|
|
story.append(PageBreak())
|
||
|
|
|
||
|
|
# Build the PDF into the buffer
|
||
|
|
doc.build(story)
|
||
|
|
|
||
|
|
# Get the PDF content from the buffer
|
||
|
|
pdf_content = buffer.getvalue()
|
||
|
|
buffer.close()
|
||
|
|
|
||
|
|
# If output_filename is provided, also save to file
|
||
|
|
if output_filename:
|
||
|
|
with open(output_filename, 'wb') as f:
|
||
|
|
f.write(pdf_content)
|
||
|
|
|
||
|
|
return pdf_content
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
print(f"Error: {e}")
|
||
|
|
return {}
|