简体   繁体   中英

How to parse CSV file in NodeJS

I have a Task.csv file with the following content:

task1,01/05/2020, 20/05/2020, Active
task2,03/05/2020, 17/05/2020, Active
task3,10/05/2020, 25/05/2020, Active
task4,02/05/2020, 21/05/2020, Active
task5,07/05/2020, 28/05/2020, Active

I want to parse this in JavaScript (NodeJS) and display each line read surrounded by brackets. The following is the code I'm using:

function readCsvFile()
{
    var fs = require('fs');
    var textByLine = fs.readFileSync('Tasks.csv').toString().split("\n");   
    var i;<br>

    for (i=0; i<textByLine.length; i++)
    {
        console.log("[" + textByLine[i] + "]");
    }
}

What I expect:

[task1,01/05/2020, 20/05/2020, Active]
[task2,03/05/2020, 17/05/2020, Active]
[task3,10/05/2020, 25/05/2020, Active]
[task4,02/05/2020, 21/05/2020, Active]
[task5,07/05/2020, 28/05/2020, Active]

When I run it, the output is:

]task1,01/05/2020, 20/05/2020, Active
]task2,03/05/2020, 17/05/2020, Active
]task3,10/05/2020, 25/05/2020, Active
]task4,02/05/2020, 21/05/2020, Active
[task5,07/05/2020, 28/05/2020, Active]

I'm new to JavaScript and NodeJS so any comment would be helpful, thanks.

Do not read file synchronously. You can use the built-in module readline to read a file line by line and process each line where you don't have to worry about CLRF. Alternatively use a module like fast-csv has many features.

fast-csv

const fs = require('fs');
const path = require('path');
const csv = require('fast-csv');

fs.createReadStream('Tasks.csv'))
    .pipe(csv.parse({ headers: true }))
    .on('error', error => console.error(error))
    .on('data', row => console.log(row))
    .on('end', rowCount => console.log(`Parsed ${rowCount} rows`));

Readline

   const readline = require('readline');
    const fs = require('fs');

    cost lineReader = readline.createInterface({
      input: fs.createReadStream('Tasks.csv')
    });

    let lineno = 0;
    lineReader.on('line', function (line) {
         lineno++
       // process line here
       // let colValues=  line.split(",") 
    });

   lineReader.on('close', () => {
    console.log('Done reading file');
   });

Please try like this

function readCsvFile()
{
    var fs = require("fs");
    var textByLine = fs.readFileSync("Tasks.csv").toString().split("\n");
    console.log(textByLine);
    const res = textByLine.map((line) => line.split(","));
    console.log(res)
}

output

[["task1","01/05/2020"," 20/05/2020"," Active\r"],
 ["task2","03/05/2020"," 17/05/2020"," Active\r"],
 ["task3","10/05/2020"," 25/05/2020"," Active\r"],
 ["task4","02/05/2020"," 21/05/2020"," Active\r"],
 ["task5","07/05/2020"," 28/05/2020"," Active"]]

To fix your code just use.split() method of Javascript to get the result in desired format. I have done a small change in your code and getting response the way you mentioned.

function readCsvFile() {
    var fs = require('fs');
    var textByLine = fs.readFileSync('data.csv').toString().split("\n");
    var i;
    for (i = 0; i < textByLine.length-1; i++) {
        console.log(textByLine[i].split("\t"))
    }
}

As much as it can be problematic to import node.js modules for trivial purposes, the parsing of CSV files has enough edge cases and gotchas for it to be better done but one that's well tested. The top result on NPM is this: https://www.npmjs.com/package/csv-parser

Using a module will also reduce the amount of fiddly and fragile code you'll have to maintain yourself.

Here's a link to the RFC for CSV files, which is the closest thing I know of to a standard for them: https://tools.ietf.org/html/rfc4180 Hopefully this will give you enough info about the edge cases I mention to appreciate the need to use a module instead.

Thanks for your feedback everyone. It solved my problem, I tried @PatrickEvans suggestion first. and it worked! Basically I should be using "\r\n" to split the file into individual lines as I created the CSV file in Windows.

So now this is the working code

function readCsvFile()
{

    var fs = require('fs');
    var textByLine = fs.readFileSync('Tasks.csv').toString().split("\r\n"); 
    var i;

    for (i=0; i<textByLine.length; i++)
    {
        console.log("[" + textByLine[i] + "]");
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM