No articles found
Try different keywords or browse our categories
Python ReportLab Tutorial: Edit PDF Files in Terminal
Learn how to use Python's ReportLab library to create and edit PDF files directly from the command line with practical examples.
ReportLab is a powerful Python library that allows you to create and manipulate PDF files programmatically. Unlike browser-based solutions, ReportLab gives you full control over PDF generation from the terminal, making it perfect for automation, batch processing, and server-side applications.
Why ReportLab?
ReportLab is ideal when you need to:
- Generate PDFs from Python scripts without a browser
- Automate PDF creation in server environments
- Create complex reports with precise layout control
- Batch process multiple PDFs from the command line
Installation
First, install ReportLab using pip:
pip install reportlab
For editing existing PDFs, you’ll also need PyPDF2:
pip install PyPDF2
Creating a Simple PDF
Let’s start with a basic example of creating a PDF from scratch:
# create_pdf.py
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
def create_simple_pdf(filename):
"""Create a simple PDF with text and shapes."""
# Create a canvas object
c = canvas.Canvas(filename, pagesize=letter)
width, height = letter
# Add title
c.setFont("Helvetica-Bold", 24)
c.drawString(100, height - 100, "My First PDF")
# Add body text
c.setFont("Helvetica", 12)
c.drawString(100, height - 150, "This PDF was created using ReportLab")
c.drawString(100, height - 170, "from a Python script in the terminal!")
# Draw a rectangle
c.rect(100, height - 250, 400, 50, stroke=1, fill=0)
# Add text inside rectangle
c.drawString(120, height - 230, "This is a text box")
# Save the PDF
c.save()
print(f"PDF created: {filename}")
if __name__ == "__main__":
create_simple_pdf("output.pdf")
Run it from terminal:
python create_pdf.py
Adding Multiple Pages
Working with multiple pages is straightforward:
# multi_page_pdf.py
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
def create_multi_page_pdf(filename):
"""Create a PDF with multiple pages."""
c = canvas.Canvas(filename, pagesize=letter)
width, height = letter
# Page 1
c.setFont("Helvetica-Bold", 20)
c.drawString(100, height - 100, "Page 1: Introduction")
c.setFont("Helvetica", 12)
c.drawString(100, height - 150, "This is the first page of our document.")
c.showPage() # Create new page
# Page 2
c.setFont("Helvetica-Bold", 20)
c.drawString(100, height - 100, "Page 2: Content")
c.setFont("Helvetica", 12)
c.drawString(100, height - 150, "Here's some content on the second page.")
c.showPage()
# Page 3
c.setFont("Helvetica-Bold", 20)
c.drawString(100, height - 100, "Page 3: Conclusion")
c.setFont("Helvetica", 12)
c.drawString(100, height - 150, "Thanks for reading!")
c.save()
print(f"Multi-page PDF created: {filename}")
if __name__ == "__main__":
create_multi_page_pdf("multi_page.pdf")
Adding Images and Graphics
ReportLab makes it easy to include images and draw shapes:
# pdf_with_images.py
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib.utils import ImageReader
def create_pdf_with_graphics(filename):
"""Create PDF with images and graphics."""
c = canvas.Canvas(filename, pagesize=letter)
width, height = letter
# Add title
c.setFont("Helvetica-Bold", 18)
c.drawString(100, height - 80, "Report with Graphics")
# Draw a blue circle
c.setFillColorRGB(0.2, 0.4, 0.8)
c.circle(300, height - 200, 50, fill=1)
# Draw a red rectangle
c.setFillColorRGB(0.8, 0.2, 0.2)
c.rect(100, height - 300, 150, 80, fill=1)
# Draw a line
c.setStrokeColorRGB(0, 0, 0)
c.setLineWidth(2)
c.line(100, height - 350, 500, height - 350)
# Add text with different colors
c.setFillColorRGB(0, 0, 0)
c.setFont("Helvetica", 12)
c.drawString(100, height - 400, "Blue circle, red rectangle, and black line")
c.save()
print(f"PDF with graphics created: {filename}")
if __name__ == "__main__":
create_pdf_with_graphics("graphics.pdf")
Editing Existing PDFs
To modify existing PDFs, combine ReportLab with PyPDF2:
# edit_pdf.py
from PyPDF2 import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
import io
def add_watermark_to_pdf(input_pdf, output_pdf, watermark_text):
"""Add a watermark to an existing PDF."""
# Read the existing PDF
reader = PdfReader(input_pdf)
writer = PdfWriter()
# Create watermark
packet = io.BytesIO()
can = canvas.Canvas(packet, pagesize=letter)
width, height = letter
# Set watermark properties
can.setFont("Helvetica-Bold", 60)
can.setFillColorRGB(0.5, 0.5, 0.5, alpha=0.3)
can.saveState()
can.translate(width/2, height/2)
can.rotate(45)
can.drawCentredString(0, 0, watermark_text)
can.restoreState()
can.save()
# Move to the beginning of the BytesIO buffer
packet.seek(0)
watermark_pdf = PdfReader(packet)
# Apply watermark to each page
for page_num in range(len(reader.pages)):
page = reader.pages[page_num]
page.merge_page(watermark_pdf.pages[0])
writer.add_page(page)
# Write output
with open(output_pdf, "wb") as output_file:
writer.write(output_file)
print(f"Watermarked PDF created: {output_pdf}")
if __name__ == "__main__":
add_watermark_to_pdf("input.pdf", "watermarked.pdf", "CONFIDENTIAL")
Creating a Table Report
Generate professional reports with tables:
# table_report.py
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.lib.units import inch
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
def create_table_report(filename):
"""Create a PDF report with a table."""
doc = SimpleDocTemplate(filename, pagesize=letter)
elements = []
styles = getSampleStyleSheet()
# Add title
title = Paragraph("<b>Sales Report - Q4 2024</b>", styles['Title'])
elements.append(title)
elements.append(Spacer(1, 0.5*inch))
# Create table data
data = [
['Product', 'Q1', 'Q2', 'Q3', 'Q4'],
['Product A', '$1,200', '$1,500', '$1,800', '$2,100'],
['Product B', '$800', '$900', '$1,000', '$1,200'],
['Product C', '$1,500', '$1,600', '$1,700', '$1,900'],
['Total', '$3,500', '$4,000', '$4,500', '$5,200']
]
# Create table
table = Table(data, colWidths=[2*inch, 1.5*inch, 1.5*inch, 1.5*inch, 1.5*inch])
# Style the table
table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 14),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
('BACKGROUND', (0, -1), (-1, -1), colors.beige),
('FONTNAME', (0, -1), (-1, -1), 'Helvetica-Bold'),
('GRID', (0, 0), (-1, -1), 1, colors.black)
]))
elements.append(table)
# Build PDF
doc.build(elements)
print(f"Table report created: {filename}")
if __name__ == "__main__":
create_table_report("sales_report.pdf")
Command-Line PDF Generator
Create a versatile script that accepts arguments:
#!/usr/bin/env python3
# pdf_generator.py
import argparse
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
def generate_pdf(title, content, filename):
"""Generate PDF from command-line arguments."""
c = canvas.Canvas(filename, pagesize=letter)
width, height = letter
# Add title
c.setFont("Helvetica-Bold", 20)
c.drawString(100, height - 100, title)
# Add content
c.setFont("Helvetica", 12)
y_position = height - 150
for line in content.split('\\n'):
c.drawString(100, y_position, line)
y_position -= 20
c.save()
print(f"PDF generated: {filename}")
def main():
parser = argparse.ArgumentParser(description='Generate PDF from terminal')
parser.add_argument('--title', required=True, help='PDF title')
parser.add_argument('--content', required=True, help='PDF content')
parser.add_argument('--output', required=True, help='Output filename')
args = parser.parse_args()
generate_pdf(args.title, args.content, args.output)
if __name__ == "__main__":
main()
Use it from terminal:
python pdf_generator.py --title "My Report" --content "Line 1\nLine 2\nLine 3" --output report.pdf
Best Practices
When working with ReportLab:
- Use context-appropriate page sizes -
letter,A4,legal, etc. - Set consistent fonts - Stick to standard fonts like Helvetica, Times, Courier
- Calculate positions carefully - Use variables for width and height
- Handle errors gracefully - Wrap file operations in try-except blocks
- Optimize for batch processing - Create reusable functions
- Test with different content - Ensure text doesn’t overflow
Conclusion
ReportLab is a robust solution for PDF generation and manipulation in Python. It excels at:
- Server-side PDF generation without browser dependencies
- Automation and batch processing of PDF documents
- Creating complex reports with precise layout control
- Integration with existing Python workflows and scripts
Whether you’re generating invoices, reports, certificates, or any other PDF document, ReportLab provides the flexibility and control you need directly from the terminal.
Start with simple examples and gradually build more complex PDF generation scripts. The terminal-based workflow makes it perfect for automation and integration into larger Python applications.
Related Articles
Python FFMPEG Integration: Edit Videos in Terminal
Master video editing from the command line using Python and FFmpeg. Learn to trim, merge, compress, and manipulate videos programmatically.
Generate Excel Files from Raw Data with Python
Quick guide to creating Excel files from raw data using Python. Learn to use openpyxl, xlsxwriter, and pandas for Excel generation.
Read and Write CSV Files with Python
Simple guide to reading and writing CSV files in Python using csv module and pandas. Quick examples for data processing.