How to Build Dynamic PDF Reports with Python’s ReportLab
This tutorial explains how to use Python’s ReportLab library to create PDF reports by installing the package, importing modules, registering fonts, defining a Graphs class with static methods for titles, paragraphs, tables, images, and bar charts, and assembling these elements into a final PDF document.
Install third‑party library
ReportLab is a third‑party Python library; install it first:
pip install reportlabModule import
Import the necessary modules and register a font (prepare the font file beforehand).
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import Table, SimpleDocTemplate, Paragraph, Image
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib import colors
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.graphics.charts.legends import Legend
from reportlab.graphics.shapes import Drawing
from reportlab.lib.units import cm
pdfmetrics.registerFont(TTFont('SimSun', 'SimSun.ttf'))Encapsulate content functions
Create a Graphs class with static methods that return ReportLab flowable objects for titles, subtitles, plain text, tables, bar charts, and images. The methods set styles such as font name, size, color, alignment, and table formatting.
class Graphs:
@staticmethod
def draw_title(title: str):
style = getSampleStyleSheet()
ct = style['Heading1']
ct.fontName = 'SimSun'
ct.fontSize = 18
ct.leading = 50
ct.textColor = colors.green
ct.alignment = 1
ct.bold = True
return Paragraph(title, ct)
@staticmethod
def draw_little_title(title: str):
style = getSampleStyleSheet()
ct = style['Normal']
ct.fontName = 'SimSun'
ct.fontSize = 15
ct.leading = 30
ct.textColor = colors.red
return Paragraph(title, ct)
@staticmethod
def draw_text(text: str):
style = getSampleStyleSheet()
ct = style['Normal']
ct.fontName = 'SimSun'
ct.fontSize = 12
ct.wordWrap = 'CJK'
ct.alignment = 0
ct.firstLineIndent = 32
ct.leading = 25
return Paragraph(text, ct)
@staticmethod
def draw_table(*args):
col_width = 120
style = [
('FONTNAME', (0,0), (-1,-1), 'SimSun'),
('FONTSIZE', (0,0), (-1,0), 12),
('FONTSIZE', (0,1), (-1,-1), 10),
('BACKGROUND', (0,0), (-1,0), '#d5dae6'),
('ALIGN', (0,0), (-1,0), 'CENTER'),
('ALIGN', (0,1), (-1,-1), 'LEFT'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TEXTCOLOR', (0,0), (-1,-1), colors.darkslategray),
('GRID', (0,0), (-1,-1), 0.5, colors.grey)
]
table = Table(args, colWidths=col_width, style=style)
return table
@staticmethod
def draw_bar(bar_data: list, ax: list, items: list):
drawing = Drawing(500, 250)
bc = VerticalBarChart()
bc.x = 45
bc.y = 45
bc.height = 200
bc.width = 350
bc.data = bar_data
bc.strokeColor = colors.black
bc.valueAxis.valueMin = 5000
bc.valueAxis.valueMax = 26000
bc.valueAxis.valueStep = 2000
bc.categoryAxis.labels.dx = 2
bc.categoryAxis.labels.dy = -8
bc.categoryAxis.labels.angle = 20
bc.categoryAxis.categoryNames = ax
leg = Legend()
leg.fontName = 'SimSun'
leg.alignment = 'right'
leg.boxAnchor = 'ne'
leg.x = 475
leg.y = 240
leg.dxTextSpace = 10
leg.columnMaximum = 3
leg.colorNamePairs = items
drawing.add(leg)
drawing.add(bc)
return drawing
@staticmethod
def draw_img(path):
img = Image(path)
img.drawWidth = 5 * cm
img.drawHeight = 8 * cm
return imgGenerate report
Assemble the flowables into a list, add titles, images, text, tables, and charts, then build the PDF with SimpleDocTemplate.
if __name__ == '__main__':
content = list()
content.append(Graphs.draw_title('Data Analysis Salary'))
content.append(Graphs.draw_img('anti_epidemic.png'))
content.append(Graphs.draw_text('...'))
content.append(Graphs.draw_little_title('Average Salary by Level'))
data = [
('Position', 'Average Salary', 'Year‑over‑Year Growth'),
('Data Analyst', '18.5K', '25%'),
('Senior Data Analyst', '25.5K', '14%'),
('Lead Data Analyst', '29.3K', '10%')
]
content.append(Graphs.draw_table(*data))
b_data = [(25400,12900,20100,20300,20300,17400), (15800,9700,12982,9283,13900,7623)]
ax_data = ['Beijing','Chengdu','Shenzhen','Shanghai','Hangzhou','Nanjing']
leg_items = [(colors.red,'Average Salary'), (colors.green,'Recruitment')]
content.append(Graphs.draw_bar(b_data, ax_data, leg_items))
doc = SimpleDocTemplate('report.pdf', pagesize=letter)
doc.build(content)The generated PDF contains the formatted title, an illustrative image, descriptive text, a salary table, and a bar chart showing employment data across major cities.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
