mcpField
R
reportlab

reportlab

github.com/jackspace文档处理1640 次安装12 周前更新
代码仓库

关于 reportlab

reportlab 技能为需要程序化生成 PDF 的开发者提供 ReportLab 使用指南、参考文档和脚本示例,涵盖精确绘制与自动分页文档布局。

主要功能

  1. 01Canvas 精确定位绘制
  2. 02Platypus 自动分页排版
  3. 03生成表格与图表
  4. 04添加条码和二维码
  5. 05制作交互式 PDF 表单

适用场景

  1. 01生成发票和收据
  2. 02制作多页业务报告
  3. 03创建证书与标签
  4. 04设计可填写 PDF 表单

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jackspace/claudeskillz --skill reportlab

安装后在 Claude Code 中输入/reportlab确认已加载。

附带文件SKILL.json

详细介绍

ReportLab PDF 生成

概述

ReportLab 是一个功能强大的 Python 库,可用于以编程方式生成 PDF。它可以创建从简单文档到包含表格、图表、图片和交互式表单的复杂报告。

两种主要方式:

  • Canvas API(低级):通过基于坐标的定位直接绘制,适用于需要精确布局的场景
  • Platypus(高级):采用流式文档布局并自动分页,适用于多页文档

核心功能:

  • 支持丰富格式和自定义字体的文本
  • 支持复杂样式和单元格合并的表格
  • 图表(柱状图、折线图、饼图、面积图、散点图)
  • 条形码和二维码(Code128、EAN、QR 等)
  • 支持透明度的图片
  • PDF 功能(链接、书签、表单、加密)

选择合适的方式

在以下情况下使用 Canvas API:
  • 创建标签、名片、证书
  • 精确定位至关重要(x、y 坐标)
  • 单页文档或简单布局
  • 绘制图形、形状和自定义设计
  • 在特定位置添加条形码或二维码
在以下情况下使用 Platypus:
  • 创建多页文档(报告、文章、书籍)
  • 内容需要自动在页面间流动
  • 需要在每页重复显示页眉/页脚
  • 处理可以跨页拆分的段落
  • 构建包含目录的复杂文档
在以下情况下同时使用两者:
  • 复杂报告既需要流式内容,也需要精确定位
  • 为 Platypus 文档添加页眉/页脚(使用 onPage 回调和 Canvas)
  • 在流式文档(Platypus)中嵌入自定义图形(Canvas)

快速入门示例

简单的 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()
简单的 Platypus 文档
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)

常见任务

创建表格

Canvas(通过 Drawing)和 Platypus(作为 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)

详细的表格参考: 有关单元格合并、边框、对齐和高级样式,请参阅 references/tables_reference.md。

创建图表

图表使用图形框架,可添加到 Canvas 和 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')

可用的图表类型: 柱状图(垂直/水平)、折线图、饼图、面积图、散点图
详细的图表参考: 有关所有图表类型、样式、图例和自定义设置,请参阅 references/charts_reference.md。

添加条形码和二维码
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)

支持的格式: Code128、Code39、EAN-13、EAN-8、UPC-A、ISBN、QR、Data Matrix 等 20 多种格式
详细的条形码参考: 有关所有格式和用法示例,请参阅 references/barcodes_reference.md。

使用文本和字体
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)

使用自定义字体:

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)

详细的文本参考: 有关段落样式、字体系列、亚洲语言、希腊字母和格式设置,请参阅 references/text_and_fonts.md。

添加图片
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()

详细的 PDF 功能参考: 有关表单、链接、书签、加密和元数据,请参阅 references/pdf_features.md。

页眉和页脚

对于 Platypus 文档,请使用页面回调:

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)

辅助脚本

此技能包含用于常见任务的辅助脚本:

快速文档生成器

使用 scripts/quick_document.py 快速创建文档:

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'

模板示例

assets/ 中的完整可运行示例:

发票模板

assets/invoice_template.py - 专业发票,包含:

  • 公司和客户信息
  • 含计算结果的明细表
  • 税费和总计
  • 条款和备注
  • Logo 放置
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 - 多页业务报告,包含:

  • 封面
  • 目录
  • 带有子章节的多个章节
  • 图表和表格
  • 页眉和页脚
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)

参考文档

按功能整理的综合 API 参考:

  • references/canvas_api.md - 底层 Canvas:绘图基元、坐标、变换、状态管理、图像、路径
  • references/platypus_guide.md - 高层 Platypus:文档模板、框架、Flowable、页面布局、目录
  • references/text_and_fonts.md - 文本格式:段落样式、行内标记、自定义字体、亚洲语言、项目符号、序列
  • references/tables_reference.md - 表格:创建、样式设置、单元格跨列或跨行、边框、对齐、颜色、渐变
  • references/charts_reference.md - 图表:所有图表类型、数据处理、坐标轴、图例、颜色、渲染
  • references/barcodes_reference.md - 条形码:Code128、QR 码、EAN、UPC、邮政编码及 20 多种格式
  • references/pdf_features.md - PDF 功能:链接、书签、表单、加密、元数据、页面过渡

最佳实践

坐标系统(Canvas)
  • 原点 (0, 0) 位于左下角(而非左上角)
  • Y 轴向上
  • 单位为点(72 点 = 1 英寸)
  • 始终明确指定页面尺寸
from 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)
性能提示
  1. 优先使用 drawImage(),而非 drawInlineImage() - 可缓存图像以供重复使用
  2. 为大型文件启用压缩: canvas.Canvas("file.pdf", pageCompression=1)
  3. 重复使用样式 - 创建一次,在整个文档中使用
  4. 对重复图形使用 Forms/XObjects
常见模式

在 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)

在 Platypus 中分页:

from reportlab.platypus import PageBreak

story.append(PageBreak())

保持内容在同一页(不拆分):

from reportlab.platypus import KeepTogether

story.append(KeepTogether([
    heading,
    paragraph1,
    paragraph2,
]))

交替设置行颜色:

style = TableStyle([
    ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.lightgrey]),
])

故障排除

文本重叠或消失:

  • 检查 Y 坐标——请记住原点位于左下角
  • 确保文本未超出页面边界
  • 确认 leading(行间距)大于 fontSize

表格无法放入页面:

  • 缩小列宽
  • 减小字号
  • 使用横向页面
  • 启用表格拆分,并设置 repeatRows

条形码无法扫描:

  • 增大 barHeight(建议至少为 0.5 英寸)
  • 设置 quiet=1 以启用静区
  • 测试打印质量(建议 300+ DPI)
  • 验证条形码类型对应的数据格式

找不到字体:

  • 使用 pdfmetrics.registerFont() 注册 TrueType 字体
  • 使用与注册时完全一致的字体系列名称
  • 检查字体文件路径是否正确

图像带有白色背景:

  • 使用 mask 参数将白色设为透明
  • 提供要屏蔽的 RGB 范围:mask=[255,255,255,255,255,255]
  • 或使用带 Alpha 通道的 PNG

示例工作流

创建发票
  1. 从 assets/invoice_template.py 中的发票模板开始
  2. 自定义公司信息和徽标路径
  3. 添加包含描述、数量、价格的项目
  4. 如适用,设置税率
  5. 添加备注和付款条款
  6. 生成 PDF
创建报告
  1. 从 assets/report_template.py 中的报告模板开始
  2. 定义包含标题和内容的章节
  3. 使用 create_styled_table() 添加数据表格
  4. 使用图形框架添加图表
  5. 使用 doc.multiBuild(story) 构建文档以生成目录
创建证书
  1. 使用 Canvas API 精确定位
  2. 加载自定义字体,打造优雅的排版
  3. 添加边框图形或背景图像
  4. 放置文本元素(姓名、日期、成就)
  5. 可选:添加用于验证的 QR 码
创建带条形码的标签
  1. 使用 Canvas 并设置自定义页面尺寸(标签尺寸)
  2. 计算网格位置,以便在每页上放置多个标签
  3. 绘制标签内容(文本、图像)
  4. 在指定位置添加条形码
  5. 在标签或网格之间使用 showPage()

安装

pip install reportlab

# For image support
pip install pillow

# For charts
pip install reportlab[renderPM]

# For barcode support (included in reportlab)
# QR codes require: pip install qrcode

何时使用此技能

在以下情况下应使用此技能:

  • 以编程方式生成 PDF 文档
  • 创建发票、收据或账单文档
  • 构建包含表格和图表的报告
  • 生成证书、徽章或凭证
  • 创建带有条形码的运输标签或产品标签
  • 设计表单或可填写的 PDF
  • 制作格式统一的多页文档
  • 将数据转换为 PDF 格式,以便归档或分发
  • 创建需要精确定位的自定义布局

此技能全面介绍了 ReportLab 的所有功能,从简单文档到包含图表、表格和交互元素的复杂多页报告。

评论

支持 Markdown