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.

PDFdata visualizationReportLabreport-generation
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

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