CSV / Excel Export
Data export is the feature every business app eventually needs and nobody enjoys building. In Grit it's automatic: every resource you scaffold withgrit generate resource ships a streaming CSV and chunked XLSX export at /export — built for constant memory.
Reference docs: DataTable & Export →
Generated for free
Every resource from grit generate gets /export with no extra code.
CSV & XLSX
Pick the format with ?format=csv or ?format=xlsx.
Constant memory
Streaming CSV and chunked XLSX export millions of rows without blowing up RAM.
Filters carry through
The same query params that filter the list filter the export.
The export endpoint
When you generate a resource, Grit injects an export route alongside the usual CRUD handlers. You choose the format with a query parameter.
# CSV (default) — streamed row-by-row
GET /api/products/export?format=csv
# Excel workbook — written in chunks
GET /api/products/export?format=xlsx
# Filters from the list endpoint apply to the export too
GET /api/products/export?format=xlsx&status=active&sort=created_atWhy streaming matters
The naive approach — load every row into a slice, build the whole file in memory, then send it — falls over on large tables. A 1-million-row export can eat gigabytes of RAM and time out. Grit avoids this by writing as it reads.
| Format | Best for | Memory profile |
|---|---|---|
| CSV | Huge dumps, piping into other tools | Flat (true stream) |
| XLSX | Hand-off to non-technical users | Bounded (chunked) |
From the admin panel
The admin DataTable includes an export menu wired to these endpoints, so end users can download the current view as CSV or Excel with one click — no API knowledge needed.
Practice
Challenge: Generate and export
Run grit generate resource Product --fields "name:string,price:float,stock:int", seed a few rows, then hit /api/products/export?format=csv. Open the file — do the columns match your fields?
Challenge: Switch to Excel
Request the same data with format=xlsx. Does it open cleanly in Excel, Numbers, or Google Sheets? What's different from the CSV?
Challenge: Carry a filter through
Add a filter query param (e.g. ?status=active) to the export URL. Does the file contain only the filtered rows? Why is reusing the list query the right design?
Challenge: Reason about scale
You need to export 5 million rows. Which format do you choose and why? What would you change so the user isn't left waiting on an open HTTP connection?
Enjoying the course?
Help us grow, star us on GitHub, subscribe on YouTube, and follow on LinkedIn.
