CSV Export
Export Prisma data as downloadable CSV files. No dependencies — pure TypeScript utilities.
Export any data to CSV with a type-safe buildCSV utility and downloadCSV browser helper. No external dependencies required.
What's Included
| File | Purpose |
|---|---|
lib/features/export.ts | buildCSV(headers, rows) and downloadCSV(filename, csv) utilities |
Usage
Client-Side Export
"use client"
import { buildCSV, downloadCSV } from "@/lib/features/export"
import { Button } from "@/components/ui/button"
import { Download } from "lucide-react"
export function ExportUsersButton({ users }: { users: Array<{ name: string; email: string; plan: string }> }) {
const handleExport = () => {
const headers = ["Name", "Email", "Plan"]
const rows = users.map((u) => [u.name, u.email, u.plan])
const csv = buildCSV(headers, rows)
downloadCSV("users-export.csv", csv)
}
return (
<Button onClick={handleExport} variant="outline" size="sm">
<Download className="mr-2 h-4 w-4" />
Export CSV
</Button>
)
}Server-Side API Route
Create app/api/export/users/route.ts for admin CSV exports:
import { NextResponse } from "next/server"
import { getAdminSession } from "@/lib/auth-utils"
import { db } from "@/lib/db"
import { buildCSV } from "@/lib/features/export"
export async function GET() {
await getAdminSession()
const users = await db.user.findMany({
select: { name: true, email: true, role: true, plan: true, createdAt: true },
orderBy: { createdAt: "desc" },
})
const headers = ["Name", "Email", "Role", "Plan", "Joined"]
const rows = users.map((u) => [
u.name ?? "",
u.email ?? "",
u.role,
u.plan ?? "FREE",
u.createdAt.toISOString().split("T")[0],
])
return new NextResponse(buildCSV(headers, rows), {
headers: {
"Content-Type": "text/csv; charset=utf-8",
"Content-Disposition": `attachment; filename="users-${new Date().toISOString().split("T")[0]}.csv"`,
},
})
}API Reference
buildCSV(headers, rows)
buildCSV(headers: string[], rows: string[][]): string- Wraps fields with commas/quotes/newlines in double-quotes
- Escapes embedded double-quotes by doubling them
- Joins rows with
\r\n(RFC 4180 compliant) - Adds a UTF-8 BOM for Excel compatibility
downloadCSV(filename, csv)
downloadCSV(filename: string, csv: string): voidCreates a text/csv Blob, generates a temporary Object URL, and programmatically clicks a hidden <a> tag to trigger the browser download. Cleans up the URL after download.
Environment Variables
None required.
Verification
- Import
buildCSVanddownloadCSVin a client component - Pass sample data and trigger the export
- Open the downloaded file in Excel or Google Sheets
- Confirm: headers on row 1, fields with commas properly quoted, UTF-8 encoding correct