Skip to content

Commit 886bae5

Browse files
prakhargupta1michelengelenmapache-salvaje
authored
[DataGrid] Add a recipe to demo exporting entire data from the data grid (#17368)
Signed-off-by: Prakhar Gupta <[email protected]> Co-authored-by: Michel Engelen <[email protected]> Co-authored-by: mapache-salvaje <[email protected]>
1 parent 95e5c79 commit 886bae5

File tree

3 files changed

+272
-0
lines changed

3 files changed

+272
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import * as React from 'react';
2+
import { DataGridPremium, useGridApiRef } from '@mui/x-data-grid-premium';
3+
import Button from '@mui/material/Button';
4+
import Box from '@mui/material/Box';
5+
import DownloadIcon from '@mui/icons-material/Download';
6+
// Define the data structure
7+
8+
// Mock API function to simulate server-side data fetching
9+
const fetchUsers = async (page, pageSize) => {
10+
// Simulate API delay
11+
await new Promise((resolve) => {
12+
setTimeout(resolve, 500);
13+
});
14+
15+
// Generate mock data
16+
const total = 100;
17+
const start = page * pageSize;
18+
const end = Math.min(start + pageSize, total);
19+
20+
const rows = Array.from({ length: end - start }, (_, index) => ({
21+
id: start + index + 1,
22+
name: `User ${start + index + 1}`,
23+
email: `user${start + index + 1}@example.com`,
24+
role: index % 2 === 0 ? 'Admin' : 'User',
25+
}));
26+
27+
return { rows, rowCount: total };
28+
};
29+
30+
// Mock API function to fetch all data for export
31+
const fetchAllUsers = async () => {
32+
// Simulate API delay
33+
await new Promise((resolve) => {
34+
setTimeout(resolve, 1000);
35+
});
36+
37+
// Generate all mock data
38+
return Array.from({ length: 100 }, (_, index) => ({
39+
id: index + 1,
40+
name: `User ${index + 1}`,
41+
email: `user${index + 1}@example.com`,
42+
role: index % 2 === 0 ? 'Admin' : 'User',
43+
}));
44+
};
45+
46+
function CustomExport() {
47+
const [loading, setLoading] = React.useState(false);
48+
const [rows, setRows] = React.useState([]);
49+
const [rowCount, setRowCount] = React.useState(0);
50+
const [paginationModel, setPaginationModel] = React.useState({
51+
page: 0,
52+
pageSize: 10,
53+
});
54+
55+
const apiRef = useGridApiRef();
56+
57+
const columns = [
58+
{ field: 'id', headerName: 'ID', width: 90 },
59+
{ field: 'name', headerName: 'Name', width: 200 },
60+
{ field: 'email', headerName: 'Email', width: 250 },
61+
{ field: 'role', headerName: 'Role', width: 130 },
62+
];
63+
64+
const handleExport = async () => {
65+
setLoading(true);
66+
try {
67+
const allData = await fetchAllUsers();
68+
apiRef.current?.updateRows(allData);
69+
await apiRef.current?.exportDataAsExcel();
70+
} catch (error) {
71+
console.error('Error exporting data:', error);
72+
}
73+
setLoading(false);
74+
};
75+
76+
React.useEffect(() => {
77+
const loadData = async () => {
78+
setLoading(true);
79+
try {
80+
const response = await fetchUsers(
81+
paginationModel.page,
82+
paginationModel.pageSize,
83+
);
84+
setRows(response.rows);
85+
setRowCount(response.rowCount);
86+
} catch (error) {
87+
console.error('Error loading data:', error);
88+
} finally {
89+
setLoading(false);
90+
}
91+
};
92+
93+
loadData();
94+
}, [paginationModel]);
95+
96+
return (
97+
<div style={{ height: 520, width: '100%' }}>
98+
<Box gap={1} mb={1} flexWrap="wrap">
99+
<Button
100+
variant="contained"
101+
startIcon={<DownloadIcon />}
102+
onClick={handleExport}
103+
disabled={loading}
104+
>
105+
Export to Excel
106+
</Button>
107+
</Box>
108+
<Box style={{ height: 480, width: '100%' }}>
109+
<DataGridPremium
110+
apiRef={apiRef}
111+
rows={rows}
112+
columns={columns}
113+
rowCount={rowCount}
114+
paginationModel={paginationModel}
115+
onPaginationModelChange={setPaginationModel}
116+
pageSizeOptions={[10, 25, 50]}
117+
loading={loading}
118+
paginationMode="server"
119+
pagination
120+
/>
121+
</Box>
122+
</div>
123+
);
124+
}
125+
126+
export default CustomExport;
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import * as React from 'react';
2+
import {
3+
DataGridPremium,
4+
GridPaginationModel,
5+
useGridApiRef,
6+
} from '@mui/x-data-grid-premium';
7+
import Button from '@mui/material/Button';
8+
import Box from '@mui/material/Box';
9+
import DownloadIcon from '@mui/icons-material/Download';
10+
// Define the data structure
11+
interface User {
12+
id: number;
13+
name: string;
14+
email: string;
15+
role: string;
16+
}
17+
18+
// Mock API function to simulate server-side data fetching
19+
const fetchUsers = async (
20+
page: number,
21+
pageSize: number,
22+
): Promise<{ rows: User[]; rowCount: number }> => {
23+
// Simulate API delay
24+
await new Promise((resolve) => {
25+
setTimeout(resolve, 500);
26+
});
27+
28+
// Generate mock data
29+
const total = 100;
30+
const start = page * pageSize;
31+
const end = Math.min(start + pageSize, total);
32+
33+
const rows = Array.from({ length: end - start }, (_, index) => ({
34+
id: start + index + 1,
35+
name: `User ${start + index + 1}`,
36+
email: `user${start + index + 1}@example.com`,
37+
role: index % 2 === 0 ? 'Admin' : 'User',
38+
}));
39+
40+
return { rows, rowCount: total };
41+
};
42+
43+
// Mock API function to fetch all data for export
44+
const fetchAllUsers = async (): Promise<User[]> => {
45+
// Simulate API delay
46+
await new Promise((resolve) => {
47+
setTimeout(resolve, 1000);
48+
});
49+
50+
// Generate all mock data
51+
return Array.from({ length: 100 }, (_, index) => ({
52+
id: index + 1,
53+
name: `User ${index + 1}`,
54+
email: `user${index + 1}@example.com`,
55+
role: index % 2 === 0 ? 'Admin' : 'User',
56+
}));
57+
};
58+
59+
function CustomExport() {
60+
const [loading, setLoading] = React.useState(false);
61+
const [rows, setRows] = React.useState<User[]>([]);
62+
const [rowCount, setRowCount] = React.useState(0);
63+
const [paginationModel, setPaginationModel] = React.useState<GridPaginationModel>({
64+
page: 0,
65+
pageSize: 10,
66+
});
67+
68+
const apiRef = useGridApiRef();
69+
70+
const columns = [
71+
{ field: 'id', headerName: 'ID', width: 90 },
72+
{ field: 'name', headerName: 'Name', width: 200 },
73+
{ field: 'email', headerName: 'Email', width: 250 },
74+
{ field: 'role', headerName: 'Role', width: 130 },
75+
];
76+
77+
const handleExport = async () => {
78+
setLoading(true);
79+
try {
80+
const allData = await fetchAllUsers();
81+
apiRef.current?.updateRows(allData);
82+
await apiRef.current?.exportDataAsExcel();
83+
} catch (error) {
84+
console.error('Error exporting data:', error);
85+
}
86+
setLoading(false);
87+
};
88+
89+
React.useEffect(() => {
90+
const loadData = async () => {
91+
setLoading(true);
92+
try {
93+
const response = await fetchUsers(
94+
paginationModel.page,
95+
paginationModel.pageSize,
96+
);
97+
setRows(response.rows);
98+
setRowCount(response.rowCount);
99+
} catch (error) {
100+
console.error('Error loading data:', error);
101+
} finally {
102+
setLoading(false);
103+
}
104+
};
105+
106+
loadData();
107+
}, [paginationModel]);
108+
109+
return (
110+
<div style={{ height: 520, width: '100%' }}>
111+
<Box gap={1} mb={1} flexWrap="wrap">
112+
<Button
113+
variant="contained"
114+
startIcon={<DownloadIcon />}
115+
onClick={handleExport}
116+
disabled={loading}
117+
>
118+
Export to Excel
119+
</Button>
120+
</Box>
121+
<Box style={{ height: 480, width: '100%' }}>
122+
<DataGridPremium
123+
apiRef={apiRef}
124+
rows={rows}
125+
columns={columns}
126+
rowCount={rowCount}
127+
paginationModel={paginationModel}
128+
onPaginationModelChange={setPaginationModel}
129+
pageSizeOptions={[10, 25, 50]}
130+
loading={loading}
131+
paginationMode="server"
132+
pagination
133+
/>
134+
</Box>
135+
</div>
136+
);
137+
}
138+
139+
export default CustomExport;

docs/data/data-grid/components/export/export.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ The demo below shows how to display export options within a menu on the toolbar.
5151

5252
{{"demo": "GridExportMenu.js", "bg": "inline", "defaultCodeOpen": false}}
5353

54+
### Customizing Excel export parameters [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan')
55+
56+
The demo below shows how to implement a custom export button that downloads the full dataset (beyond the current page) to an Excel spreadsheet, while preserving any sorting, filtering, or grouping parameters that the user has applied to the Grid.
57+
It uses the built-in [`exportDataAsExcel()`](/x/react-data-grid/export/#excel) method.
58+
59+
{{"demo": "CustomExport.js", "bg": "inline", "defaultCodeOpen": false}}
60+
5461
## Custom elements
5562

5663
Use the `render` prop to replace default elements.

0 commit comments

Comments
 (0)