I am trying to generate the file name using current date time using below code:
getFileName() {
let d = new Date();
let dformat = [this.padLeft(d.getMonth() + 1),
this.padLeft(d.getDate()),
d.getFullYear()].join('') +
'_' +
[this.padLeft(d.getHours()),
this.padLeft(d.getMinutes()),
this.padLeft(d.getSeconds())].join('');
console.log("getCurrentDate : ", dformat);
return "GridWidget_" + dformat + ".csv";
}
render() {
return(
<CSVLink data={data} filename={this.getFileName()} className="btn btn-primary" target="_blank">Export To CSV</CSVLink>);
}
Issue with the above code is like File name is not generated with date time while downloading the file, but the time is taken while the page loads. What I want to do is the filename should generated only when the user clicks the download button.
I know this doesn't make much difference in time but requirement is like should generate it with actual date time. Not able to understand why this is happening.
By default you can't do it because filename props is download attribute of <a /> tag which is a built-in HTML. and it generate on render.
<a download="10-36-45.csv" target="_blank" href="">Export To CSV</a>
But there is a hack way you can do by using React Refs to modify attribute of <a> tag.
export default class extends Component {
$CSVLink = React.createRef();
getFileName() {
let d = new Date();
let dformat = `${d.getHours()}-${d.getMinutes()}-${d.getSeconds()}`;
console.log("getCurrentDate : ", dformat);
return "GridWidget_" + dformat + ".csv";
}
render() {
const data = [
{ firstname: "Ahmed", lastname: "Tomi", email: "[email protected]" },
{ firstname: "Raed", lastname: "Labes", email: "[email protected]" },
{ firstname: "Yezzi", lastname: "Min l3b", email: "[email protected]" }
];
return (
<CSVLink
onClick={() => {
this.$CSVLink.current.link.download = this.getFileName();
}}
ref={this.$CSVLink}
data={data}
filename={this.getFileName()}
className="btn btn-primary"
target="_blank"
>
Export To CSV
</CSVLink>
);
}
}
I change getFileName method since I don't have information about this.padLeft, getFileName method will return current date so you can see the second changes.
Your getFileName is being called during rendering, you need to call it when the click happens (i.e. CSVLink's onCLick) method. Luckily they provide a way to write async onClick.
First, set a state named filename:
state = {
filename: ""
}
Now add a callback to CSVLink with asyncOnClick={true}. This function is supposed to be called before any handling logic. See the docs.
In that onClick, set your state and once that is finished call done():
<CSVLink
data={data}
asyncOnClick={true}
filename={this.state.filename}
onClick={(event, done) => {
this.setState({
filename: this.getFileName()
}, () => {
done()
})
}}
>
Download me
</CSVLink>;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With