OpenSpace pdf-checklist-generator

Generate structured PDF checklists and reports with tables, sections, and scoring criteria using Python libraries

install
source · Clone the upstream repo
git clone https://github.com/HKUDS/OpenSpace
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/HKUDS/OpenSpace "$T" && mkdir -p ~/.claude/skills && cp -r "$T/gdpval_bench/skills/pdf-checklist-generator" ~/.claude/skills/hkuds-openspace-pdf-checklist-generator && rm -rf "$T"
manifest: gdpval_bench/skills/pdf-checklist-generator/SKILL.md
source content

PDF Checklist/Report Generator

This skill provides a reusable pattern for creating professional PDF documents (checklists, reports, scorecards) using Python libraries within

execute_code_sandbox
.

When to Use This Skill

  • Need to generate structured PDF documents programmatically
  • Creating checklists with scoring criteria
  • Building reports with tables, sections, and formatted content
  • Producing downloadable artifacts for workflow tasks

Library Selection

Choose the appropriate library based on your needs:

LibraryBest ForInstallation
reportlabComplex layouts, tables, precise control
pip install reportlab
fpdf2Simple documents, easy API
pip install fpdf2
matplotlibCharts/graphs in PDFs
pip install matplotlib

Step-by-Step Procedure

Step 1: Plan Document Structure

Define the sections, tables, and scoring criteria before coding:

  • Document title and metadata
  • Section headers
  • Table columns and rows
  • Scoring rubric (if applicable)

Step 2: Write Python Code in execute_code_sandbox

Use

execute_code_sandbox
with the appropriate library. Here are templates:

Template A: Using reportlab (recommended for tables)

from reportlab.lib import colors
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch

# Create PDF
doc = SimpleDocTemplate("checklist.pdf", pagesize=letter)
elements = []
styles = getSampleStyleSheet()

# Title
title_style = ParagraphStyle('CustomTitle', parent=styles['Heading1'], alignment=1)
elements.append(Paragraph("Compliance Checklist", title_style))
elements.append(Spacer(1, 0.25*inch))

# Create table data
data = [
    ['Criteria', 'Status', 'Score', 'Notes'],
    ['Security Review', 'Pass', '10', 'All checks passed'],
    ['Code Quality', 'Pass', '8', 'Minor improvements'],
    ['Documentation', 'Pending', '5', 'Needs updates'],
]

# Create and style table
table = Table(data, colWidths=[3*inch, 1*inch, 1*inch, 2*inch])
table.setStyle(TableStyle([
    ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
    ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
    ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
    ('GRID', (0, 0), (-1, -1), 1, colors.black),
    ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
]))
elements.append(table)

# Build PDF
doc.build(elements)
print("PDF created: checklist.pdf")
print(f"ARTIFACT_PATH:/workspace/checklist.pdf")

Template B: Using fpdf2 (simpler API)

from fpdf import FPDF

pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", "B", 16)
pdf.cell(0, 10, "Project Report", ln=True, align='C')

pdf.set_font("Arial", size=12)
pdf.ln(10)

# Add sections
sections = [
    ("Executive Summary", "Project completed successfully."),
    ("Key Findings", "All milestones achieved on time."),
    ("Recommendations", "Continue current practices."),
]

for title, content in sections:
    pdf.set_font("Arial", "B", 14)
    pdf.cell(0, 10, title, ln=True)
    pdf.set_font("Arial", size=12)
    pdf.multi_cell(0, 8, content)
    pdf.ln(5)

pdf.output("report.pdf")
print("PDF created: report.pdf")
print(f"ARTIFACT_PATH:/workspace/report.pdf")

Template C: Checklist with Scoring

from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib import colors

doc = SimpleDocTemplate("scorecard.pdf", pagesize=letter)
elements = []
styles = getSampleStyleSheet()

# Title
elements.append(Paragraph("Evaluation Scorecard", styles['Heading1']))
elements.append(Spacer(1, 0.25*inch))

# Scoring criteria table
criteria = [
    ['Category', 'Weight', 'Score (0-10)', 'Weighted'],
    ['Functionality', '30%', '9', '2.7'],
    ['Performance', '25%', '8', '2.0'],
    ['Security', '25%', '10', '2.5'],
    ['Documentation', '20%', '7', '1.4'],
    ['TOTAL', '100%', '-', '8.6/10'],
]

table = Table(criteria, colWidths=[2.5*inch, 1*inch, 1.5*inch, 1.5*inch])
table.setStyle(TableStyle([
    ('BACKGROUND', (0, 0), (-1, 0), colors.darkblue),
    ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
    ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
    ('GRID', (0, 0), (-1, -1), 1, colors.black),
    ('FONTNAME', (0, -1), (-1, -1), 'Helvetica-Bold'),
    ('BACKGROUND', (0, -1), (-1, -1), colors.lightgrey),
]))
elements.append(table)

doc.build(elements)
print("ARTIFACT_PATH:/workspace/scorecard.pdf")

Step 3: Include ARTIFACT_PATH in Output

Always include the artifact path in your print output so the system can locate the generated file:

print(f"ARTIFACT_PATH:/workspace/your_filename.pdf")

Step 4: Verify Output

After generation, verify the PDF was created successfully:

Option A: Use read_file

read_file with filetype="pdf" and file_path="/workspace/checklist.pdf"

Option B: Use shell inspection

run_shell with command="ls -la /workspace/*.pdf"

Common Patterns

Pattern 1: Multi-Section Report

sections = [
    ("Introduction", "Overview text..."),
    ("Methodology", "Process description..."),
    ("Results", "Findings summary..."),
    ("Conclusion", "Final recommendations..."),
]

for title, content in sections:
    elements.append(Paragraph(title, styles['Heading2']))
    elements.append(Paragraph(content, styles['Normal']))
    elements.append(Spacer(1, 0.2*inch))

Pattern 2: Status Indicator Table

status_colors = {
    'Pass': colors.green,
    'Fail': colors.red,
    'Pending': colors.orange,
    'N/A': colors.grey,
}

# Apply conditional coloring in table style
for row_idx, row_data in enumerate(data[1:], 1):
    status = row_data[1]
    if status in status_colors:
        table.setStyle(TableStyle([
            ('BACKGROUND', (1, row_idx), (1, row_idx), status_colors[status]),
        ]))

Pattern 3: Page Breaks for Long Documents

from reportlab.platypus import PageBreak

elements.append(PageBreak())  # Insert page break

Troubleshooting

IssueSolution
Library not foundAdd
pip install <library>
at start of code
Font errorsUse built-in fonts: Arial, Helvetica, Times-Roman
Table overflowAdjust
colWidths
or split into multiple tables
PDF not createdCheck ARTIFACT_PATH is correct and file is written

Best Practices

  1. Always verify: Check the PDF exists and is readable after generation
  2. Use ARTIFACT_PATH: Include it in output for system discovery
  3. Keep it readable: Use adequate spacing (
    Spacer
    ) between elements
  4. Test incrementally: Build complex PDFs section by section
  5. Handle errors: Wrap file operations in try/except blocks

Example Complete Workflow

# 1. Install library
!pip install reportlab -q

# 2. Generate PDF
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors

doc = SimpleDocTemplate("/workspace/checklist.pdf", pagesize=letter)
elements = []
styles = getSampleStyleSheet()

elements.append(Paragraph("Task Completion Checklist", styles['Heading1']))
elements.append(Spacer(1, 0.25*inch))

data = [['Task', 'Complete', 'Notes'],
        ['Setup environment', 'Yes', ''],
        ['Run tests', 'Yes', 'All passed'],
        ['Documentation', 'No', 'In progress']]

table = Table(data)
table.setStyle(TableStyle([('GRID', (0,0), (-1,-1), 1, colors.black)]))
elements.append(table)

doc.build(elements)
print("ARTIFACT_PATH:/workspace/checklist.pdf")

# 3. Verify
import os
print(f"File exists: {os.path.exists('/workspace/checklist.pdf')}")
print(f"File size: {os.path.getsize('/workspace/checklist.pdf')} bytes")