Download a ReactJS object as a file
I used a package jsonexport in my React app and now I am able to download the csv file on a link click. Here is what I did:
.
.
import React, {useState,useEffect} from 'react';// I am using React Hooks
import * as jsonexport from "jsonexport/dist";
.
.
.
const [filedownloadlink, setFiledownloadlink] = useState("");//To store the file download link
.
.
.
Create a function that will provide data for CSV. It can also be in a callback from a network request. When this method is called, it will set value in filedownloadlink
state.
function handleSomeEvent(){
var contacts = [{
name: 'Bob',
lastname: 'Smith'
},{
name: 'James',
lastname: 'David'
},{
name: 'Robert',
lastname: 'Miller'
},{
name: 'David',
lastname: 'Martin'
}];
jsonexport(contacts,function(err, csv){
if(err) return console.log(err);
var myURL = window.URL || window.webkitURL //window.webkitURL works in Chrome and window.URL works in Firefox
var csv = csv;
var blob = new Blob([csv], { type: 'text/csv' });
var csvUrl = myURL.createObjectURL(blob);
setFiledownloadlink(csvUrl);
});
}
In the render function use something like this:
{filedownloadlink &&<a download="UserExport.csv" href={filedownloadlink}>Download</a>}
The above link will be visible when filedownloadlink
has some data to download.
Adding the below code for future reference. This is to include some additional checks on browser compatibility and additional code to include IE10+.
/* Take a blob and force browser to click a link and save it from a download path
* log out timing
*
* @param {Blob}
* @method saveFile
*/
function saveFile(blob) {
const uniqTime = new Date().getTime();
const filename = `my_file_${uniqTime}`;
if (navigator.msSaveBlob) { // IE 10+
console.info('Starting call for ' + 'ie download');
const csvFormatTimeStart = new Date().getTime();
const ieFilename = `${filename}.csv`;
navigator.msSaveBlob(blob, ieFilename);
const csvFormatTimeEnd = new Date().getTime();
const csvFormatTime = csvFormatTimeEnd - csvFormatTimeStart;
console.log('ie download takes ' + csvFormatTime + ' ms to run');
} else {
console.info('Starting call for ' + 'regular download');
const csvFormatTimeStart = new Date().getTime();
let link = document.createElement("a");
if (link.download !== undefined) { // feature detection
// Browsers that support HTML5 download attribute
var url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", filename);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
const csvFormatTimeEnd = new Date().getTime();
const csvFormatTime = csvFormatTimeEnd - csvFormatTimeStart;
console.log('regular download takes ' + csvFormatTime + ' ms to run');
}
clickEnd = new Date().getTime();
console.log('The whole process took: ' + (clickEnd - clickStart) + ' ms');
}
Credit should go to this article.
Adding the following code based on comments by @blex got the file download working. To see it in context, take a look at the success callback in the question.
var data = new Blob([res], {type: 'text/csv'});
var csvURL = window.URL.createObjectURL(data);
tempLink = document.createElement('a');
tempLink.href = csvURL;
tempLink.setAttribute('download', 'filename.csv');
tempLink.click();