demo D118
CSV export in React
Delimiters, quoting, which rows, and per-cell processing
export.csv()
This grid writes its current data out as CSV, with control over delimiters, quoting, which rows are included and per-cell processing. It gets a report into any spreadsheet or downstream system in a format everything reads, straight from the browser.
This is the React version. The grid mounts through the createLatticeGrid adapter, which takes its configuration as ordinary props and hands back the live grid through a ref. The grid below is the same one every other tab runs.
The configuration
<link rel="stylesheet" href="https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.min.css">
<div id="grid"></div>
<script type="module">
import React from 'https://esm.sh/react@18';
import { createRoot } from 'https://esm.sh/react-dom@18/client';
import { createGrid } from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.esm.min.js';
import createLatticeGrid from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/modules/react.esm.min.js';
const LatticeGrid = createLatticeGrid({ React, createGrid });
const columns = [
{ field: 'ref', title: 'Invoice', layout: { pin: 'start', width: 140 } },
{ field: 'supplier', title: 'Supplier', layout: { flex: 1, min: 200 }, filter: { type: 'set' } },
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ field: 'category', title: 'Category', filter: { type: 'set' } },
{ field: 'quantity', title: 'Qty', type: 'number', layout: { width: 110 } },
{ field: 'amount', title: 'Amount', type: 'number', layout: { width: 150 },
format: { style: 'currency', currency: 'GBP', decimals: 2 }, total: 'sum', filter: { type: 'number' } },
{ field: 'note', title: 'Note', layout: { width: 280 } },
// On screen and out of the file. What a grid exports is a separate decision
// from what it shows, and this is the column that proves it.
{ field: 'internal', title: 'Internal', layout: { width: 200 }, export: { csv: false } },
];
// The rail's CSV button takes the defaults; the named ones set the options.
const toolPanel = {
side: 'left',
panels: ['columns', 'filters', 'quick'],
exportName: 'supplier-charges',
actions: [
'undo', 'redo', 'restore', 'maximise', '-',
'export',
{
name: 'csv-semicolon',
title: 'Download CSV, semicolon-delimited',
icon: 'download',
run: ({ grid }) => grid.export.csv({ download: true, fileName: 'supplier-charges-semicolon', delimiter: ';' }),
},
{
// The same call with rows: 'selected'. Nothing selected would write a
// file of headers alone, so the guard sits here rather than in the option.
name: 'csv-selected',
title: 'Download CSV of the selected rows only',
icon: 'check',
run: ({ grid, keys }) => {
if (!keys.length) return;
grid.export.csv({ download: true, fileName: 'supplier-charges-selected', rows: 'selected' });
},
},
],
};
const rows = [/* supplier charge records, one per invoice line */];
function App() {
const gridRef = React.useRef(null);
// The same writer, reached imperatively through the ref, saved from your own
// button or effect.
const download = () => gridRef.current.grid.export.csv({ download: true, fileName: 'supplier-charges' });
return (
<>
<button onClick={download}>Download CSV</button>
<LatticeGrid
ref={gridRef}
rowKey="id"
selection="multiple"
toolPanel={toolPanel}
columns={columns}
rows={rows}
style={{ height: '540px', marginTop: '8px' }}
/>
</>
);
}
createRoot(document.getElementById('grid')).render(<App />);
</script>
Exporting grid data to CSV with control over delimiters, quoting and rows
CSV export writes the grid’s current data out as plain text, one row per line, in a format any spreadsheet, script or downstream system can read without a library of its own. A developer reaches for it when a report needs to leave the browser as a file: a filtered result set for a colleague, a scheduled download, or an input to a tool that only accepts flat text. Lattice Grid exposes this through export.csv(), which takes the delimiter, the quoting rule and the row selection as options, so a comma-separated file for one audience and a tab-separated file for another come from the same call with different arguments. Row selection chooses between the full dataset, the current filtered view, or a specific selection, which matters because a filtered grid and its unfiltered source are not the same export unless asked to be. A per-cell processing hook runs before each value is written, letting an application reformat a date or apply the same redaction rule it uses on screen so an export never leaks a value the grid itself would mask. Because the write walks the underlying row store rather than the rendered, virtualised viewport, exporting a million rows costs the same per row as exporting ten, without first requiring every row to have been scrolled into view.
How do I export only the filtered or selected rows from a JavaScript data grid to CSV?
Pass the row selection option to export.csv(): it accepts the full dataset, the rows currently matching the grid’s filters, or an explicit selection. Combined with the per-cell processing hook, this produces a CSV that reflects exactly what a user sees on screen, including any redaction applied to individual cells, rather than the grid’s raw underlying data.