Reputation: 724
I have the following Data which when downloaded can be viewed in an xls/csv format. I am using react-csv npm package which is displaying the name and description in same columns as opposed to different columns.
I need some help in figuring out how to display data where Name, Description, and Roles are displayed in different columns as shown below.
Data:-
const csvData = [
{
name: 'Data science training',
description:
'Data Science certification training',
suggestedRoles: [
{ id: 16, category: 'DEVELOPER', name: 'Data Engineer' },
{ id: 17, category: 'DEVELOPER', name: 'Data Scientist' }]
},{
name: 'AWS',
description:
'AWS certification training',
suggestedRoles: [
{ id: 16, category: 'DEVELOPER', name: 'Cloud Engineer' },
{ id: 17, category: 'DEVELOPER', name: 'Network Engineer' }]
}],
Expected Output:-
Name Description RoleName
Data Science Training Data Science Certification Training Data Engineer
Data Scientist
AWS Training AWS Certification Training Cloud Engineer
Network Engineer
Current Output:-
Name Description RoleName
Data Science Training,AWS Training Data Science Certification Training, AWS Certification Training Data Engineer,Data Scientist,Cloud Engineer,Network Engineer
Code:-
export const ReactCsv = () => {
const createCsvFileName = ()=> `data_${moment().format()}.csv`;
const headers = [
{ label: 'Name', key: 'name' },
{ label: 'Description', key: 'description' },
{ label: 'SuggestedRoles', key: 'suggestedRoles' }
];
const data = [
{
name: csvData.map((_)=>_.name),
description: csvData.map((_)=>_.description),
suggestedRoles: csvData.map((_)=>_.suggestedRoles.map((role)=>role.name)),
}
];
return (
<CSVLink
data={data}
headers={headers}
filename={createCsvFileName()}
target="_blank"
style={{ textDecoration: 'none', outline: 'none', height: '5vh' }}
>
<Button variant="contained" color="secondary" style={{ height: '100%' }}>
Download CSV
</Button>
</CSVLink>
);
};
Upvotes: 1
Views: 8493
Reputation: 81
The data property should be one single object. So, what you can do is create a function that returns an object. That object structure you can decide based on the data and attributes you want to display.
eg:
const newBillingReport = () => {
try {
const newBillingReportData = billingExportReportData.map((data) => ({
"Type": data?.type || "Not Provided",
"Status": data?.status || "Not Provided",
"Billed": data?.billedAmount || "0",
}),[])
return newBillingReportData
} catch (error) {
console.error(error)
}
}
This will returns object with three attributes:
eg:
{
"Type": "COMPLETED",
"Status": "DONE",
"Billed": "True"
}
So like this you can create a function. Then for the header attribute map same as you returned. That should also will be a function that returns an object
eg:
const formatUserName = () => {
return [
{ label: "Type", key: "Type" },
{ label: "Status", key: "Status" },
{ label: "Billed ($)", key: "Billed" },
]
}
In here you can see how you need to add label and keys. Most likely the function return data.
So CVLink like this
headers={headers}
data={newBillingReport()}
headers should call the function const headers = formatUserName()
Upvotes: 0
Reputation: 1016
Your ReactCsv
's data
generating code should be changed into like this one.
export const ReactCsv = () => {
const createCsvFileName = ()=> `data_${moment().format()}.csv`;
const headers = [
{ label: 'Name', key: 'name' },
{ label: 'Description', key: 'description' },
{ label: 'SuggestedRoles', key: 'suggestedRoles' }
];
let data = []
csvData.forEach(item => {
data.push({
name: item.name,
description: item.description,
suggestedRoles: item.suggestedRoles[0].name
});
for (let i = 1; i < item.suggestedRoles.length; i++) {
const role = item.suggestedRoles[i];
data.push({
name: '',
description: '',
suggestedRoles: role.name
});
}
});
return (
<CSVLink
data={data}
headers={headers}
filename={createCsvFileName()}
target="_blank"
style={{ textDecoration: 'none', outline: 'none', height: '5vh' }}
>
<Button variant="contained" color="secondary" style={{ height: '100%' }}>
Download CSV
</Button>
</CSVLink>
);
};
Upvotes: 2
Reputation: 713
The data
variable must be an array of objects, not an array of a single object where each property is an array of values.
const csvData = [{
name: 'Data science training',
description: 'Data Science certification training',
suggestedRoles: [{
id: 16,
category: 'DEVELOPER',
name: 'Data Engineer'
},
{
id: 17,
category: 'DEVELOPER',
name: 'Data Scientist'
}
]
}, {
name: 'AWS',
description: 'AWS certification training',
suggestedRoles: [{
id: 16,
category: 'DEVELOPER',
name: 'Cloud Engineer'
},
{
id: 17,
category: 'DEVELOPER',
name: 'Network Engineer'
}
]
}];
const data = csvData.map(item => ({
name: item.name,
description: item.description,
suggestedRoles: item.suggestedRoles.map(role => role.name),
}))
console.log(data);
Upvotes: 2