Read CSV file in React
Today we’ll show you how to upload and read CSV file in React. Basically, we’ll show you an example to upload or Import CSV file and read the data of the CSV file using ReactJS.
In this demo example, we will have two HTML elements such as file upload and table. The file upload will be used to select the CSV file from the system and parse data in JSON format whereas the table will be used to display the CSV data from the file.
Steps to read CSV file in React
- Create react application
- Install npm dependencies
- Create a page to upload CSV file and display data
- Add logic to read CSV file
- Output
1. Create react application
First of all, we have to create a startup react application using the create-react-app
. Run the following command to create a react application.
1 | npx create-react-app read-csv-file-react |
2. Install npm dependencies
In the second step, we will install the required dependencies such as xlsx and react-data-table-component.
Run the following command to install the SheetJS js-xlsx
npm package.
1 | npm install xlsx |
In this example, we will also use the React Datatable to display uploaded CSV records in the table view. Run the following command to install the react-data-table-component
.
1 | npm install react-data-table-component styled-components |
3. Create a page to upload CSV file and display data
Let’s create a simple page where we will add the file input element to upload the CSV file and the react datatable to display the data.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import React, { useState } from 'react'; import DataTable from 'react-data-table-component'; function App() { const [columns, setColumns] = useState([]); const [data, setData] = useState([]); // handle file upload const handleFileUpload = e => { } return ( <div> <h3>Read CSV file in React - <a href="https://www.cluemediator.com" target="_blank" rel="noopener noreferrer">Clue Mediator</a></h3> <input type="file" accept=".csv,.xlsx,.xls" onChange={handleFileUpload} /> <DataTable pagination highlightOnHover columns={columns} data={data} /> </div> ); } export default App; |
4. Add logic to read CSV file
Let’s try to add the logic to read the CSV file. Therefore we will import the xlsx
npm package on top of the page. Also, we have to add two methods to convert CSV data to JSON format.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | import * as XLSX from 'xlsx'; ... ... function App() { ... ... // process CSV data const processData = dataString => { const dataStringLines = dataString.split(/\r\n|\n/); const headers = dataStringLines[0].split(/,(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)/); const list = []; for (let i = 1; i < dataStringLines.length; i++) { const row = dataStringLines[i].split(/,(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)/); if (headers && row.length == headers.length) { const obj = {}; for (let j = 0; j < headers.length; j++) { let d = row[j]; if (d.length > 0) { if (d[0] == '"') d = d.substring(1, d.length - 1); if (d[d.length - 1] == '"') d = d.substring(d.length - 2, 1); } if (headers[j]) { obj[headers[j]] = d; } } // remove the blank rows if (Object.values(obj).filter(x => x).length > 0) { list.push(obj); } } } // prepare columns list from headers const columns = headers.map(c => ({ name: c, selector: c, })); setData(list); setColumns(columns); } // handle file upload const handleFileUpload = e => { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = (evt) => { /* Parse data */ const bstr = evt.target.result; const wb = XLSX.read(bstr, { type: 'binary' }); /* Get first worksheet */ const wsname = wb.SheetNames[0]; const ws = wb.Sheets[wsname]; /* Convert array of arrays */ const data = XLSX.utils.sheet_to_csv(ws, { header: 1 }); processData(data); }; reader.readAsBinaryString(file); } return ( <div> <h3>Read CSV file in React - <a href="https://www.cluemediator.com" target="_blank" rel="noopener noreferrer">Clue Mediator</a></h3> ... ... </div> ); } export default App; |
5. Output
Let’s combine all the code together and see how it looks.
App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import React, { useState } from 'react'; import * as XLSX from 'xlsx'; import DataTable from 'react-data-table-component'; function App() { const [columns, setColumns] = useState([]); const [data, setData] = useState([]); // process CSV data const processData = dataString => { const dataStringLines = dataString.split(/\r\n|\n/); const headers = dataStringLines[0].split(/,(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)/); const list = []; for (let i = 1; i < dataStringLines.length; i++) { const row = dataStringLines[i].split(/,(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)/); if (headers && row.length == headers.length) { const obj = {}; for (let j = 0; j < headers.length; j++) { let d = row[j]; if (d.length > 0) { if (d[0] == '"') d = d.substring(1, d.length - 1); if (d[d.length - 1] == '"') d = d.substring(d.length - 2, 1); } if (headers[j]) { obj[headers[j]] = d; } } // remove the blank rows if (Object.values(obj).filter(x => x).length > 0) { list.push(obj); } } } // prepare columns list from headers const columns = headers.map(c => ({ name: c, selector: c, })); setData(list); setColumns(columns); } // handle file upload const handleFileUpload = e => { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = (evt) => { /* Parse data */ const bstr = evt.target.result; const wb = XLSX.read(bstr, { type: 'binary' }); /* Get first worksheet */ const wsname = wb.SheetNames[0]; const ws = wb.Sheets[wsname]; /* Convert array of arrays */ const data = XLSX.utils.sheet_to_csv(ws, { header: 1 }); processData(data); }; reader.readAsBinaryString(file); } return ( <div> <h3>Read CSV file in React - <a href="https://www.cluemediator.com" target="_blank" rel="noopener noreferrer">Clue Mediator</a></h3> <input type="file" accept=".csv,.xlsx,.xls" onChange={handleFileUpload} /> <DataTable pagination highlightOnHover columns={columns} data={data} /> </div> ); } export default App; |
Run the project and check the output in the browser. You can download the sample CSV file from here.
That’s it for today.
Thank you for reading. Happy Coding..!!
Hi,
Can you please show how to implement datatable with csv file instead of json file
Hi Sayli,
The current article will help you to read the CSV file and display the data on the screen. But as per your requirement, you have to implement file upload functionality and then try to read the data in the back-end for insertion.
We have similar functionality in react to upload files where we are uploading the image but you can refer the following article for file upload and you have to perform the rest of the functionalities in the backend.
Image upload in ReactJS
Hope this will help you!
Try a 450k record file and it crashes
Yes Andres, You can not manage so many records at the client-side. You have to split the sheet before doing the process or manage the whole functionality at the backend side.
Hi
Great article, thanks!!
I want implement a upload file feature as well (probably using a dropzone) and having it rendered as a list, so this will help me. I’ll handle all logic at the server-side bc i want the application to allow upload and parsing of different file types, so i think it’s best to do all this at the backend.
I think i will need to: 1) Make http post request, sending the uploaded file from client to server 2) handle file type validation and parsing 3) Make http get request to fetch parsed data from server to client, and have it rendered there
Would you suggest other wise?
thanks
You can refer to the following article.
Drag and Drop File Upload in React using react-dropzone-uploader
I can`t install xlsx, getting the following message:
npm WARN [email protected].6 requires a peer of react@>= ^16.8.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected].1 requires a peer of typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta but none is installed. You must install peer dependencies yourself.
Hi Dimce, It looks like you have to install the higher version of the react for react-data-table-component. But instead, you can use the other packages or plain HTML code for display purposes. Check out the following link.
Display data in the table using React
Great article! I have another question is that, what about I want to access the path of the file I chose right now? How can I access it?
Do you want to access the file path of the local system?
Hi, Thank you for this blog!!
I was wondering what
———
const dataStringLines = dataString.split(/\r\n|\n/);
const headers = dataStringLines[0].split(/,(?![^”]*”(?:(?:[^”]*”){2})*[^”]*$)/);
———
this part does?
I know it’s regular expression. But did’t know why it needed to be ”/\r\n|\n/” and ”/,(?![^”]*”(?:(?:[^”]*”){2})*[^”]*$)/”
Thank you!
Hi Tomo,
The first line
const dataStringLines = dataString.split(/\r\n|\n/);
is used to get the list of rows.The second line
const headers = dataStringLines[0].split(/,(?![^”]*”(?:(?:[^”]*”){2})*[^”]*$)/);
is used to get the list of the headers.To get the header const headers = dataStringLines[0].split(/,(?![^”]*”(?:(?:[^”]*”){2})*[^”]*$)/); this regular expression can not work if I give the space in header. If my header contais the 2 words the how to write the RE for that?
Hi Rahul,
Can you please compare your code with the given GitHub source code? You can see the output at the end of the article, where we have space in the header and it’s working fine.
How to display the particular required column data after uploading the .csv file?
You can use the filter method to get only the required columns. Look at the following article for your reference.
https://www.cluemediator.com/map-filter-and-reduce-operators-in-javascript#fo
const columns = headers.map(c => ({
name: c,
selector: c,
}));
could you please explain whats happening?
It’s a same as this one.
const columns = headers.map(c => {
return {
name: c,
selector: c
}
});
The above code will return a list of objects that have a name and a selector and we will read them from the headers.
Hope this is clear now.