Fundamentals 9 min read

Generating PDF Reports with Python ReportLab: Installation, Imports, and Example Code

This tutorial demonstrates how to use Python's ReportLab library to create PDF reports, covering installation, module imports, font registration, and a Graphs class with static methods for titles, paragraphs, tables, bar charts, and images, culminating in a complete script that assembles and builds the PDF.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Generating PDF Reports with Python ReportLab: Installation, Imports, and Example Code

ReportLab is a Python library that enables drawing graphics, tables, and text to produce PDF files, similar to creating Word or PowerPoint documents.

First, install the third‑party package: pip install reportlab Import the necessary modules and register a custom font (e.g., SimSun):

from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
pdfmetrics.registerFont(TTFont('SimSun', 'SimSun.ttf'))

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

A Graphs class is defined with static methods to create different parts of the report, such as titles, subtitles, regular paragraphs, tables, bar charts, and images. Each method configures styles (font, size, color, alignment) and returns the appropriate ReportLab flowable object.

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
        ct.alignment = 0
        ct.bold = True
        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

The main script creates a list of flowable objects, adds a title, an image, descriptive text, subtitles, a data table, and a bar chart, then builds the PDF document using SimpleDocTemplate('report.pdf', pagesize=letter).

if __name__ == '__main__':
    content = []
    content.append(Graphs.draw_title('数据分析就业薪资'))
    content.append(Graphs.draw_img('抗疫必胜.png'))
    content.append(Graphs.draw_text('众所周知,大数据分析师岗位是香饽饽,近几年数据分析热席卷了整个互联网行业,与数据分析的相关的岗位招聘、培训数不胜数。很多人前赴后继,想要参与到这波红利当中。那么数据分析师就业前景到底怎么样呢?'))
    content.append(Graphs.draw_little_title('不同级别的平均薪资'))
    data = [
        ('职位名称', '平均薪资', '较上年增长率'),
        ('数据分析师', '18.5K', '25%'),
        ('高级数据分析师', '25.5K', '14%'),
        ('资深数据分析师', '29.3K', '10%')
    ]
    content.append(Graphs.draw_table(*data))
    content.append(Graphs.draw_little_title('热门城市的就业情况'))
    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, '平均薪资'), (colors.green, '招聘量')]
    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, image, explanatory paragraph, a table of average salaries by position, and a bar chart showing employment data across major cities.

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.

PythonData visualizationReportLab
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

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.