Comments (19)
The downside of using the CSVDownload
component is that it doesn't accept the filename
prop. I ended up getting this to work by setting up a regular button, which, when clicked, fetches the data and then triggers a click of a hidden CSVLink
:
class MyCsvLink extends React.Component {
csvLink = React.createRef()
state = { data: [] }
fetchData = () => {
fetch('/mydata').then(data => {
this.setState({ data }, () => {
// click the CSVLink component to trigger the CSV download
this.csvLink.current.link.click()
})
})
}
render() {
return (
<div>
<button onClick={this.fetchData}>Download CSV</button>
<CSVLink
data={this.state.data}
filename="data.csv"
className="hidden"
ref={this.csvLink}
target="_blank"
/>
</div>
)
}
}
It'd be nice if this plugin exposed a JS API that could be used to trigger a download instead of requiring the CSVDownload
or CSVLink
components to be used.
from react-csv.
This worked for me:
<CSVLink data={[["Test", 1], ['Test', 2]].toString()} filename={this.props.title}><Button>Download CSV</Button></CSVLink>
from react-csv.
Given that the function for data property does not appear to actually work, I suggest removing it from the docs.
from react-csv.
In case anyone is having only a Ôªø
symbol in CSV, put your this.csvLink.current.link.click()
inside of the setTimeout
statement like so:
setTimeout(() => {
this.csvLink.current.link.click();
});
from react-csv.
@abdennour I've tried following the 'Async + data function' approach using react-csv version 2.2.2, copying the example closely (but using my own async function/request), and reliably get the following error:
dev-1214.js:1 Uncaught TypeError: Data should be a "String", "Array of arrays" OR "Array of objects"
at toCSV (core.js:1:3429)
at buildURI (core.js:1:3625)
at CSVLink.buildURI (Link.js:1:2399)
at CSVLink.render (Link.js:1:4230)
at finishClassComponent (one-vui-9e10834c-dev.js:1:566704)
at updateClassComponent (one-vui-9e10834c-dev.js:1:566126)
at beginWork (one-vui-9e10834c-dev.js:1:584296)
at HTMLUnknownElement.callCallback (one-vui-9e10834c-dev.js:1:422607)
at HTMLUnknownElement.nrWrapper (dev-1214.js:1:30034)
at Object.invokeGuardedCallbackDev (one-vui-9e10834c-dev.js:1:422975)
A stripped-down version of my implementation:
export default class DownloadUsers extends Component {
constructor(props) {
super(props);
this.state = {
listOfUsers: [],
};
}
fetchData = (event, done) => {
Querier.query({
query: someQuery
}).then(({ data }) => {
const users = data.listOfUsers;
this.setState({ listOfUsers });
done(true);
});
};
dataFromListOfUsersState = () => {
return this.state.listOfUsers;
};
render() {
return (
<CSVLink data={this.dataFromListOfUsersState} asyncOnClick={true} onClick={this.fetchData}>
Download CSV
</CSVLink>
);
}
}
Any ideas before I file an issue? And thank you for your work on this excellent package.
from react-csv.
@christianallred the problem with that solution is that it will potentially download the CSV every time a render occurs after fetching data.
I don't think that this component should be responsible for fetching data, so the solution to this problem needs to exist outside of this library.
@arpitprod assuming that this component exists on a page that has to fetch some data before, you could try something like this:
- Fetch the data required for the page to render
- Fetch the data for the CSV, but don't let it prevent the rest of the page from loading
- Render the page, but display a loader in place of the CSV download button
- When the data for the CSV has returned, render the CSV button properly
This pattern may help you with this solution: https://lucasmreis.github.io/blog/simple-react-patterns/
from react-csv.
In case anyone is having only a
Ôªø
symbol in CSV, put yourthis.csvLink.current.link.click()
inside of thesetTimeout
statement like so:setTimeout(() => { this.csvLink.current.link.click(); });
I confirm, my code was based on this answer: https://stackoverflow.com/a/53558566 and I needed to add a setTimeout to make it work. I did not find a better solution... :(
from react-csv.
Follow the given Point -
Define
- const ref = React.useRef(null)
const [exportData, setExportData] = useState([])
const onClickExport = async () => {
showLoadingModal()
let data = await api.index(userId)
setExportData(data)
hideLoadingModal()
ref.current.click()
}
3.
<> <UiButton color="link" icon="download" size="small" onClick={onClickExport} /> </>
4.
<CSVLink data={exportData} filename={fileName}> <span ref={ref}></span> </CSVLink>
from react-csv.
This is already doable via CSVDownload element.
https://github.com/abdennour/react-csv#2-csvdownload-component
<div>
<Button onClick={this.fetchData}>Button</Button>
{this.state.data != null ? <CSVDownload data={this.state.data} target="_blank" /> : null }
</div>
Disclosure: i have not tried this.. but a quick review of the documentation would suggest my code above shoudl work.
from react-csv.
@kundan621 I haven't found a solution to this particular issue however there is a workaround to handle async data loading following the approach described here or here.
from react-csv.
@christianallred Doesn't this solution also will require user to click 2 buttons to download a single csv?
@arpitprod: Hey, I am also working on a similar issue. Did you come across a solution for this?
from react-csv.
It should be written like this:
{ this.state.boolean?<CSVDownload target="_parent" data={data}></CSVDownload>:''}
onClick=(){ this.setState({ boolean: true },() =>{ this.setState({ boolean: false }) }) }
from react-csv.
this is what I tried and it works for me: (I use React+Redux)
P.S: This is what @christianallred suggests in the initial comment as well, using react state.
Made a stateless component like this:
const CSVButton = ({ data, fetchCSVData, fileName }) => {
if (_.isEmpty(data)) {
return (
<span onClick={fetchCSVData} className="csv-download">
CSV <Icon icon="download" />
</span>
)
} else {
return (
<CSVDownload
className="csv-download"
target="_self"
filename={fileName}
data={data}
/>
)
}
}
the fetchCSVData action, fetches the data in async mode, and dispatches two actions. one for setting the data field and other which un-sets/resets the data field.
What really happens is, the state change triggers the reload of the stateless component and CSVDownload is rendered in the DOM to initiate the download functionality. The state is reset then to remove the specific element out of the DOM
from react-csv.
@stevehanson is CSVLink component working on firefox as well ? i am having some issues with that.
from react-csv.
A couple of great solutions to the question here. Hopefully @arpitprod they answer your question, please re-open if not. @vikapath please open a new issue if your still having issues with Firefox
from react-csv.
@stevehanson I'm trying your approach, however when I go to open the csv e.g in excel, the index.html HTML is just shown..
Any idea how to fix this? I'm doing exactly the same as you, and if I console log the this.state.data I see the data..
from react-csv.
Check README.md, and specifically the section 🔬 Async + data function
. Enjoy!
Available since [email protected]
from react-csv.
@abdennour
I am also facing the same issues. Example code itself is not working and breaking screen by throwing Data should be a "String", "Array of arrays" OR "Array of objects"
@garedean Did you find any solution?
from react-csv.
@kundan621 I haven't found a solution to this particular issue however there is a workaround to handle async data loading following the approach described here or here.
Thank you @garedean :)
from react-csv.
Related Issues (20)
- Can we download multiple tables in same file? HOT 1
- Start download while data is still being fetched from API calls HOT 1
- How to get it to ignore commas in strings within an array
- how to new line in cell HOT 1
- still getting UTF-8-BOM when setting prop uFEFF={false} HOT 1
- asyncOnClick = true together with onClick just doesnt work HOT 9
- is there any condition ' . ' must after ' " ' ? (need full stop after closing of double inverted comma)
- When the text contains double quotes, it will be divided into different columns. HOT 4
- File .csv not open directly with Excel HOT 1
- Data display vertically instead
- Module not found: Can't resolve 'prop-types' for NextJS project HOT 3
- Issue in async data
- [Object object] alert coming on CSVLink click
- The downloaded file is corrupted and cannot be open by microsoft excel
- Specify column order but not write headers
- Getting empty CSV files after upgrading to React 18 HOT 4
- Async Data HOT 3
- Detect the correct seperator
- Zip multiple files
- data attribute doesn't support function HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-csv.