Export (CSV / JSON)

useTableExport is a headless hook that turns your columns and rows into CSV or JSON. It can also trigger a browser download or copy to the clipboard. It does not touch your DataTable; you pass it the same data the table is rendering — or a filtered / sorted slice if you only want to export the "current view".

New in 8.1.0useTableExport ships as part of the library's headless surface alongside useTableState, useTableData, and friends.

Download and copy

Export the table as CSV or JSON, or copy to clipboard.

Name
Department
Salary
Aria Chen
Engineering
$155,000
Marcus Webb
Product
$132,000
Priya Kapoor
Design
$118,000
Jordan Ellis
Analytics
$143,000
Sam Rivera
Engineering
$128,000
Taylor Brooks
Sales
$97,000

Basic usage

import DataTable, { useTableExport, type TableColumn } from 'react-data-table-component';

type Employee = { id: number; name: string; salary: number };

const columns: TableColumn<Employee>[] = [
  { id: 'id',     name: 'ID',     selector: r => r.id },
  { id: 'name',   name: 'Name',   selector: r => r.name },
  { id: 'salary', name: 'Salary', selector: r => r.salary,
    format: r => `$${r.salary.toLocaleString()}` },
];

function EmployeesTable({ data }: { data: Employee[] }) {
  const { download, copy } = useTableExport({ columns, rows: data });

  return (
    <>
      <div className="flex gap-2">
        <button onClick={() => download('employees.csv')}>Download CSV</button>
        <button onClick={() => download('employees.json', 'json')}>Download JSON</button>
        <button onClick={() => copy('csv')}>Copy CSV</button>
      </div>
      <DataTable columns={columns} data={data} />
    </>
  );
}

What gets exported

  • Columns: all columns are included except those with omit: true. Pass columnOrder to restrict and reorder.
  • Rows: exactly what you pass in. To export the current filtered/sorted view, see the recipe below.
  • Values: by default the raw selector output is stringified. Pass valueSource: 'format' to prefer column.format instead.
  • Headers: derived from column.name when it's a string or number; otherwise the column id. Override per-column with headerOverrides.

Exporting the current view

DataTable owns sort and pagination state internally, but you can lift them out by using the headless hooks directly — or just keep a copy of the filtered/sorted rows via the callbacks. The simplest pattern for "what the user is looking at right now" is to drive DataTable from the same hooks that feed useTableExport:

import DataTable, {
  useTableState,
  useTableData,
  useColumnFilter,
  useTableExport,
} from 'react-data-table-component';

function App() {
  // 1. Filters
  const { filterValues, handleFilterChange, filteredData } = useColumnFilter(columns);

  // 2. Sort + pagination state
  const { tableState, handleSort, /* ... */ } = useTableState({ /* ... */ });

  // 3. Apply sort + pagination
  const { sortedData, tableRows } = useTableData({
    data: filteredData(rawData),
    columns,
    selectedColumn: tableState.selectedColumn,
    sortDirection: tableState.sortDirection,
    currentPage: tableState.currentPage,
    rowsPerPage: tableState.rowsPerPage,
    pagination: true,
  });

  // 4. Export the filtered + sorted full result (not just the current page).
  //    Swap `sortedData` for `tableRows` to export just the current page.
  const { download } = useTableExport({ columns, rows: sortedData });

  return (
    <>
      <button onClick={() => download('view.csv')}>Export filtered view</button>
      <DataTable columns={columns} data={rawData} pagination />
    </>
  );
}

For server-side data, just pass whatever rows the server returned for your current filters — useTableExport doesn't care where the rows came from.

Customizing column output

Reorder and restrict columns

useTableExport({
  columns,
  rows: data,
  columnOrder: ['name', 'salary', 'id'],  // export these three, in this order
});

Override header labels

Useful when column.name is a React node (e.g. an icon + text), or when the export needs a different label than the UI shows:

useTableExport({
  columns,
  rows: data,
  headerOverrides: {
    name: 'Full Name',
    salary: 'Annual Salary (USD)',
  },
});

Export formatted values

By default, exports use raw selector values so a CSV "salary" column contains 80000 rather than $80,000. To export what the user sees, opt into valueSource: 'format':

useTableExport({ columns, rows: data, valueSource: 'format' });

Clipboard support

copy() uses the navigator.clipboard API and returns a Promise that resolves once the write completes. It throws if the API is not available (older browsers, insecure contexts).

async function handleCopy() {
  try {
    await copy('csv'); // or 'json'
    toast.success('Copied to clipboard');
  } catch (err) {
    toast.error('Clipboard not available');
  }
}

SSR safety

Both download and copy guard against document / navigator being undefined, so calling them during server rendering is a no-op rather than a crash. The hook itself does no browser-only work at render time.

CSV escaping

Values containing commas, quotes, or newlines are wrapped in double quotes and any interior quotes are doubled — the standard RFC 4180 rule. Booleans and numbers are coerced with String(). null and undefined become empty cells. Anything more complex (objects, React nodes) is run through JSON.stringify as a safety net.

API

OptionTypeDefaultDescription
columnsTableColumn<T>[]requiredSame columns array you pass to DataTable. Columns with omit: true are skipped.
rowsT[]requiredRows to export.
valueSource'selector' | 'format''selector'Use raw selector values or run column.format first.
headerOverridesRecord<string|number, string>Replace header label per column id.
columnOrder(string|number)[]Restrict and reorder columns by id.

Returns

PropertyTypeDescription
toCSV() => stringBuild a CSV string (no download).
toJSON() => stringBuild a pretty-printed JSON array string.
download(filename, format?) => voidTrigger a browser download. format defaults to 'csv'.
copy(format?) => Promise<void>Copy to clipboard. Rejects when the clipboard API is unavailable.