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.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
How to Build Dynamic PDF Reports with Python’s ReportLab

Install third‑party library

ReportLab is a third‑party Python library; install it first:

pip install reportlab

Module 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 img

Generate 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.

Report PDF preview
Report PDF preview
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

pdf-generationReportLabProgramming tutorial
MaGe Linux Operations
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.