58

I have data in CSV format and want to convert into JSON format using JavaScript.

Following are csv format:

[Test.csv] 
id;name;author
integer;string;authors:n
1;To Kill an Angry Bird;1
[authors.csv] 
id;name
integer;string
1;Harper Lee
2;JRR Tolkien
3;William Shakespeare

I want to get all the books with their authors. How can I implement it using JavaScript?

TylerH
21.3k84 gold badges84 silver badges122 bronze badges
asked Jan 16, 2015 at 7:15
1
  • Use jquery-csv, specifically toArrays() to convert the CSV to convert to in-memory data. Then call JSON.stringify() to convert it to JSON. Here's the link to jquery-csv github.com/evanplaice/jquery-csv Commented Jan 21, 2016 at 14:16

8 Answers 8

88

The below should work for you.

All credit to Convert CSV to JSON in JavaScript (archived), by iwek:

//var csv is the CSV file with headers
function csvJSON(csv){
 
 var lines=csv.split("\n");
 
 var result = [];
 
 var headers=lines[0].split(",");
 
 for(var i=1;i<lines.length;i++){
 
 var obj = {};
 var currentline=lines[i].split(",");
 
 for(var j=0;j<headers.length;j++){
 obj[headers[j]] = currentline[j];
 }
 
 result.push(obj);
 
 }
 
 //return result; //JavaScript object
 return JSON.stringify(result); //JSON
}

If your columns contain commas in their values, you'll need to deal with those before doing the next step (you might convert them to &&& or something, then covert them back later).

TylerH
21.3k84 gold badges84 silver badges122 bronze badges
answered Jan 16, 2015 at 7:21
Sign up to request clarification or add additional context in comments.

5 Comments

This will go awry if the string in-between any delimiters is a quoted string with those delimiters. Like a quoted sentence with a comma, since it will split at the comma inside the string instead of ignoring the ones inside quotes.
@matthew-e-brown Indeed it will. Good observation.
Perhaps take a look at my answer here, the question that led me here in the first place? I don't exactly wish to copy-paste my answer over, since this answer works well for most cases, but I think just leaving this link in the comments may help others in the future if they're in this edge case. :-)
Can u tell me how do I convert CSV to JSON and add a parent node here is my CSV drive.google.com/file/d/1mQGqoXuxkLHAfJ4mrQMIB90apg9LiC1X/… here is the exact JSON format I want drive.google.com/file/d/1U_UoZhlM2CyJiGZ9nT0UqaXq-FuMuIJm/… ,u may think that if i have already converted the CSV to JSON why I'm asking to do it in programmatically,because when I'm converting the CSV to JSON the online converter is creating some issues with special characters and replacing it to this � ,so I was thinking to do it programmatically without this symbol error
The first challenge among others is to avoid special characters contained in a cell. your code failed at this first obstacle.
34

I would check out PapaParse. They have a file called papaparse.min.js that you can drop into your project if need be. PapaParse has no dependencies.

I have used it myself and can verify it works, is convenient, and is well-documented.

TylerH
21.3k84 gold badges84 silver badges122 bronze badges
answered Apr 16, 2019 at 20:00

Comments

8

Based on the code by iwek re-shared in Wesley Smith's answer, I would add if (!lines[i]) continue so it can ignore any empty line and trailing lines.

function csvJSON(csv) {
 const lines = csv.split('\n')
 const result = []
 const headers = lines[0].split(',')
 for (let i = 1; i < lines.length; i++) { 
 if (!lines[i])
 continue
 const obj = {}
 const currentline = lines[i].split(',')
 for (let j = 0; j < headers.length; j++) {
 obj[headers[j]] = currentline[j]
 }
 result.push(obj)
 }
 return result
}
TylerH
21.3k84 gold badges84 silver badges122 bronze badges
answered Aug 9, 2019 at 5:58

2 Comments

This is the result I retrieve from my CSV ... I think you forgot to take count of quotes formatted CSV files [ { '"foo"': '"bar"', '"created"': '"2021年08月09日 13:44:42"', '"price"': '"10.00"', }, ]
we have created online tool using above code, which anyone can refer here: minify-beautify.com/online-csv-to-json-convert
6

This solution fixed the comma issue.

function csvJSON(text, quoteChar = '"', delimiter = ',') {
 var rows=text.split("\n");
 var headers=rows[0].split(",");
 const regex = new RegExp(`\\s*(${quoteChar})?(.*?)\1円\\s*(?:${delimiter}|$)`, 'gs');
 
 const match = line => [...line.matchAll(regex)]
 .map(m => m[2]) 
 .slice(0, -1); 
 
 var lines = text.split('\n');
 const heads = headers ?? match(lines.shift());
 lines = lines.slice(1);
 
 return lines.map(line => {
 return match(line).reduce((acc, cur, i) => {
 // replace blank matches with `null`
 const val = cur.length <= 0 ? null : Number(cur) || cur;
 const key = heads[i] ?? `{i}`;
 return { ...acc, [key]: val };
 }, {});
 });
 }
var csvtojson = csvJSON(SOME_CSV_DATA);
console.log(csvtojson)
answered Sep 18, 2022 at 2:43

Comments

6

This solution has one issue i.e. the values should not contain comma(,):

 // convert csv to json
csvJSON(csvText) {
let lines = [];
const linesArray = csvText.split('\n');
// for trimming and deleting extra space 
linesArray.forEach((e: any) => {
 const row = e.replace(/[\s]+[,]+|[,]+[\s]+/g, ',').trim();
 lines.push(row);
});
// for removing empty record
lines.splice(lines.length - 1, 1);
const result = [];
const headers = lines[0].split(",");
for (let i = 1; i < lines.length; i++) {
 const obj = {};
 const currentline = lines[i].split(",");
 for (let j = 0; j < headers.length; j++) {
 obj[headers[j]] = currentline[j];
 }
 result.push(obj);
}
//return result; //JavaScript object
// return JSON.stringify(result); //JSON
return result;
}
// For Reading CSV File
readCSV(event) {
const reader = new FileReader();
reader.readAsText(event.files[0]);
reader.onload = () => {
 const text = reader.result;
 const csvToJson = this.csvJSON(text);
 console.log(csvToJson);
};
}
TylerH
21.3k84 gold badges84 silver badges122 bronze badges
answered Dec 3, 2019 at 19:52

2 Comments

Can u tell me how do I convert CSV to JSON and add a parent node here is my CSV drive.google.com/file/d/1mQGqoXuxkLHAfJ4mrQMIB90apg9LiC1X/… here is the exact JSON format I want drive.google.com/file/d/1U_UoZhlM2CyJiGZ9nT0UqaXq-FuMuIJm/… ,u may think that if i have already converted the CSV to JSON why I'm asking to do it in programmatically,because when I'm converting the CSV to JSON the online converter is creating some issues with special characters and replacing it to this � ,so I was thinking to do it programmatically without this symbol error
please reffer this to know more reddit.com/r/androiddev/comments/vftmlq/…
3

Here is my try on your SPECIFIC example. I know it is an old question but I have used current methods

const titlesCsv = `id;name;author
integer;string;authors:n
1;To Kill an Mockingbird;1
2;Lord of the Rings;2
3;Hamlet;3`
const authorsCsv = `id;name
integer;string
1;Harper Lee
2;JRR Tolkien
3;William Shakespeare`
const parseCsv = csv => {
 let lines = csv.split("\n");
 const header = lines.shift().split(";")
 lines.shift(); // get rid of definitions
 return lines.map(line => {
 const bits = line.split(";")
 let obj = {};
 header.forEach((h, i) => obj[h] = bits[i]); // or use reduce here
 return obj;
 })
};
const titles = parseCsv(titlesCsv)
const authors = parseCsv(authorsCsv)
const books = titles.map(title => {
 return {
 id: title.id,
 name: title.name,
 author: authors.find(author => author.id === title.author).name
 }
})
console.log(books)

answered Apr 28, 2020 at 6:40

Comments

2

Here is an improved version of Sandeep Sherpur's answer. This version handles:

  1. comma (,) and double quotes (") inside the value fields
  2. empty fields
  3. empty lines and useless spaces
  4. extra or missing commas
function csvToJson(text, quoteChar = '"', delimiter = ",") {
 text = text.trim()
 let rows = text.split("\n")
 let headers = rows[0].split(",")
 const regex = new RegExp(`\\s*(${quoteChar})?(.*?)\1円\\s*(?:${delimiter}|$)`, "gs")
 const match = (line) => {
 const matches = [...line.matchAll(regex)].map((m) => m[2])
 // Ensure matches length matches headers length by padding with null values
 const paddedMatches = Array.from({ length: headers.length }, (_, i) => matches[i] ?? null)
 return paddedMatches
 }
 let lines = text.split("\n")
 const heads = headers ?? match(lines.shift())
 lines = lines.slice(1)
 return lines.map((line) => {
 return match(line).reduce((acc, cur, i) => {
 // replace blank matches with `null`
 const val = cur === null || cur.length <= 0 ? null : Number(cur) || cur
 const key = heads[i] ?? `{i}`
 return { ...acc, [key]: val }
 }, {})
 })
}
const csvString = `
aa,bb,cc
11,22,33
44,
77,,99
`
const jsonData = csvToJson(csvString)
console.log(jsonData)
TylerH
21.3k84 gold badges84 silver badges122 bronze badges
answered May 28, 2024 at 9:46

Comments

0

I have a similar answer like the code by iwek re-shared in Wesley Smith's answer, but my code can be used in conjunction with Excel directly (copy and paste from Excel into a textarea).

function csvUpload(csvText){
 //Split all the text into seperate lines on new lines and carriage return feeds
 var allTextLines = csvText.split(/\r\n|\n/);
 //Split per line on tabs and commas
 var headers = allTextLines[0].split(/\t|,/);
 var lines = [];
 var locations = [];
 for (var i=1; i<allTextLines.length; i++) {
 var data = allTextLines[i].split(/\t|,/);
 
 if (data.length == headers.length) {
 
 var location = {"device_id":data[0], "address":data[1], "city":data[2]};
 locations.push(location);
 }
 }
 return locations;
 }

This way you can use a CSV that is copied into Excel. Excel will remove the seperators like , and others and will insert newlines etc.

With the my code you can pass everything into a textfield directly from Excel and then use that to create a json.

I have the naming of the fields static here, but you could use iwek's code to set the headers dynamically:

for(var j=0;j<headers.length;j++){
 obj[headers[j]] = currentline[j];
}
TylerH
21.3k84 gold badges84 silver badges122 bronze badges
answered Jan 16, 2015 at 9:10

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.