home / skills / jwynia / agent-skills / pdf-generator

This skill helps you generate and manipulate PDF documents programmatically, including form filling, overlays, merging, and scratch generation from JSON.

npx playbooks add skill jwynia/agent-skills --skill pdf-generator

Review the files below or copy the command above to add this skill to your agents.

Files (4)
SKILL.md
9.5 KB
---
name: pdf-generator
description: "Create and manipulate PDF files programmatically. Use when the user needs to generate PDFs, fill PDF forms, extract PDF content, add watermarks/overlays, or merge documents. Supports both template-based generation (form filling, overlays) and from-scratch creation. Keywords: PDF, document, form, fillable, merge, watermark, extract, text, report."
license: MIT
compatibility: Requires Deno with --allow-read, --allow-write permissions
metadata:
  author: agent-skills
  version: "1.0"
  type: generator
  mode: generative
  domain: documents
---

# PDF Generator

## When to Use This Skill

Use this skill when:
- Creating PDF documents programmatically from data or specifications
- Filling PDF forms with dynamic data
- Adding watermarks, stamps, or overlays to existing PDFs
- Extracting text and metadata from PDF files
- Merging multiple PDFs into one document
- Analyzing PDF structure and form fields

Do NOT use this skill when:
- User wants to open/view PDFs (use native PDF viewer)
- Complex page layout with flowing text is needed (consider HTML-to-PDF tools)
- Working with password-protected PDFs (limited support)
- OCR is needed for scanned documents

## Prerequisites

- Deno installed (https://deno.land/)
- Input PDF files for template-based operations
- JSON specification for scratch generation

## Quick Start

### Two Modes of Operation

1. **Template Mode**: Modify existing PDF templates
   - Fill form fields (text, checkbox, dropdown)
   - Add overlays (text, images, shapes)
   - Merge and combine PDFs

2. **Scratch Mode**: Create PDFs from nothing using JSON specifications

## Instructions

### Mode 1: Template-Based Generation

#### Step 1a: Analyze the Template

Extract form fields and structure from an existing PDF:

```bash
deno run --allow-read scripts/analyze-template.ts form-template.pdf > inventory.json
```

**Output** (inventory.json):
```json
{
  "filename": "form-template.pdf",
  "pageCount": 2,
  "title": "Application Form",
  "author": "Company Inc",
  "pages": [
    { "pageNumber": 1, "width": 612, "height": 792, "text": "..." }
  ],
  "formFields": [
    { "name": "FullName", "type": "text", "value": "" },
    { "name": "Email", "type": "text", "value": "" },
    { "name": "AgreeToTerms", "type": "checkbox", "value": false }
  ],
  "placeholders": [
    { "tag": "{{DATE}}", "location": "page 1", "pageNumber": 1 }
  ],
  "hasFormFields": true
}
```

#### Step 1b: Create Fill Specification

Create `form-data.json`:
```json
{
  "formFields": [
    { "name": "FullName", "value": "John Smith" },
    { "name": "Email", "value": "[email protected]" },
    { "name": "AgreeToTerms", "value": true }
  ],
  "flattenForm": true
}
```

#### Step 1c: Generate Filled PDF

```bash
deno run --allow-read --allow-write scripts/generate-from-template.ts \
  form-template.pdf form-data.json filled-form.pdf
```

### Adding Overlays (Watermarks, Stamps)

Create `watermark-spec.json`:
```json
{
  "overlays": [
    {
      "type": "text",
      "page": 1,
      "x": 200,
      "y": 400,
      "text": "CONFIDENTIAL",
      "fontSize": 48,
      "color": { "r": 1, "g": 0, "b": 0 },
      "rotate": 45
    },
    {
      "type": "image",
      "page": 1,
      "x": 450,
      "y": 700,
      "path": "logo.png",
      "width": 100,
      "height": 50
    }
  ]
}
```

### Merging PDFs

Create `merge-spec.json`:
```json
{
  "prependPdfs": [
    { "path": "cover-page.pdf" }
  ],
  "appendPdfs": [
    { "path": "appendix-a.pdf", "pages": [1, 2, 3] },
    { "path": "appendix-b.pdf" }
  ],
  "excludePages": [5, 6]
}
```

### Mode 2: From-Scratch Generation

#### Step 2a: Create Specification

Create `spec.json`:
```json
{
  "title": "Quarterly Report",
  "author": "Finance Team",
  "pages": [
    {
      "size": "A4",
      "elements": [
        {
          "type": "text",
          "x": 50,
          "y": 750,
          "text": "Q4 2024 Financial Report",
          "fontSize": 28,
          "font": "HelveticaBold",
          "color": { "r": 0, "g": 0, "b": 0.5 }
        },
        {
          "type": "line",
          "startX": 50,
          "startY": 740,
          "endX": 550,
          "endY": 740,
          "thickness": 2
        },
        {
          "type": "text",
          "x": 50,
          "y": 700,
          "text": "Executive Summary",
          "fontSize": 18,
          "font": "HelveticaBold"
        },
        {
          "type": "text",
          "x": 50,
          "y": 670,
          "text": "This quarter showed strong growth across all divisions...",
          "fontSize": 12,
          "maxWidth": 500,
          "lineHeight": 16
        }
      ]
    }
  ]
}
```

#### Step 2b: Generate PDF

```bash
deno run --allow-read --allow-write scripts/generate-scratch.ts spec.json output.pdf
```

## Examples

### Example 1: Fill Application Form

**Scenario**: Automatically fill a job application form.

```bash
# 1. Analyze form to find field names
deno run --allow-read scripts/analyze-template.ts application.pdf --pretty

# 2. Create form-data.json with applicant info
# 3. Generate filled form
deno run --allow-read --allow-write scripts/generate-from-template.ts \
  application.pdf form-data.json john-smith-application.pdf
```

### Example 2: Add Approval Stamp

**Scenario**: Add an "APPROVED" stamp to a document.

**stamp-spec.json**:
```json
{
  "overlays": [
    {
      "type": "rectangle",
      "page": 1,
      "x": 400,
      "y": 700,
      "width": 150,
      "height": 50,
      "color": { "r": 0.9, "g": 1, "b": 0.9 }
    },
    {
      "type": "text",
      "page": 1,
      "x": 410,
      "y": 720,
      "text": "APPROVED",
      "fontSize": 20,
      "font": "HelveticaBold",
      "color": { "r": 0, "g": 0.5, "b": 0 }
    },
    {
      "type": "text",
      "page": 1,
      "x": 410,
      "y": 705,
      "text": "2024-12-15",
      "fontSize": 10
    }
  ]
}
```

### Example 3: Create Report with Table

**Scenario**: Generate a simple report with a data table.

**report-spec.json**:
```json
{
  "title": "Sales Report",
  "pages": [{
    "size": "Letter",
    "elements": [
      {
        "type": "text",
        "x": 72,
        "y": 720,
        "text": "Monthly Sales Report",
        "fontSize": 24,
        "font": "HelveticaBold"
      },
      {
        "type": "table",
        "x": 72,
        "y": 680,
        "rows": [
          ["Product", "Units", "Revenue"],
          ["Widget A", "150", "$15,000"],
          ["Widget B", "75", "$11,250"],
          ["Widget C", "200", "$8,000"]
        ],
        "columnWidths": [150, 80, 100],
        "rowHeight": 25,
        "headerBackground": { "r": 0.9, "g": 0.9, "b": 0.9 }
      }
    ]
  }]
}
```

## Script Reference

| Script | Purpose | Permissions |
|--------|---------|-------------|
| `analyze-template.ts` | Extract text, metadata, form fields from PDF | `--allow-read` |
| `generate-from-template.ts` | Fill forms, add overlays, merge PDFs | `--allow-read --allow-write` |
| `generate-scratch.ts` | Create PDF from JSON specification | `--allow-read --allow-write` |

## Element Types (Scratch Mode)

| Type | Description | Key Options |
|------|-------------|-------------|
| `text` | Text content | `x`, `y`, `text`, `fontSize`, `font`, `color`, `rotate` |
| `image` | PNG/JPEG images | `x`, `y`, `path`, `width`, `height`, `opacity` |
| `rectangle` | Filled/outlined rectangles | `x`, `y`, `width`, `height`, `color`, `borderColor` |
| `line` | Straight lines | `startX`, `startY`, `endX`, `endY`, `thickness` |
| `circle` | Filled/outlined circles | `x`, `y`, `radius`, `color`, `borderColor` |
| `table` | Basic table layout | `x`, `y`, `rows`, `columnWidths`, `rowHeight` |

## Available Fonts

- `Helvetica` (default)
- `HelveticaBold`
- `HelveticaOblique`
- `TimesRoman`
- `TimesBold`
- `Courier`
- `CourierBold`

## Page Sizes

- `A4` (595.28 x 841.89 points)
- `Letter` (612 x 792 points)
- `Legal` (612 x 1008 points)
- Custom: `[width, height]` in points

## Common Issues and Solutions

### Issue: Form fields not found

**Symptoms**: Error saying field name doesn't exist.

**Solution**:
1. Run `analyze-template.ts` to get exact field names
2. Field names are case-sensitive
3. Some PDFs have non-fillable text that looks like form fields

### Issue: Text positioning is off

**Symptoms**: Text appears in wrong location.

**Solution**:
- PDF coordinates start from bottom-left (0,0)
- Y increases upward, X increases rightward
- Use `analyze-template.ts` to see page dimensions

### Issue: Images not appearing

**Symptoms**: Image overlay not visible.

**Solution**:
1. Check file path is relative to spec.json location
2. Verify image is PNG or JPEG format
3. Ensure coordinates are within page bounds

### Issue: Merged PDF has wrong page order

**Symptoms**: Pages appear in unexpected order.

**Solution**:
- `prependPdfs` add pages before template
- `appendPdfs` add pages after template
- Use `pages` array to select specific pages: `[1, 3, 5]`

## Limitations

- **No built-in table layout**: Tables require manual column width specification
- **Standard fonts only**: Custom font embedding not supported in scratch mode
- **No flowing text**: Text doesn't automatically wrap to next page
- **Limited form field creation**: Can fill existing forms, not create new fields
- **No encryption**: Cannot create password-protected PDFs
- **Basic graphics**: No gradients, patterns, or complex paths
- **Text extraction**: May not work perfectly on all PDFs (depends on PDF structure)

## Related Skills

- **pptx-generator**: For creating PowerPoint presentations
- **docx-generator**: For creating Word documents
- **xlsx-generator**: For creating Excel spreadsheets

Overview

This skill generates and manipulates PDF files programmatically for a wide range of document workflows. It supports template-based form filling and overlays, as well as creating PDFs from structured JSON specifications. Use it to fill forms, add watermarks/stamps, merge documents, extract text/metadata, or build reports from scratch.

How this skill works

In template mode the skill analyzes an existing PDF to extract form fields and page metrics, then fills those fields and applies overlays (text, images, shapes) or merges additional PDFs. In scratch mode it consumes a JSON specification describing pages and elements (text, images, tables, shapes) and renders a new PDF. CLI scripts handle analysis, template generation, and scratch generation with read/write permissions.

When to use it

  • Automatically fill and flatten fillable PDF forms for applications or contracts
  • Add watermarks, approval stamps, headers/footers, or logos to existing PDFs
  • Merge cover pages, appendices, or selective pages into a single PDF
  • Extract text, metadata, and form field inventories from PDFs for processing
  • Generate structured reports, invoices, or simple tables from data via JSON specs

Best practices

  • Run the template analysis first to obtain exact field names and page dimensions
  • Use bottom-left coordinate system: origin (0,0) is bottom-left and Y grows upward
  • Keep image paths relative to the spec file and use PNG/JPEG formats
  • Specify explicit column widths for tables and avoid expecting automatic text flow
  • Flatten forms when you need a non-editable final PDF for distribution

Example use cases

  • Fill a job application PDF by analyzing fields, supplying applicant data, and generating a flattened output
  • Apply a red CONFIDENTIAL watermark and company logo overlay across specific pages
  • Prepend a branded cover page and append appendices to produce a single deliverable
  • Generate a quarterly report from a JSON spec with headings, lines, and a simple table
  • Extract form field inventory and text to build a validation step in an ingestion pipeline

FAQ

Can this skill create password-protected PDFs?

No. The skill cannot create encrypted or password-protected PDFs.

Does scratch mode support flowing or paginated text?

No. Text does not automatically flow across lines or pages; specify maxWidth and handle pagination in the spec.