reportlab
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReportLab
ReportLab
Overview
概述
ReportLab is a powerful open-source Python library for creating PDF documents programmatically. Generate professional PDFs with precise control over layout, typography, graphics, tables, and charts. Perfect for automated report generation, invoices, certificates, and custom documents.
ReportLab是一款功能强大的开源Python库,用于以程序化方式创建PDF文档。您可以通过它生成专业的PDF文档,对布局、排版、图形、表格和图表进行精确控制。非常适合自动生成报告、发票、证书和自定义文档。
When to Use This Skill
何时使用该技能
Activate when the user:
- Wants to generate PDF documents programmatically
- Needs to create invoices, reports, or receipts
- Asks to create certificates, labels, or forms
- Mentions ReportLab explicitly
- Wants custom PDF layouts with tables, charts, or graphics
- Needs to automate document generation
- Wants precise control over PDF layout and styling
当用户有以下需求时启用该技能:
- 想要以程序化方式生成PDF文档
- 需要创建发票、报告或收据
- 要求创建证书、标签或表单
- 明确提及ReportLab
- 需要包含表格、图表或图形的自定义PDF布局
- 需要实现文档生成自动化
- 希望对PDF布局和样式进行精确控制
Installation
安装
Check if ReportLab is installed:
bash
python3 -c "import reportlab; print(reportlab.Version)"If not installed:
bash
pip3 install reportlabFor additional fonts and features:
bash
pip3 install reportlab[renderPM,rlPyCairo]检查ReportLab是否已安装:
bash
python3 -c "import reportlab; print(reportlab.Version)"如果未安装:
bash
pip3 install reportlab如需额外字体和功能:
bash
pip3 install reportlab[renderPM,rlPyCairo]Two Approaches: Canvas vs Platypus
两种实现方式:Canvas vs Platypus
ReportLab provides two APIs:
Canvas API (Low-Level)
- Direct drawing on PDF pages
- Precise positioning with x, y coordinates
- Like painting on a canvas
- Best for: Simple documents, custom layouts, graphics-heavy PDFs
Platypus API (High-Level)
- Flowable document elements
- Automatic layout and pagination
- Easier for complex multi-page documents
- Best for: Reports, articles, documents with lots of text
ReportLab提供两种API:
Canvas API(底层)
- 直接在PDF页面上绘图
- 使用x、y坐标进行精确定位
- 类似于在画布上绘画
- 最适合:简单文档、自定义布局、图形密集型PDF
Platypus API(高级)
- 支持流式文档元素
- 自动布局和分页
- 更易于创建复杂的多页文档
- 最适合:报告、文章、包含大量文本的文档
Canvas API (Low-Level Drawing)
Canvas API(底层绘图)
Basic Canvas Usage
Canvas基础用法
python
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.units import inchpython
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.units import inchCreate PDF
Create PDF
c = canvas.Canvas("output.pdf", pagesize=letter)
width, height = letter
c = canvas.Canvas("output.pdf", pagesize=letter)
width, height = letter
Draw text
Draw text
c.drawString(100, height - 100, "Hello, World!")
c.drawString(100, height - 100, "Hello, World!")
Set font
Set font
c.setFont("Helvetica-Bold", 24)
c.drawString(100, height - 150, "Large Bold Text")
c.setFont("Helvetica-Bold", 24)
c.drawString(100, height - 150, "Large Bold Text")
Save PDF
Save PDF
c.save()
undefinedc.save()
undefinedDrawing Shapes and Lines
绘制形状和线条
python
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
c = canvas.Canvas("shapes.pdf", pagesize=letter)
width, height = letterpython
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
c = canvas.Canvas("shapes.pdf", pagesize=letter)
width, height = letterLine
Line
c.line(50, height - 50, width - 50, height - 50)
c.line(50, height - 50, width - 50, height - 50)
Rectangle
Rectangle
c.rect(50, height - 200, 200, 100, stroke=1, fill=0)
c.rect(50, height - 200, 200, 100, stroke=1, fill=0)
Filled rectangle with color
Filled rectangle with color
c.setFillColor(colors.lightblue)
c.setStrokeColor(colors.blue)
c.rect(300, height - 200, 200, 100, stroke=1, fill=1)
c.setFillColor(colors.lightblue)
c.setStrokeColor(colors.blue)
c.rect(300, height - 200, 200, 100, stroke=1, fill=1)
Circle
Circle
c.circle(150, height - 350, 50, stroke=1, fill=0)
c.circle(150, height - 350, 50, stroke=1, fill=0)
Rounded rectangle
Rounded rectangle
c.roundRect(300, height - 400, 200, 100, 10, stroke=1, fill=0)
c.save()
undefinedc.roundRect(300, height - 400, 200, 100, 10, stroke=1, fill=0)
c.save()
undefinedWorking with Text
文本处理
python
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
c = canvas.Canvas("text.pdf", pagesize=letter)
width, height = letterpython
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
c = canvas.Canvas("text.pdf", pagesize=letter)
width, height = letterDifferent fonts and sizes
Different fonts and sizes
c.setFont("Helvetica", 12)
c.drawString(50, height - 50, "Helvetica 12pt")
c.setFont("Helvetica-Bold", 16)
c.drawString(50, height - 80, "Helvetica Bold 16pt")
c.setFont("Times-Roman", 14)
c.drawString(50, height - 110, "Times Roman 14pt")
c.setFont("Helvetica", 12)
c.drawString(50, height - 50, "Helvetica 12pt")
c.setFont("Helvetica-Bold", 16)
c.drawString(50, height - 80, "Helvetica Bold 16pt")
c.setFont("Times-Roman", 14)
c.drawString(50, height - 110, "Times Roman 14pt")
Colored text
Colored text
c.setFillColor(colors.red)
c.drawString(50, height - 140, "Red text")
c.setFillColor(colors.blue)
c.drawString(50, height - 170, "Blue text")
c.setFillColor(colors.red)
c.drawString(50, height - 140, "Red text")
c.setFillColor(colors.blue)
c.drawString(50, height - 170, "Blue text")
Text alignment
Text alignment
text = "Right-aligned text"
text_width = c.stringWidth(text, "Helvetica", 12)
c.setFont("Helvetica", 12)
c.setFillColor(colors.black)
c.drawString(width - text_width - 50, height - 200, text)
text = "Right-aligned text"
text_width = c.stringWidth(text, "Helvetica", 12)
c.setFont("Helvetica", 12)
c.setFillColor(colors.black)
c.drawString(width - text_width - 50, height - 200, text)
Multi-line text with textobject
Multi-line text with textobject
textobject = c.beginText(50, height - 250)
textobject.setFont("Helvetica", 12)
textobject.textLines("""This is multi-line text.
Each line will be rendered separately.
Great for paragraphs!""")
c.drawText(textobject)
c.save()
undefinedtextobject = c.beginText(50, height - 250)
textobject.setFont("Helvetica", 12)
textobject.textLines("""This is multi-line text.
Each line will be rendered separately.
Great for paragraphs!""")
c.drawText(textobject)
c.save()
undefinedAdding Images
添加图片
python
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
c = canvas.Canvas("images.pdf", pagesize=letter)
width, height = letterpython
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
c = canvas.Canvas("images.pdf", pagesize=letter)
width, height = letterDraw image
Draw image
c.drawImage("logo.png", 50, height - 200, width=2inch, height=1inch)
c.drawImage("logo.png", 50, height - 200, width=2inch, height=1inch)
Image with preserved aspect ratio
Image with preserved aspect ratio
c.drawImage("photo.jpg", 50, height - 400, width=3*inch, preserveAspectRatio=True)
c.save()
undefinedc.drawImage("photo.jpg", 50, height - 400, width=3*inch, preserveAspectRatio=True)
c.save()
undefinedPlatypus API (High-Level Documents)
Platypus API(高级文档)
Basic Document Structure
基础文档结构
python
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inchpython
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inchCreate document
Create document
doc = SimpleDocTemplate("document.pdf", pagesize=letter)
story = [] # Container for flowable elements
doc = SimpleDocTemplate("document.pdf", pagesize=letter)
story = [] # Container for flowable elements
Get styles
Get styles
styles = getSampleStyleSheet()
styles = getSampleStyleSheet()
Add content
Add content
story.append(Paragraph("Document Title", styles['Title']))
story.append(Spacer(1, 0.2*inch))
story.append(Paragraph("This is a paragraph of text.", styles['Normal']))
story.append(Paragraph("This is another paragraph.", styles['Normal']))
story.append(Paragraph("Document Title", styles['Title']))
story.append(Spacer(1, 0.2*inch))
story.append(Paragraph("This is a paragraph of text.", styles['Normal']))
story.append(Paragraph("This is another paragraph.", styles['Normal']))
Build PDF
Build PDF
doc.build(story)
undefineddoc.build(story)
undefinedWorking with Paragraphs and Styles
段落与样式处理
python
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_JUSTIFY
from reportlab.lib.units import inch
from reportlab.lib import colors
doc = SimpleDocTemplate("styled_doc.pdf", pagesize=letter)
story = []
styles = getSampleStyleSheet()python
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_JUSTIFY
from reportlab.lib.units import inch
from reportlab.lib import colors
doc = SimpleDocTemplate("styled_doc.pdf", pagesize=letter)
story = []
styles = getSampleStyleSheet()Built-in styles
Built-in styles
story.append(Paragraph("Title Style", styles['Title']))
story.append(Paragraph("Heading 1", styles['Heading1']))
story.append(Paragraph("Heading 2", styles['Heading2']))
story.append(Paragraph("Normal paragraph text.", styles['Normal']))
story.append(Spacer(1, 0.2*inch))
story.append(Paragraph("Title Style", styles['Title']))
story.append(Paragraph("Heading 1", styles['Heading1']))
story.append(Paragraph("Heading 2", styles['Heading2']))
story.append(Paragraph("Normal paragraph text.", styles['Normal']))
story.append(Spacer(1, 0.2*inch))
Custom style
Custom style
custom_style = ParagraphStyle(
'CustomStyle',
parent=styles['Normal'],
fontSize=14,
textColor=colors.blue,
alignment=TA_CENTER,
spaceAfter=10,
)
story.append(Paragraph("Centered blue text", custom_style))
custom_style = ParagraphStyle(
'CustomStyle',
parent=styles['Normal'],
fontSize=14,
textColor=colors.blue,
alignment=TA_CENTER,
spaceAfter=10,
)
story.append(Paragraph("Centered blue text", custom_style))
Justified paragraph
Justified paragraph
justified_style = ParagraphStyle(
'Justified',
parent=styles['Normal'],
alignment=TA_JUSTIFY,
)
long_text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " * 10
story.append(Paragraph(long_text, justified_style))
doc.build(story)
undefinedjustified_style = ParagraphStyle(
'Justified',
parent=styles['Normal'],
alignment=TA_JUSTIFY,
)
long_text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " * 10
story.append(Paragraph(long_text, justified_style))
doc.build(story)
undefinedCreating Tables
创建表格
python
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet
doc = SimpleDocTemplate("table.pdf", pagesize=letter)
story = []
styles = getSampleStyleSheet()
story.append(Paragraph("Sales Report", styles['Title']))python
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet
doc = SimpleDocTemplate("table.pdf", pagesize=letter)
story = []
styles = getSampleStyleSheet()
story.append(Paragraph("Sales Report", styles['Title']))Table data
Table data
data = [
['Product', 'Q1', 'Q2', 'Q3', 'Q4'],
['Widget A', '$1,000', '$1,200', '$1,100', '$1,300'],
['Widget B', '$800', '$900', '$950', '$1,000'],
['Widget C', '$1,500', '$1,600', '$1,700', '$1,800'],
['Total', '$3,300', '$3,700', '$3,750', '$4,100'],
]
data = [
['Product', 'Q1', 'Q2', 'Q3', 'Q4'],
['Widget A', '$1,000', '$1,200', '$1,100', '$1,300'],
['Widget B', '$800', '$900', '$950', '$1,000'],
['Widget C', '$1,500', '$1,600', '$1,700', '$1,800'],
['Total', '$3,300', '$3,700', '$3,750', '$4,100'],
]
Create table
Create table
table = Table(data)
table = Table(data)
Style table
Style table
table.setStyle(TableStyle([
# Header row
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, 0), 'CENTER'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 12),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
# Data rows
('BACKGROUND', (0, 1), (-1, -2), colors.beige),
('ALIGN', (1, 1), (-1, -1), 'RIGHT'),
('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
('FONTSIZE', (0, 1), (-1, -1), 10),
('GRID', (0, 0), (-1, -1), 1, colors.black),
# Total row
('BACKGROUND', (0, -1), (-1, -1), colors.lightgrey),
('FONTNAME', (0, -1), (-1, -1), 'Helvetica-Bold'),]))
story.append(table)
doc.build(story)
undefinedtable.setStyle(TableStyle([
# Header row
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, 0), 'CENTER'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 12),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
# Data rows
('BACKGROUND', (0, 1), (-1, -2), colors.beige),
('ALIGN', (1, 1), (-1, -1), 'RIGHT'),
('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
('FONTSIZE', (0, 1), (-1, -1), 10),
('GRID', (0, 0), (-1, -1), 1, colors.black),
# Total row
('BACKGROUND', (0, -1), (-1, -1), colors.lightgrey),
('FONTNAME', (0, -1), (-1, -1), 'Helvetica-Bold'),]))
story.append(table)
doc.build(story)
undefinedAdding Charts
添加图表
python
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.graphics.shapes import Drawing
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.graphics.charts.piecharts import Pie
from reportlab.lib import colors
doc = SimpleDocTemplate("charts.pdf", pagesize=letter)
story = []
styles = getSampleStyleSheet()
story.append(Paragraph("Sales Charts", styles['Title']))python
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.graphics.shapes import Drawing
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.graphics.charts.piecharts import Pie
from reportlab.lib import colors
doc = SimpleDocTemplate("charts.pdf", pagesize=letter)
story = []
styles = getSampleStyleSheet()
story.append(Paragraph("Sales Charts", styles['Title']))Bar chart
Bar chart
drawing = Drawing(400, 200)
bar_chart = VerticalBarChart()
bar_chart.x = 50
bar_chart.y = 50
bar_chart.height = 125
bar_chart.width = 300
bar_chart.data = [[100, 150, 200, 175, 225]]
bar_chart.categoryAxis.categoryNames = ['Q1', 'Q2', 'Q3', 'Q4', 'Q5']
bar_chart.bars[0].fillColor = colors.blue
drawing.add(bar_chart)
story.append(drawing)
drawing = Drawing(400, 200)
bar_chart = VerticalBarChart()
bar_chart.x = 50
bar_chart.y = 50
bar_chart.height = 125
bar_chart.width = 300
bar_chart.data = [[100, 150, 200, 175, 225]]
bar_chart.categoryAxis.categoryNames = ['Q1', 'Q2', 'Q3', 'Q4', 'Q5']
bar_chart.bars[0].fillColor = colors.blue
drawing.add(bar_chart)
story.append(drawing)
Pie chart
Pie chart
drawing2 = Drawing(400, 200)
pie = Pie()
pie.x = 150
pie.y = 50
pie.width = 100
pie.height = 100
pie.data = [30, 25, 20, 15, 10]
pie.labels = ['Product A', 'Product B', 'Product C', 'Product D', 'Other']
pie.slices.strokeWidth = 0.5
drawing2.add(pie)
story.append(drawing2)
doc.build(story)
undefineddrawing2 = Drawing(400, 200)
pie = Pie()
pie.x = 150
pie.y = 50
pie.width = 100
pie.height = 100
pie.data = [30, 25, 20, 15, 10]
pie.labels = ['Product A', 'Product B', 'Product C', 'Product D', 'Other']
pie.slices.strokeWidth = 0.5
drawing2.add(pie)
story.append(drawing2)
doc.build(story)
undefinedCommon Patterns
常见模式
See references/patterns.md for common patterns and uses.
如需常见模式和用法,请查看references/patterns.md。
Best Practices
最佳实践
- Choose the right API - Use Canvas for simple layouts, Platypus for complex documents
- Use constants for measurements - Use ,
inchfromcmreportlab.lib.units - Define styles once - Create custom styles and reuse them
- Test page sizes - Verify output on different page sizes (letter, A4, etc.)
- Handle images carefully - Check image paths exist before adding to PDF
- Use tables for layouts - Tables are great for structured layouts
- Cache fonts - Register custom fonts once at module level
- 选择合适的API - 简单布局使用Canvas,复杂文档使用Platypus
- 使用常量进行测量 - 使用中的
reportlab.lib.units、inch等单位cm - 一次性定义样式 - 创建自定义样式并重复使用
- 测试页面尺寸 - 在不同页面尺寸(如letter、A4等)上验证输出效果
- 谨慎处理图片 - 添加到PDF前检查图片路径是否存在
- 使用表格进行布局 - 表格非常适合结构化布局
- 缓存字体 - 在模块级别注册自定义字体一次即可
Common Issues
常见问题
Issue: Text going off page
问题:文本超出页面
Calculate available space before drawing:
python
from reportlab.lib.pagesizes import letter
width, height = letter
margin = 50 # pixels
usable_width = width - 2 * margin
usable_height = height - 2 * margin绘制前计算可用空间:
python
from reportlab.lib.pagesizes import letter
width, height = letter
margin = 50 # pixels
usable_width = width - 2 * margin
usable_height = height - 2 * marginIssue: Images not found
问题:图片未找到
Use absolute paths or verify file existence:
python
import os
image_path = "logo.png"
if os.path.exists(image_path):
c.drawImage(image_path, x, y, width=w, height=h)使用绝对路径或验证文件是否存在:
python
import os
image_path = "logo.png"
if os.path.exists(image_path):
c.drawImage(image_path, x, y, width=w, height=h)Issue: Unicode characters not displaying
问题:Unicode字符无法显示
Register and use TrueType fonts:
python
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
pdfmetrics.registerFont(TTFont('Arial', 'Arial.ttf'))
c.setFont('Arial', 12)注册并使用TrueType字体:
python
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
pdfmetrics.registerFont(TTFont('Arial', 'Arial.ttf'))
c.setFont('Arial', 12)Resources
资源
- references/api_reference.md: Quick reference for common ReportLab operations
- Official docs: https://docs.reportlab.com/
- User guide (PDF): https://www.reportlab.com/docs/reportlab-userguide.pdf
- PyPI: https://pypi.org/project/reportlab/
- references/api_reference.md:ReportLab常见操作快速参考
- 官方文档:https://docs.reportlab.com/
- 用户指南(PDF):https://www.reportlab.com/docs/reportlab-userguide.pdf
- PyPI:https://pypi.org/project/reportlab/