data-export-pdf
Create professional PDF reports with text, tables, and embedded images using reportlab. Works with ANY LLM provider (GPT, Gemini, Claude, etc.).
Install
mkdir -p .claude/skills/data-export-pdf && curl -L -o skill.zip "https://mcp.directory/api/skills/download/2784" && unzip -o skill.zip -d .claude/skills/data-export-pdf && rm skill.zipInstalls to .claude/skills/data-export-pdf
About this skill
PDF Report Generation (Universal)
Overview
This skill enables you to create professional PDF reports containing analysis summaries, formatted tables, and embedded visualizations. Unlike cloud-hosted solutions, this skill uses the reportlab Python library and executes locally in your environment, making it compatible with ALL LLM providers including GPT, Gemini, Claude, DeepSeek, and Qwen.
When to Use This Skill
- Generate analysis reports with text and tables
- Create summary PDFs with embedded plots
- Export formatted documentation
- Produce publication-ready supplementary materials
- Combine multiple analysis results into a single document
How to Use
Step 1: Import Required Libraries
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak, Image
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from datetime import datetime
import matplotlib.pyplot as plt
Step 2: Create Basic PDF Document
# Create PDF file
pdf_filename = "analysis_report.pdf"
doc = SimpleDocTemplate(pdf_filename, pagesize=letter)
story = [] # Container for PDF elements
# Get default styles
styles = getSampleStyleSheet()
title_style = styles['Title']
heading_style = styles['Heading1']
normal_style = styles['Normal']
# Add title
story.append(Paragraph("Analysis Report", title_style))
story.append(Spacer(1, 0.2*inch))
# Add date
date_text = f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}"
story.append(Paragraph(date_text, normal_style))
story.append(Spacer(1, 0.3*inch))
# Build PDF
doc.build(story)
print(f"✅ PDF saved to: {pdf_filename}")
Step 3: Add Text Content
story = []
# Title
story.append(Paragraph("Single-Cell RNA-seq Analysis Report", title_style))
story.append(Spacer(1, 0.2*inch))
# Section heading
story.append(Paragraph("1. Overview", heading_style))
story.append(Spacer(1, 0.1*inch))
# Paragraph text
overview_text = """
This report summarizes the single-cell RNA-seq analysis performed on the dataset.
The analysis includes quality control, normalization, dimensionality reduction,
clustering, and cell type annotation.
"""
story.append(Paragraph(overview_text, normal_style))
story.append(Spacer(1, 0.2*inch))
Step 4: Add Tables
# Prepare table data
table_data = [
['Metric', 'Value'], # Header
['Total Cells', '5,000'],
['Total Genes', '20,000'],
['Mean Genes/Cell', '2,500'],
['Median UMIs/Cell', '10,000']
]
# Create table
table = Table(table_data, colWidths=[2.5*inch, 2*inch])
# Style table
table.setStyle(TableStyle([
# Header styling
('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), 12),
# Body styling
('BACKGROUND', (0, 1), (-1, -1), colors.beige),
('GRID', (0, 0), (-1, -1), 1, colors.black),
('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
('FONTSIZE', (0, 1), (-1, -1), 10),
]))
story.append(table)
story.append(Spacer(1, 0.3*inch))
Step 5: Embed Images/Plots
# Save matplotlib figure first
fig, ax = plt.subplots(figsize=(6, 4))
# ... create your plot ...
plot_filename = "temp_plot.png"
fig.savefig(plot_filename, dpi=150, bbox_inches='tight')
plt.close(fig)
# Add image to PDF
story.append(Paragraph("2. UMAP Visualization", heading_style))
story.append(Spacer(1, 0.1*inch))
img = Image(plot_filename, width=4*inch, height=3*inch)
story.append(img)
story.append(Spacer(1, 0.2*inch))
Complete Example: Analysis Report
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image
from datetime import datetime
import matplotlib.pyplot as plt
import pandas as pd
def create_analysis_report(adata, output_path="analysis_report.pdf"):
"""Create comprehensive PDF analysis report"""
# Initialize PDF
doc = SimpleDocTemplate(output_path, pagesize=letter)
story = []
styles = getSampleStyleSheet()
# Title
story.append(Paragraph("Single-Cell RNA-seq Analysis Report", styles['Title']))
story.append(Spacer(1, 0.2*inch))
story.append(Paragraph(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}", styles['Normal']))
story.append(Spacer(1, 0.3*inch))
# Overview
story.append(Paragraph("1. Dataset Overview", styles['Heading1']))
story.append(Spacer(1, 0.1*inch))
overview_data = [
['Metric', 'Value'],
['Total Cells', f'{adata.n_obs:,}'],
['Total Genes', f'{adata.n_vars:,}'],
['Observations', ', '.join(adata.obs.columns[:5].tolist())],
]
table = Table(overview_data, colWidths=[2.5*inch, 3.5*inch])
table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('GRID', (0, 0), (-1, -1), 1, colors.black),
('BACKGROUND', (0, 1), (-1, -1), colors.beige),
]))
story.append(table)
story.append(Spacer(1, 0.3*inch))
# Cluster distribution
if 'clusters' in adata.obs:
story.append(Paragraph("2. Cluster Distribution", styles['Heading1']))
story.append(Spacer(1, 0.1*inch))
cluster_counts = adata.obs['clusters'].value_counts().sort_index()
cluster_data = [['Cluster', 'Cell Count', 'Percentage']]
total_cells = adata.n_obs
for cluster, count in cluster_counts.items():
percentage = (count / total_cells) * 100
cluster_data.append([str(cluster), str(count), f'{percentage:.1f}%'])
table = Table(cluster_data, colWidths=[1.5*inch, 1.5*inch, 1.5*inch])
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'),
('GRID', (0, 0), (-1, -1), 1, colors.black),
('BACKGROUND', (0, 1), (-1, -1), colors.lightblue),
]))
story.append(table)
story.append(Spacer(1, 0.3*inch))
# Visualization (if UMAP exists)
if 'X_umap' in adata.obsm:
story.append(Paragraph("3. UMAP Visualization", styles['Heading1']))
story.append(Spacer(1, 0.1*inch))
# Create UMAP plot
fig, ax = plt.subplots(figsize=(6, 5))
scatter = ax.scatter(
adata.obsm['X_umap'][:, 0],
adata.obsm['X_umap'][:, 1],
c=adata.obs['clusters'].astype('category').cat.codes if 'clusters' in adata.obs else 'blue',
s=5, alpha=0.5
)
ax.set_xlabel('UMAP1')
ax.set_ylabel('UMAP2')
ax.set_title('UMAP Projection')
plot_path = 'temp_umap.png'
fig.savefig(plot_path, dpi=150, bbox_inches='tight')
plt.close(fig)
img = Image(plot_path, width=5*inch, height=4*inch)
story.append(img)
# Build PDF
doc.build(story)
print(f"✅ PDF report saved to: {output_path}")
return output_path
# Usage
create_analysis_report(adata, "my_analysis_report.pdf")
Best Practices
- Page Size: Use
letter(US) orA4(international) for standard documents - Margins: SimpleDocTemplate has default margins (1 inch); adjust with
leftMargin,rightMargin, etc. - Images: Save matplotlib figures at 150-300 DPI for good quality
- Tables: Keep column counts reasonable (4-6 columns max for readability)
- File Cleanup: Delete temporary image files after PDF creation
- Memory: For large documents, build in sections to manage memory
Advanced Features
Custom Page Header/Footer
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
def add_header_footer(canvas_obj, doc):
canvas_obj.saveState()
# Header
canvas_obj.setFont('Helvetica', 9)
canvas_obj.drawString(inch, letter[1] - 0.5*inch, "Analysis Report")
# Footer
canvas_obj.drawString(inch, 0.5*inch, f"Page {doc.page}")
canvas_obj.restoreState()
doc = SimpleDocTemplate(pdf_filename, pagesize=letter)
doc.build(story, onFirstPage=add_header_footer, onLaterPages=add_header_footer)
Multi-Column Layout
from reportlab.platypus import Frame, PageTemplate
frame1 = Frame(doc.leftMargin, doc.bottomMargin, doc.width/2-6, doc.height, id='col1')
frame2 = Frame(doc.leftMargin+doc.width/2+6, doc.bottomMargin, doc.width/2-6, doc.height, id='col2')
doc.addPageTemplates([PageTemplate(id='TwoCol', frames=[frame1, frame2])])
Color-Coded Tables
# Highlight significant results
for i, row in enumerate(deg_results):
if row['qvalue'] < 0.05:
table.setStyle(TableStyle([
('BACKGROUND', (0, i+1), (-1, i+1), colors.yellow)
]))
Common Use Cases
QC Report
qc_metrics = {
'Total Cells': adata.n_obs,
'Median Genes/Cell': int(adata.obs['n_genes'].median()),
'Median UMIs/Cell': int(adata.obs['n_counts'].median()),
'Mean Mito %': f"{adata.obs['percent_mito'].mean():.2f}%"
}
table_data = [['Metric', 'Value']] + [[k, str(v)] for k, v in qc_metrics.items()]
# ... create table as shown above
DEG Summary Table
# Top 10 upregulated genes
top_genes = deg_df.nlargest(10, 'log2FC')[['gene', 'log2FC', 'qvalue']]
table_data = [['Gene', 'log2FC', 'Q-value']]
for _, row in top_genes.iterrows():
table_data.append([
---
*Content truncated.*
More by Starlitnightly
View all skills by Starlitnightly →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversConnect Blender to Claude AI for seamless 3D modeling. Use AI 3D model generator tools for faster, intuitive, interactiv
Create modern React UI components instantly with Magic AI Agent. Integrates with top IDEs for fast, stunning design and
Create and edit PowerPoint presentations in Python with Office PowerPoint. Use python pptx or pptx python tools to add s
Unlock powerful text to speech and AI voice generator tools with ElevenLabs. Create, clone, and customize speech easily.
Unlock powerful Excel automation: read/write Excel files, create sheets, and automate workflows with seamless integratio
Use our meme generator to quickly create your memes with ImgFlip API. Make your meme easily by adding text and templates
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.