Last modified: Feb 07, 2026 By Alexander Williams

Python Code to PDF | Generate Reports & Documents

Python makes creating PDFs easy. You can turn code, data, and text into polished documents. This is vital for reports, invoices, and automated workflows.

Several powerful libraries handle this task. Each has unique strengths for different needs.

Why Generate PDFs with Python?

PDFs are the standard for sharing documents. They preserve formatting across all devices and operating systems.

Using Python to create them automates manual work. You can generate hundreds of personalized reports from a database in minutes.

This is useful for data analysis, business documentation, and application logging. For reading existing PDFs, see our Python PDF Reader Guide.

Top Python Libraries for PDF Generation

You have excellent choices. ReportLab is the most powerful for complex layouts. FPDF is simple and straightforward. WeasyPrint is great for converting HTML.

1. ReportLab: For Advanced Layouts

ReportLab is the industry standard for programmatic PDFs. It offers pixel-level control over every element on the page.

You can draw shapes, use custom fonts, and create multi-column layouts. It is perfect for invoices, certificates, and branded reports.

First, install it using pip.


pip install reportlab
    

Here is a basic example to create a simple PDF with text.


from reportlab.pdfgen import canvas

# Create a canvas object to draw on
pdf_canvas = canvas.Canvas("hello_reportlab.pdf")

# Set the title
pdf_canvas.setTitle("My First ReportLab PDF")

# Draw a string at coordinates (100, 750). Origin is bottom-left.
pdf_canvas.drawString(100, 750, "Hello, World! From ReportLab.")
pdf_canvas.drawString(100, 730, "This PDF was generated programmatically.")

# Save the canvas to the PDF file
pdf_canvas.save()

print("PDF created successfully: hello_reportlab.pdf")
    

PDF created successfully: hello_reportlab.pdf
    

The canvas.Canvas() function creates the PDF file. The drawString() method places text at specific X, Y coordinates. Remember to call save() to write the file.

2. FPDF: Simple and Lightweight

FPDF stands for "Free PDF." It is a simpler library inspired by PHP's FPDF. It is easier to learn for basic text-based documents.

Install it with pip.


pip install fpdf
    

This example creates a PDF with a title and a paragraph.


from fpdf import FPDF

# Create instance of FPDF class
pdf = FPDF()

# Add a page
pdf.add_page()

# Set font: family, style, size
pdf.set_font("Arial", "B", 16)

# Add a cell for the title
pdf.cell(200, 10, txt="Welcome to FPDF", ln=1, align='C')

# Set font for body text
pdf.set_font("Arial", size=12)

# Add a multi-line cell for body text
pdf.multi_cell(0, 10, txt="This is a simple paragraph created using the FPDF library in Python. It automatically handles line breaks and text wrapping.")

# Output the PDF to a file
pdf.output("simple_fpdf_document.pdf")

print("FPDF document created: simple_fpdf_document.pdf")
    

FPDF document created: simple_fpdf_document.pdf
    

The add_page() method starts a new page. The cell() method creates a text box. Use multi_cell() for text that wraps. Finally, output() saves the file.

3. WeasyPrint: HTML to PDF

WeasyPrint converts HTML and CSS into PDF. This is perfect if you already know web development.

You design your document like a webpage. Then WeasyPrint renders it as a PDF. Install it via pip.


pip install weasyprint
    

Create an HTML file as a template, then convert it.


from weasyprint import HTML

# HTML content as a string
html_content = """
<!DOCTYPE html>
<html>
<head>
    <style>
        body { font-family: Arial, sans-serif; }
        h1 { color: #2c3e50; }
        .content { padding: 20px; }
    </style>
</head>
<body>
    <div class="content">
        <h1>Monthly Data Report</h1>
        <p>This report was generated automatically using WeasyPrint.</p>
        <ul>
            <li>Total Users: 1,250</li>
            <li>Revenue: $45,670</li>
            <li>Growth: +12.5%</li>
        </ul>
    </div>
</body>
</html>
"""

# Generate PDF from HTML string
HTML(string=html_content).write_pdf("weasyprint_report.pdf")

print("PDF generated from HTML: weasyprint_report.pdf")
    

PDF generated from HTML: weasyprint_report.pdf
    

The HTML() class parses the HTML. The write_pdf() method does the conversion. You can also pass a URL or file path to HTML().

Adding Images and Styling

Professional PDFs need images and better styling. Here is how to add an image with ReportLab.


from reportlab.pdfgen import canvas
from reportlab.lib.units import inch

c = canvas.Canvas("report_with_image.pdf")
c.setFont("Helvetica", 14)
c.drawString(1*inch, 10*inch, "Quarterly Report with Chart")

# Draw an image. Provide path, x, y, width, height.
# The image should be in the same directory or provide full path.
c.drawImage("chart.png", 1*inch, 5*inch, width=5*inch, height=3*inch)

c.drawString(1*inch, 4*inch, "Figure 1: Sales Performance Q1")
c.save()
print("PDF with image created.")
    

For adding metadata like author and keywords, which is crucial for document management, techniques shown in our guide on Python PdfWriter.add_metadata are very useful.

Creating Multi-Page Documents

Real-world reports span multiple pages. Libraries handle this automatically when content overflows.

With FPDF, you can manually add pages and control page breaks.


from fpdf import FPDF

pdf = FPDF()
pdf.set_font("Arial", size=12)

for page_num in range(1, 4):
    pdf.add_page()
    pdf.cell(0, 10, txt=f"This is the content for Page {page_num}", ln=1, align='C')
    # Add a lot of lines to demonstrate page break in a real scenario
    for i in range(1, 40):
        pdf.cell(0, 10, txt=f"Line {i} on page {page_num}.", ln=1)

pdf.output("multi_page_fpdf.pdf")
print("Multi-page PDF created.")
    

Practical Use Case: Data Report to PDF

Let's combine pandas for data analysis with ReportLab for PDF output. This is a common automation task.


import pandas as pd
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter

# Sample data
data = {
    'Product': ['Widget A', 'Widget B', 'Widget C'],
    'Q1 Sales': [12000, 8000, 15000],
    'Q2 Sales': [14000, 9500, 16000]
}
df = pd.DataFrame(data)

# Create PDF
c = canvas.Canvas("sales_report.pdf", pagesize=letter)
width, height = letter
c.setFont("Helvetica-Bold", 16)
c.drawString(100, height - 100, "Annual Sales Report")

c.setFont("Helvetica", 12)
y_position = height - 150

# Draw table headers
c.drawString(100, y_position, "Product")
c.drawString(250, y_position, "Q1 Sales")
c.drawString(350, y_position, "Q2 Sales")
y_position -= 30

# Draw table rows from DataFrame
for index, row in df.iterrows():
    c.drawString(100, y_position, row['Product'])
    c.drawString(250, y_position, f"${row['Q1 Sales']:,}")
    c.drawString(350, y_position, f"${row['Q2 Sales']:,}")
    y_position -= 20
    if y_position < 100:  # Simple page break check
        c.showPage()
        y_position = height - 100
        c.setFont("Helvetica", 12)

c.save()
print("Sales report PDF generated from DataFrame.")
    

This script turns a DataFrame into a formatted table in a PDF. For extracting data from existing PDF forms, methods like getFields are essential, as detailed in our Python PdfReader.getFields guide.

Conclusion

Generating PDFs from Python code is a powerful skill. ReportLab is best for precise, complex documents. FPDF is excellent for quick, simple text-based PDFs. WeasyPrint is ideal if you work with HTML and CSS.

Start with a simple script. Automate a weekly report or an invoice. The ability to create documents programmatically saves immense time and reduces errors.

Combine these libraries with data from pandas, SQL databases, or web APIs. You can build robust document automation systems. The key is to choose the right tool for your specific project's requirements.