---
title: "Reports"
space: "Frappe Framework"
url: "https://www.prilk.com/docs/frappe-framework/reports"
updated: "2026-05-14"
---

## Reports

Frappe has three report types, in order of complexity.

### 1. Report Builder
Click **Reports → Report Builder**, pick a DocType, choose fields and filters, save as a named report. Anyone with access can run it and export to CSV/XLSX.

Strengths: no code, fast to iterate, end-user friendly.
Limits: single DocType, no joins, no SQL.

### 2. Query Report
For multi-DocType joins or computed columns, developers create Query Reports — a Python function returning columns and rows, plus a JSON config. Defined in code, shipped with apps.

Example structure:
```
my_app/my_app/report/sales_summary/
├── sales_summary.json
├── sales_summary.py     # def execute(filters): return columns, data
└── sales_summary.js     # Filter form
```

End users see them in the same Reports list and run them like Report Builder reports.

### 3. Script Report
Similar to Query Report but with more flexibility — you can run arbitrary Python, call APIs, do anything before returning data. Use sparingly; SQL via Query Report is usually enough.

### Dashboards
Reports can be added to a **Dashboard** with charts (number cards, bar/line, pie). Dashboards live on Workspaces and can be the landing page for a role.

### Scheduling
Any report can email itself to users on a schedule: **Report → Set "Send to Users" → frequency**. Saves you logging in every Monday for the weekly sales summary.

### Exporting
All reports export to CSV and XLSX from the toolbar. For programmatic access, hit the API or use a Query Report's underlying `execute()` function via `frappe.get_attr()`.
