# Generating Pdfs

> Creates PDF documents from scratch (reports, invoices, one-pagers) or from HTML content. Use whenever the deliverable needs to be a PDF, or when a polished printable document is expected instead of markdown.

- Skill: `aaravriyer193/generating-pdfs` (Agent Skill)
- Install (CLI): `npx skillmds@latest add aaravriyer193/generating-pdfs`
- Raw SKILL.md: https://api.skillmd.com/api/skills/aaravriyer193/generating-pdfs/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: aaravriyer193 (https://skillmd.com/u/aaravriyer193)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/aaravriyer193/generating-pdfs

---


# Generating PDFs

Never hand-write .pdf with write_file — build it with a real library.

**From scratch (structured document)** — use reportlab:
```bash
pip install reportlab
```
```python
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet

styles = getSampleStyleSheet()
doc = SimpleDocTemplate("/home/user/report.pdf", pagesize=letter)
story = [Paragraph("Title", styles["Title"]), Spacer(1, 12), Paragraph("Body text.", styles["Normal"])]
doc.build(story)
```

**From HTML/CSS (richer layout)** — use weasyprint:
```bash
pip install weasyprint
```
```python
from weasyprint import HTML
HTML(string="<h1>Title</h1><p>Body.</p>").write_pdf("/home/user/report.pdf")
```
weasyprint gives real CSS layout (columns, fonts, page breaks via `page-break-after`), which is easier for anything visually complex than assembling reportlab flowables by hand — prefer it for anything more than a simple text report.

Present the .pdf with present_file, never the generating script.

