如何将Material-UI表格选中数据传至后端以上选内容下载?
Hey there! Let's fix this step by step—you're already halfway there with your Material-UI Table setup. Here's a straightforward way to capture selected rows, send their data to your backend, and generate the download:
Step 1: Track Selected Rows in Your Frontend
First, we need to add state to keep track of which rows are selected, plus a handler to update that state when selections change.
Update your component constructor to add the new state property and bind the handler:
constructor(props) { super(props); this.state = { // ... keep all your existing state properties selectedRows: [] // Add this to track selected data rows }; // ... keep your existing bindings this.handleRowSelection = this.handleRowSelection.bind(this); // Bind the new handler }
Add the handleRowSelection method to translate selected row indices into actual data rows:
handleRowSelection(selectedIndices) { // Map the selected indices to the corresponding rows from tableData const selectedData = selectedIndices.map(index => this.state.tableData[index]); this.setState({ selectedRows: selectedData }); }
Attach the handler to your Table component with the onRowSelection prop:
<Table // ... all your existing props onRowSelection={this.handleRowSelection} // Add this line >
Step 2: Modify the Download Handler to Send Selected Data
Your current download uses a GET request, which isn't great for sending data. Switch to a POST request and send the selected rows' unique IDs (like MongoDB's _id) to the backend.
Update the handleClick method:
handleClick() { // Extract the _id values from selected rows (ensure your tableData includes _id!) const selectedIds = this.state.selectedRows.map(row => row._id); if (selectedIds.length === 0) { alert("Please select at least one row to download!"); return; } let anchor = document.createElement("a"); let file = 'http://localhost:3000/api/export'; let headers = new Headers(); headers.append('Authorization', `bearer ${Auth.getToken()}`); headers.append('Content-Type', 'application/json'); // Tell backend we're sending JSON fetch(file, { method: 'POST', // Switch to POST for sending data headers, body: JSON.stringify({ selectedIds }) // Send the selected IDs in the request body }) .then(response => response.blob()) .then(blobby => { let objectUrl = window.URL.createObjectURL(blobby); anchor.href = objectUrl; anchor.download = 'selected-data.xlsx'; anchor.click(); window.URL.revokeObjectURL(objectUrl); }) .catch(err => console.error('Download error:', err)); };
Step 3: Update Your Backend to Process Selected IDs
Your backend currently uses a GET route, which won't receive request body data properly. Switch to a POST route and adjust the logic to use the incoming selected IDs.
Modify your backend export route:
// Change from router.get to router.post router.post("/export",(req,res) => { const selectedIds = req.body.selectedIds; // Handle empty selection case if (!selectedIds || selectedIds.length === 0) { return res.status(400).send("No rows selected for export"); } // Convert string IDs to MongoDB ObjectIds const productArr = selectedIds.map(id => mongoose.Types.ObjectId(id)); var conf ={}; conf.name = "mysheet"; conf.cols = [ { caption:'name', type:'string' }, { caption:'event', type:'string' }, { caption:'email', type:'string' }, { caption:'iban', type:'string' }, { caption:'uid', type:'string' }, { caption:'date', type:'date' } ]; conf.rows = []; User.find({'_id': { $in: productArr }}, function(err, allUid){ if (err) { console.error(err); return res.status(500).send("Error fetching selected data"); } for(var i= 0; i < allUid.length; i++) { var tempdate = ""; try { tempdate = new Date(allUid[i].date).toISOString().replace(/T/, ' ').replace(/\..+/, ''); } catch(err) { console.log("Date formatting error: ", err); } conf.rows.push([ allUid[i].name, allUid[i].event, allUid[i].email, allUid[i].iban, allUid[i].uid, tempdate ]); } var result = nodeExcel.execute(conf); res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); res.setHeader("Content-Disposition", "attachment; filename=SelectedReport.xlsx"); res.end(result, 'binary'); }); });
Quick Notes to Keep in Mind:
- Make sure your
tableDatafrom the backend includes the_idfield (it should by default in MongoDB) so we can send those IDs back for filtering. - We switched to POST because GET requests aren't designed to carry request body data—this is the standard approach for sending data to a server.
- Added basic error handling for empty selections and server errors to make the flow more robust.
内容的提问来源于stack exchange,提问作者Anas

