A Python script that generates a professional PDF report with a title page, summary table, charts, and styled sections — ready to email or share.
ReportLab is the gold standard for PDF generation in Python — stable since 2000.
pip install reportlab
from reportlab.pdfgen import canvas
# Create a PDF
c = canvas.Canvas("report.pdf")
# Add text
c.setFont("Helvetica-Bold", 24)
c.drawString(100, 750, "Monthly Sales Report")
c.setFont("Helvetica", 12)
c.drawString(100, 720, "Generated: August 2026")
c.drawString(100, 700, "Prepared by: IT Expert Training")
c.save()
print("report.pdf created!")
report.pdf created!
Platypus (part of ReportLab) lets you build multi-page documents with paragraphs, tables, and images using a flow-based layout.
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
doc = SimpleDocTemplate(
"sales_report.pdf",
pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2*cm, bottomMargin=2*cm
)
styles = getSampleStyleSheet()
story = [] # list of flowables (content blocks)
# Title
title_style = ParagraphStyle(
'Title', parent=styles['Heading1'],
fontSize=22, textColor=colors.HexColor('#162447'),
spaceAfter=6
)
story.append(Paragraph("Monthly Sales Report — August 2026", title_style))
story.append(Paragraph("Prepared by IT Expert Training", styles['Normal']))
story.append(Spacer(1, 0.8*cm))
doc.build(story)
print("sales_report.pdf created!")
ReportLab tables accept a 2D list of data and a TableStyle to control colours and borders.
# Sales data
data = [
['Product', 'Units Sold', 'Revenue', 'Growth'],
['Python Course', '124', '₹1,24,000', '+18%'],
['Web Dev Course', '89', '₹89,000', '+12%'],
['AI Bootcamp', '56', '₹1,12,000', '+34%'],
['Arduino Kit', '210', '₹63,000', '+5%'],
['Total', '479', '₹3,88,000', '+17%'],
]
table = Table(data, colWidths=[5*cm, 3*cm, 3.5*cm, 2.5*cm])
table.setStyle(TableStyle([
# Header row
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#162447')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 10),
('ALIGN', (0,0), (-1,-1), 'CENTER'),
('ROWBACKGROUNDS',(0,1),(-1,-2), [colors.whitesmoke, colors.white]),
# Total row
('BACKGROUND', (0,-1),(-1,-1), colors.HexColor('#FFF3CD')),
('FONTNAME', (0,-1),(-1,-1), 'Helvetica-Bold'),
# Grid
('GRID', (0,0), (-1,-1), 0.5, colors.lightgrey),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING',(0,0), (-1,-1), 6),
]))
story.append(Paragraph("Sales Summary", styles['Heading2']))
story.append(Spacer(1, 0.3*cm))
story.append(table)
story.append(Spacer(1, 0.8*cm))
Generate a chart with matplotlib, save it as an image, and embed it in the PDF.
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('Agg') # non-interactive backend for saving files
from reportlab.platypus import Image
import io
# Create bar chart
products = ['Python\nCourse', 'Web Dev\nCourse', 'AI\nBootcamp', 'Arduino\nKit']
revenue = [124000, 89000, 112000, 63000]
fig, ax = plt.subplots(figsize=(6, 3))
bars = ax.bar(products, revenue, color=['#162447','#1E3A6E','#F59C0D','#e74c3c'])
ax.set_title('Revenue by Product', fontweight='bold')
ax.set_ylabel('Revenue (₹)')
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f'₹{x/1000:.0f}K'))
for bar, val in zip(bars, revenue):
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 1000,
f'₹{val//1000}K', ha='center', fontsize=9, fontweight='bold')
plt.tight_layout()
# Save chart to memory buffer (no temp file needed)
buf = io.BytesIO()
fig.savefig(buf, format='png', dpi=150, bbox_inches='tight')
buf.seek(0)
plt.close()
story.append(Paragraph("Revenue Chart", styles['Heading2']))
story.append(Spacer(1, 0.3*cm))
story.append(Image(buf, width=14*cm, height=7*cm))
# Build the final PDF
doc.build(story)
print("sales_report.pdf ready!")
sales_report.pdf ready! [PDF opens with: title, date, styled table with coloured header and alternating rows, bar chart]
You generated a professional multi-section PDF entirely in Python — no Word, no Excel, no manual formatting. ReportLab has been stable since 2000 and powers PDF generation for banks, governments, and major enterprises.
Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.