How to Parse CSV Data With JavaScript

How to parse CSV data?

You can use the CSVToArray() function mentioned in this blog entry.

<script type="text/javascript">
// ref: http://stackoverflow.com/a/1293163/2343
// This will parse a delimited string into an array of
// arrays. The default delimiter is the comma, but this
// can be overriden in the second argument.
function CSVToArray( strData, strDelimiter ){
// Check to see if the delimiter is defined. If not,
// then default to comma.
strDelimiter = (strDelimiter || ",");

// Create a regular expression to parse the CSV values.
var objPattern = new RegExp(
(
// Delimiters.
"(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +

// Quoted fields.
"(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +

// Standard fields.
"([^\"\\" + strDelimiter + "\\r\\n]*))"
),
"gi"
);

// Create an array to hold our data. Give the array
// a default empty first row.
var arrData = [[]];

// Create an array to hold our individual pattern
// matching groups.
var arrMatches = null;

// Keep looping over the regular expression matches
// until we can no longer find a match.
while (arrMatches = objPattern.exec( strData )){

// Get the delimiter that was found.
var strMatchedDelimiter = arrMatches[ 1 ];

// Check to see if the given delimiter has a length
// (is not the start of string) and if it matches
// field delimiter. If id does not, then we know
// that this delimiter is a row delimiter.
if (
strMatchedDelimiter.length &&
strMatchedDelimiter !== strDelimiter
){

// Since we have reached a new row of data,
// add an empty row to our data array.
arrData.push( [] );

}

var strMatchedValue;

// Now that we have our delimiter out of the way,
// let's check to see which kind of value we
// captured (quoted or unquoted).
if (arrMatches[ 2 ]){

// We found a quoted value. When we capture
// this value, unescape any double quotes.
strMatchedValue = arrMatches[ 2 ].replace(
new RegExp( "\"\"", "g" ),
"\""
);

} else {

// We found a non-quoted value.
strMatchedValue = arrMatches[ 3 ];

}

// Now that we have our value string, let's add
// it to the data array.
arrData[ arrData.length - 1 ].push( strMatchedValue );
}

// Return the parsed data.
return( arrData );
}

</script>

How to read data From *.CSV file using JavaScript?

NOTE: I concocted this solution before I was reminded about all the "special cases" that can occur in a valid CSV file, like escaped quotes. I'm leaving my answer for those who want something quick and dirty, but I recommend Evan's answer for accuracy.


This code will work when your data.txt file is one long string of comma-separated entries, with no newlines:

data.txt:

 heading1,heading2,heading3,heading4,heading5,value1_1,...,value5_2

javascript:

$(document).ready(function() {
$.ajax({
type: "GET",
url: "data.txt",
dataType: "text",
success: function(data) {processData(data);}
});
});

function processData(allText) {
var record_num = 5; // or however many elements there are in each row
var allTextLines = allText.split(/\r\n|\n/);
var entries = allTextLines[0].split(',');
var lines = [];

var headings = entries.splice(0,record_num);
while (entries.length>0) {
var tarr = [];
for (var j=0; j<record_num; j++) {
tarr.push(headings[j]+":"+entries.shift());
}
lines.push(tarr);
}
// alert(lines);
}

The following code will work on a "true" CSV file with linebreaks between each set of records:

data.txt:

heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2

javascript:

$(document).ready(function() {
$.ajax({
type: "GET",
url: "data.txt",
dataType: "text",
success: function(data) {processData(data);}
});
});

function processData(allText) {
var allTextLines = allText.split(/\r\n|\n/);
var headers = allTextLines[0].split(',');
var lines = [];

for (var i=1; i<allTextLines.length; i++) {
var data = allTextLines[i].split(',');
if (data.length == headers.length) {

var tarr = [];
for (var j=0; j<headers.length; j++) {
tarr.push(headers[j]+":"+data[j]);
}
lines.push(tarr);
}
}
// alert(lines);
}

http://jsfiddle.net/mblase75/dcqxr/

Javascript how to parse csv to create new columns

You can use a regular expression for that:

let rawData = "<ul>\
\n<li>Dimensions: 37 x 45,5 x 203,5(h) cm</li>\
\n<li>made of wood</li>\
\n</ul>"

console.log(rawData)

const regexp = /<li>(.*)<\/li>/g
const data = rawData.match(regexp).map(el => {
return el.replace(/<\/?li>/g, '')
})

console.log(data)
// Array [ "Dimensions: 37 x 45,5 x 203,5(h) cm", "made of wood" ]

Parse the data read from csv file with Nodejs ExcelJS package

I prepared example, how could you pare your file. As it was proposed in one answer above we use fast-csv. The parsing is quite simple you split by separator and than took line[0] which is first element.

const fs = require('fs');
const csv = require('@fast-csv/parse');

fs.createReadStream('Test_12345.csv')
.pipe(csv.parse())
.on('error', error => console.error(error))
.on('data', function (row) {
var line = String(row)
line = line.split(';')
console.log(`${line[0]}`)

})
.on('end', rowCount => console.log(`Parsed ${rowCount} rows`));

If we put for input like this:

Value1;1101;
Value2;2202;
Value3;3303;
Value4;4404;

your output is in this case like this:

Value1
Value2
Value3
Value4

How to parse CSV correctly for Puppeteer to fill strings from CSV lines to text input on website?

As you have noticed, the CSV parser is asynchronous. "asynchronous" means you can't do this:

var upcData=[];                               // 1
fs.createReadStream('Book_Bulk.csv') // 2
.pipe(parse({delimiter: ':'}))
.on('data', (csvrow) { // 5 6 7 8 9
upcData.push(+csvrow.CODECONTENT);
})
.on('end',function() { // 10
console.log(upcData);
});
}
console.log(upcData); // 3
// call puppeteer or whatever // 4

I've outlined the order of execution. The last console.log() runs immediately after you set up the read stream. upcData will not contain anything at this point.

But it will contain data at point #10, and #5 etc will fill it.

That means: Whatever you want to do with upcData, do it inside the 'end' event handler.

    .on('end',function() {                    // 10
console.log(upcData);
for (let upc of upcData) {
// call puppeteer or whatever
}
});

Since csv reader will give you one row per data event, you can also do things directly in the data event handler and not build an upcData array at all.

    .on('data', (csvrow) {                    // 5 6 7 8 9
const upc = +csvrow.CODECONTENT;
// call puppeteer or whatever
})

If you want to be able to await the whole thing, you must turn it into a promise first. In this case again the relevant step (promise resolution) happens in the end callback:

function readCsvAsync(filename, delimiter=',', encoding='utf-8') {
return new Promise((resolve, reject) => {
const rows = [];
try {
fs.createReadStream(filename, {encoding: encoding})
.pipe(parse({delimiter: delimiter}))
.on('data', (row) => rows.push(row))
.on('end', () => resolve(rows))
.on('error', reject);
} catch (err) {
reject(err);
}
});
}

async function main() {
try {
const rows = await readCsvAsync('Book_Bulk.csv', ':');
// call puppeteer or whatever
} catch (err) {
console.log(err);
}
}

Parse csv using csv-parser node JS

Why is that?

It's because createReadStream is working asynchronously and when you console.log(birthdays); outside, the code execution reads the log before createReadStream has finished processing

how can I solve it?

You were correct to put it inside the .on("end")

const birthdays = [];  
fs.createReadStream('./data/groupes.csv')
.pipe(csv({}))
.on('data', (data) => birthdays.push(data))
.on('end', () => {
console.log(birthdays);
// further processing with birthdays
});


Related Topics



Leave a reply



Submit