claude-desktop-skills/reportlab/SKILL.md
PDF generation toolkit. Create invoices, reports, certificates, forms, charts, tables, barcodes, QR codes, Canvas/Platypus APIs, for professional document automation.
npx skillsauth add ViggyV/claude-skills reportlabInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
ReportLab is a powerful Python library for programmatic PDF generation. Create anything from simple documents to complex reports with tables, charts, images, and interactive forms.
Two main approaches:
Core capabilities:
onPage callback with Canvas)from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
c = canvas.Canvas("output.pdf", pagesize=letter)
width, height = letter
# Draw text
c.setFont("Helvetica-Bold", 24)
c.drawString(inch, height - inch, "Hello ReportLab!")
# Draw a rectangle
c.setFillColorRGB(0.2, 0.4, 0.8)
c.rect(inch, 5*inch, 4*inch, 2*inch, fill=1)
# Save
c.showPage()
c.save()
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch
doc = SimpleDocTemplate("output.pdf", pagesize=letter)
story = []
styles = getSampleStyleSheet()
# Add content
story.append(Paragraph("Document Title", styles['Title']))
story.append(Spacer(1, 0.2*inch))
story.append(Paragraph("This is body text with <b>bold</b> and <i>italic</i>.", styles['BodyText']))
# Build PDF
doc.build(story)
Tables work with both Canvas (via Drawing) and Platypus (as Flowables):
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colors
from reportlab.lib.units import inch
# Define data
data = [
['Product', 'Q1', 'Q2', 'Q3', 'Q4'],
['Widget A', '100', '150', '130', '180'],
['Widget B', '80', '120', '110', '160'],
]
# Create table
table = Table(data, colWidths=[2*inch, 1*inch, 1*inch, 1*inch, 1*inch])
# Apply styling
style = TableStyle([
# Header row
('BACKGROUND', (0, 0), (-1, 0), colors.darkblue),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
# Data rows
('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.lightgrey]),
('GRID', (0, 0), (-1, -1), 1, colors.black),
])
table.setStyle(style)
# Add to Platypus story
story.append(table)
# Or draw on Canvas
table.wrapOn(c, width, height)
table.drawOn(c, x, y)
Detailed table reference: See references/tables_reference.md for cell spanning, borders, alignment, and advanced styling.
Charts use the graphics framework and can be added to both Canvas and Platypus:
from reportlab.graphics.shapes import Drawing
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.lib import colors
# Create drawing
drawing = Drawing(400, 200)
# Create chart
chart = VerticalBarChart()
chart.x = 50
chart.y = 50
chart.width = 300
chart.height = 125
# Set data
chart.data = [[100, 150, 130, 180, 140]]
chart.categoryAxis.categoryNames = ['Q1', 'Q2', 'Q3', 'Q4', 'Q5']
# Style
chart.bars[0].fillColor = colors.blue
chart.valueAxis.valueMin = 0
chart.valueAxis.valueMax = 200
# Add to drawing
drawing.add(chart)
# Use in Platypus
story.append(drawing)
# Or render directly to PDF
from reportlab.graphics import renderPDF
renderPDF.drawToFile(drawing, 'chart.pdf', 'Chart Title')
Available chart types: Bar (vertical/horizontal), Line, Pie, Area, Scatter
Detailed charts reference: See references/charts_reference.md for all chart types, styling, legends, and customization.
from reportlab.graphics.barcode import code128
from reportlab.graphics.barcode.qr import QrCodeWidget
from reportlab.graphics.shapes import Drawing
from reportlab.graphics import renderPDF
# Code128 barcode (general purpose)
barcode = code128.Code128("ABC123456789", barHeight=0.5*inch)
# On Canvas
barcode.drawOn(c, x, y)
# QR Code
qr = QrCodeWidget("https://example.com")
qr.barWidth = 2*inch
qr.barHeight = 2*inch
# Wrap in Drawing for Platypus
d = Drawing()
d.add(qr)
story.append(d)
Supported formats: Code128, Code39, EAN-13, EAN-8, UPC-A, ISBN, QR, Data Matrix, and 20+ more
Detailed barcode reference: See references/barcodes_reference.md for all formats and usage examples.
from reportlab.platypus import Paragraph
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_JUSTIFY
# Create custom style
custom_style = ParagraphStyle(
'CustomStyle',
fontSize=12,
leading=14, # Line spacing
alignment=TA_JUSTIFY,
spaceAfter=10,
textColor=colors.black,
)
# Paragraph with inline formatting
text = """
This paragraph has <b>bold</b>, <i>italic</i>, and <u>underlined</u> text.
You can also use <font color="blue">colors</font> and <font size="14">different sizes</font>.
Chemical formula: H<sub>2</sub>O, Einstein: E=mc<sup>2</sup>
"""
para = Paragraph(text, custom_style)
story.append(para)
Using custom fonts:
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
# Register TrueType font
pdfmetrics.registerFont(TTFont('CustomFont', 'CustomFont.ttf'))
# Use in Canvas
c.setFont('CustomFont', 12)
# Use in Paragraph style
style = ParagraphStyle('Custom', fontName='CustomFont', fontSize=12)
Detailed text reference: See references/text_and_fonts.md for paragraph styles, font families, Asian languages, Greek letters, and formatting.
from reportlab.platypus import Image
from reportlab.lib.units import inch
# In Platypus
img = Image('photo.jpg', width=4*inch, height=3*inch)
story.append(img)
# Maintain aspect ratio
img = Image('photo.jpg', width=4*inch, height=3*inch, kind='proportional')
# In Canvas
c.drawImage('photo.jpg', x, y, width=4*inch, height=3*inch)
# With transparency (mask white background)
c.drawImage('logo.png', x, y, mask=[255,255,255,255,255,255])
from reportlab.pdfgen import canvas
from reportlab.lib.colors import black, white, lightgrey
c = canvas.Canvas("form.pdf")
# Text field
c.acroForm.textfield(
name="name",
tooltip="Enter your name",
x=100, y=700,
width=200, height=20,
borderColor=black,
fillColor=lightgrey,
forceBorder=True
)
# Checkbox
c.acroForm.checkbox(
name="agree",
x=100, y=650,
size=20,
buttonStyle='check',
checked=False
)
# Dropdown
c.acroForm.choice(
name="country",
x=100, y=600,
width=150, height=20,
options=[("United States", "US"), ("Canada", "CA")],
forceBorder=True
)
c.save()
Detailed PDF features reference: See references/pdf_features.md for forms, links, bookmarks, encryption, and metadata.
For Platypus documents, use page callbacks:
from reportlab.platypus import BaseDocTemplate, PageTemplate, Frame
def add_header_footer(canvas, doc):
"""Called on each page"""
canvas.saveState()
# Header
canvas.setFont('Helvetica', 9)
canvas.drawString(inch, height - 0.5*inch, "Document Title")
# Footer
canvas.drawRightString(width - inch, 0.5*inch, f"Page {doc.page}")
canvas.restoreState()
# Set up document
doc = BaseDocTemplate("output.pdf")
frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal')
template = PageTemplate(id='normal', frames=[frame], onPage=add_header_footer)
doc.addPageTemplates([template])
# Build with story
doc.build(story)
This skill includes helper scripts for common tasks:
Use scripts/quick_document.py for rapid document creation:
from scripts.quick_document import create_simple_document, create_styled_table
# Simple document from content blocks
content = [
{'type': 'heading', 'content': 'Introduction'},
{'type': 'paragraph', 'content': 'Your text here...'},
{'type': 'bullet', 'content': 'Bullet point'},
]
create_simple_document("output.pdf", "My Document", content_blocks=content)
# Styled tables with presets
data = [['Header1', 'Header2'], ['Data1', 'Data2']]
table = create_styled_table(data, style_name='striped') # 'default', 'striped', 'minimal', 'report'
Complete working examples in assets/:
assets/invoice_template.py - Professional invoice with:
from assets.invoice_template import create_invoice
create_invoice(
filename="invoice.pdf",
invoice_number="INV-2024-001",
invoice_date="January 15, 2024",
due_date="February 15, 2024",
company_info={'name': 'Acme Corp', 'address': '...', 'phone': '...', 'email': '...'},
client_info={'name': 'Client Name', ...},
items=[
{'description': 'Service', 'quantity': 1, 'unit_price': 500.00},
...
],
tax_rate=0.08,
notes="Thank you for your business!",
)
assets/report_template.py - Multi-page business report with:
from assets.report_template import create_report
report_data = {
'title': 'Quarterly Report',
'subtitle': 'Q4 2023',
'author': 'Analytics Team',
'sections': [
{
'title': 'Executive Summary',
'content': 'Report content...',
'table_data': {...},
'chart_data': {...}
},
...
]
}
create_report("report.pdf", report_data)
Comprehensive API references organized by feature:
references/canvas_api.md - Low-level Canvas: drawing primitives, coordinates, transformations, state management, images, pathsreferences/platypus_guide.md - High-level Platypus: document templates, frames, flowables, page layouts, TOCreferences/text_and_fonts.md - Text formatting: paragraph styles, inline markup, custom fonts, Asian languages, bullets, sequencesreferences/tables_reference.md - Tables: creation, styling, cell spanning, borders, alignment, colors, gradientsreferences/charts_reference.md - Charts: all chart types, data handling, axes, legends, colors, renderingreferences/barcodes_reference.md - Barcodes: Code128, QR codes, EAN, UPC, postal codes, and 20+ formatsreferences/pdf_features.md - PDF features: links, bookmarks, forms, encryption, metadata, page transitionsfrom reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
width, height = letter
margin = inch
# Top of page
y_top = height - margin
# Bottom of page
y_bottom = margin
from reportlab.lib.pagesizes import letter, A4, landscape
# US Letter (8.5" x 11")
pagesize=letter
# ISO A4 (210mm x 297mm)
pagesize=A4
# Landscape
pagesize=landscape(letter)
# Custom
pagesize=(6*inch, 9*inch)
drawImage() over drawInlineImage() - caches images for reusecanvas.Canvas("file.pdf", pageCompression=1)Centering text on Canvas:
text = "Centered Text"
text_width = c.stringWidth(text, "Helvetica", 12)
x = (width - text_width) / 2
c.drawString(x, y, text)
# Or use built-in
c.drawCentredString(width/2, y, text)
Page breaks in Platypus:
from reportlab.platypus import PageBreak
story.append(PageBreak())
Keep content together (no split):
from reportlab.platypus import KeepTogether
story.append(KeepTogether([
heading,
paragraph1,
paragraph2,
]))
Alternate row colors:
style = TableStyle([
('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.lightgrey]),
])
Text overlaps or disappears:
leading (line spacing) is greater than fontSizeTable doesn't fit on page:
repeatRowsBarcode not scanning:
barHeight (try 0.5 inch minimum)quiet=1 for quiet zonesFont not found:
pdfmetrics.registerFont()Images have white background:
mask parameter to make white transparentmask=[255,255,255,255,255,255]assets/invoice_template.pyassets/report_template.pycreate_styled_table()doc.multiBuild(story) for TOCshowPage() between labels or gridsuv pip install reportlab
# For image support
uv pip install pillow
# For charts
uv pip install reportlab[renderPM]
# For barcode support (included in reportlab)
# QR codes require: uv pip install qrcode
This skill should be used when:
This skill provides comprehensive guidance for all ReportLab capabilities, from simple documents to complex multi-page reports with charts, tables, and interactive elements.
data-ai
Use this skill for reinforcement learning tasks including training RL agents (PPO, SAC, DQN, TD3, DDPG, A2C, etc.), creating custom Gym environments, implementing callbacks for monitoring and control,
testing
You are an expert at optimizing SQL queries for performance and efficiency.
tools
Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like "make me a G
tools
21 production-ready scripts for iOS app testing, building, and automation. Provides semantic UI navigation, build automation, accessibility testing, and simulator lifecycle management. Optimized for A