# useDataExport URL: /docs/web/hooks/use-data-export Project an in-memory array of rows through a column definition and trigger a browser download as CSV, JSON, Markdown, or XLSX. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/hooks-use-data-export ``` **Dependencies:** - [xlsx](https://www.npmjs.com/package/xlsx) `xlsx` is loaded with a dynamic `import('xlsx')` and is only fetched when `format === 'xlsx'`. CSV, JSON, and Markdown exports work without it. ## Overview `useDataExport` is a generic, framework-agnostic export hook for any in-memory array. You describe how each column should be projected, and the hook handles serialization, escaping, blob construction, and the browser download. - **Four formats** — `csv`, `json`, `markdown`, and `xlsx`. - **Column projection** — pick fields, rename headers, derive values via `accessor`, format cells via `formatter`. Order is preserved in the output. - **Safe by default** — CSV cells are RFC 4180 escaped, Markdown cells escape `|`, `\`, and newlines, and `Date` values are written as ISO strings. - **Excel-friendly** — CSV output is prefixed with a UTF-8 BOM so Excel auto-detects encoding (toggle with `csvBom`). - **SSR-safe** — `exportData()` is a no-op on the server (`typeof window === 'undefined'`) and returns `null` instead of throwing. - **Lazy xlsx** — the `xlsx` package is only loaded when the user actually picks the XLSX format. ## Usage ### Basic example ```tsx 'use client'; import { Button } from '@docyrus/ui/primitives/ui/button'; import { useDataExport } from '@docyrus/ui/library/hooks/use-data-export'; type Contact = { id: string; name: string; email: string; createdAt: Date; }; const rows: Array ); } ``` ### Custom accessor + formatter ```tsx const { exportData } = useDataExport ))} ); ``` ### Awaiting the resolved file metadata ```tsx async function downloadAndToast() { const result = await exportData(rows, 'xlsx'); if (!result) return; // server-side, no-op toast.success(`Saved ${result.fileName}`); } ``` ## API Reference ### Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `options` | `UseDataExportOptions` | — | Hook configuration (see below). **Required.** | ### `UseDataExportOptions` | Option | Type | Default | Description | |--------|------|---------|-------------| | `columns` | `Array>` | — | Column projection. Order is preserved in the output. **Required.** | | `fileName` | `string` | `'export'` | File name without extension. The format-specific extension is appended automatically. | | `sheetName` | `string` | `'Sheet1'` | Sheet name used for `xlsx` exports. | | `csvBom` | `boolean` | `true` | Prepend a UTF-8 BOM to CSV output so Excel auto-detects encoding. | ### `DataExportColumn` | Property | Type | Default | Description | |----------|------|---------|-------------| | `id` | `string` | — | Stable column id. Used as the JSON object key when `format === 'json'` and as the lookup key when `accessor` is omitted. **Required.** | | `header` | `string` | — | Header label rendered in CSV / Markdown / XLSX output. **Required.** | | `accessor` | `(row: TData) => unknown` | `row => row[id]` | Pull the raw cell value for this column from a row. | | `formatter` | `(value: unknown, row: TData) => string` | default stringifier | Coerce the raw value into the string written to the file. The default renders primitives verbatim, ISO-formats `Date`s, and `JSON.stringify`s objects/arrays. | ### Return Value — `UseDataExportResult` | Property | Type | Description | |----------|------|-------------| | `exportData` | `(rows: Array, format: DataExportFormat) => Promise` | Project `rows` through `columns` and trigger a browser download in the requested `format`. Returns `null` on the server. | | `isExporting` | `boolean` | `true` while a download is in flight (mainly relevant for the async `xlsx` path). Use it to disable the trigger button. | ### `DataExportResult` | Property | Type | Description | |----------|------|-------------| | `mimeType` | `string` | MIME type written to the `Blob`. | | `extension` | `string` | File extension including the leading dot (e.g. `'.csv'`). | | `fileName` | `string` | Final file name (``). | ### Type Exports | Type | Description | |------|-------------| | `DataExportFormat` | `'csv' \| 'json' \| 'markdown' \| 'xlsx'` | | `DataExportColumn` | Single-column definition (`id`, `header`, `accessor`, `formatter`). | | `UseDataExportOptions` | Hook input (`columns`, `fileName`, `sheetName`, `csvBom`). | | `UseDataExportResult` | Hook return value (`exportData`, `isExporting`). | | `DataExportResult` | File metadata returned by `exportData()`. | ## Format Reference | Format | Extension | MIME Type | Notes | |--------|-----------|-----------|-------| | `csv` | `.csv` | `text/csv;charset=utf-8` | RFC 4180 escaping. UTF-8 BOM prepended unless `csvBom: false`. CRLF line endings. | | `json` | `.json` | `application/json;charset=utf-8` | Pretty-printed (`JSON.stringify(rows, null, 2)`). Object keys come from each column's `id`. | | `markdown` | `.md` | `text/markdown;charset=utf-8` | GitHub-flavored table. `\|`, `\\`, and newlines are escaped; multi-line cells use `
`. | | `xlsx` | `.xlsx` | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` | Lazy-loads the `xlsx` package. Numbers, booleans, and `Date` values are written as their native Excel types. | ## Notes - The hook keeps no internal cache — pass the rows you want to export each time you call `exportData()`. This is what lets the same hook handle a filtered grid, a selection-only export, and a "download all" button. - Calling `exportData()` from a server component or during SSR is safe: the function bails out before touching `document` and resolves to `null`. - The download is triggered by injecting a temporary `` element. No popup, no new tab, no user gesture beyond the original click.