如何在Node.js中将CSV转换为JSON


68

我正在尝试将csv文件转换为json。我在用 。

CSV示例:

a,b,c,d
1,2,3,4
5,6,7,8
...

所需的JSON:

{"a": 1,"b": 2,"c": 3,"d": 4},
{"a": 5,"b": 6,"c": 7,"d": 8},
...

我尝试了node-csv解析器库。但是输出类似于数组,与我预期的不一样。

我正在使用Node 0.8和express.js,希望就如何轻松实现这一目标提出建议。



:我写了一个类似的解决方案小型博客中所建议的brnrd thinkingonthinking.com/scripting-a-csv-converter
poseid

Answers:


93

Node.jscsvtojson模块是一个全面的nodejs csv解析器。它可以用来作为Node.js的应用程序库/命令行工具/或与帮助浏览器browserifywebpack

可以在以下位置找到源代码:https : //github.com/Keyang/node-csvtojson

它运行速度快,内存消耗低,但功能强大,具有丰富的API和易于阅读的文档,可满足任何分析需求。

详细的文档可以在这里找到

以下是一些代码示例:

将其用作Node.js应用程序(csvtojson@2.0.0 +)中的库:

  1. 通过安装 npm

npm install --save csvtojson@latest

  1. 在您的node.js应用中使用它:
// require csvtojson
var csv = require("csvtojson");

// Convert a csv file with csvtojson
csv()
  .fromFile(csvFilePath)
  .then(function(jsonArrayObj){ //when parse finished, result will be emitted here.
     console.log(jsonArrayObj); 
   })

// Parse large csv with stream / pipe (low mem consumption)
csv()
  .fromStream(readableStream)
  .subscribe(function(jsonObj){ //single json object will be emitted for each csv line
     // parse each json asynchronousely
     return new Promise(function(resolve,reject){
         asyncStoreToDb(json,function(){resolve()})
     })
  }) 

//Use async / await
const jsonArray=await csv().fromFile(filePath);

将其用作命令行工具:

sh# npm install csvtojson
sh# ./node_modules/csvtojson/bin/csvtojson ./youCsvFile.csv

-要么-

sh# npm install -g csvtojson
sh# csvtojson ./yourCsvFile.csv

对于高级用法:

sh# csvtojson --help

您可以从上面的github页面找到更多详细信息。


代码已添加。在这里看到更详细的文档github.com/Keyang/node-csvtojson
科阳

从0.3.0版开始,csvtojson不依赖于任何其他库。它的行为就像一个适当的Stream对象。
Keyang

博客链接已死。
E. Maggini 2014年

更新。谢谢你让我知道。
Keyang

我不知道这是否仅发生在我身上,但是对于大型CSV文件,这会变慢。好像比d3慢10秒
limoragni

22

您可以尝试使用underscore.js

首先使用toArray函数转换数组中的行:

var letters = _.toArray(a,b,c,d);
var numbers = _.toArray(1,2,3,4);

然后使用对象函数将数组对象在一起:

var json = _.object(letters, numbers);

届时,json var应该包含类似以下内容:

{"a": 1,"b": 2,"c": 3,"d": 4}

12

这是不需要单独模块的解决方案。但是,它非常粗糙,并且没有实现太多错误处理。它还可以使用更多测试,但可以助您一臂之力。如果要解析非常大的文件,则可能需要寻找替代方法。另外,请参见Ben Nadel的解决方案

节点模块代码csv2json.js:

/*
 * Convert a CSV String to JSON
 */
exports.convert = function(csvString) {
    var json = [];
    var csvArray = csvString.split("\n");

    // Remove the column names from csvArray into csvColumns.
    // Also replace single quote with double quote (JSON needs double).
    var csvColumns = JSON
            .parse("[" + csvArray.shift().replace(/'/g, '"') + "]");

    csvArray.forEach(function(csvRowString) {

        var csvRow = csvRowString.split(",");

        // Here we work on a single row.
        // Create an object with all of the csvColumns as keys.
        jsonRow = new Object();
        for ( var colNum = 0; colNum < csvRow.length; colNum++) {
            // Remove beginning and ending quotes since stringify will add them.
            var colData = csvRow[colNum].replace(/^['"]|['"]$/g, "");
            jsonRow[csvColumns[colNum]] = colData;
        }
        json.push(jsonRow);
    });

    return JSON.stringify(json);
};

茉莉花测试,csv2jsonSpec.js:

var csv2json = require('csv2json.js');

var CSV_STRING = "'col1','col2','col3'\n'1','2','3'\n'4','5','6'";
var JSON_STRING = '[{"col1":"1","col2":"2","col3":"3"},{"col1":"4","col2":"5","col3":"6"}]';

/* jasmine specs for csv2json */
describe('csv2json', function() {

    it('should convert a csv string to a json string.', function() {
        expect(csv2json.convert(CSV_STRING)).toEqual(
                JSON_STRING);
    });
});

这个功能不如csvtojson好。当我有“ 2016年8月23日”时,它将aug23和2016年划分为不同的字段
MrWiLofDoom

笨蛋 您可以将日期用引号引起来解决吗?
杰西

12

不得不做类似的事情,希望这会有所帮助。

// Node packages for file system
var fs = require('fs');
var path = require('path');


var filePath = path.join(__dirname, 'PATH_TO_CSV');
// Read CSV
var f = fs.readFileSync(filePath, {encoding: 'utf-8'}, 
    function(err){console.log(err);});

// Split on row
f = f.split("\n");

// Get first row for column headers
headers = f.shift().split(",");

var json = [];    
f.forEach(function(d){
    // Loop through each row
    tmp = {}
    row = d.split(",")
    for(var i = 0; i < headers.length; i++){
        tmp[headers[i]] = row[i];
    }
    // Add object to list
    json.push(tmp);
});

var outPath = path.join(__dirname, 'PATH_TO_JSON');
// Convert object to string, write json to file
fs.writeFileSync(outPath, JSON.stringify(json), 'utf8', 
    function(err){console.log(err);});

甚至var json = f.map(function(d, i){ ... return tmp; }
arve0

4

使用lodash

function csvToJson(csv) {
  const content = csv.split('\n');
  const header = content[0].split(',');
  return _.tail(content).map((row) => {
    return _.zipObject(header, row.split(','));
  });
}

调整方案:我添加.MAP(函数(STR){返回_.trim(STR,“'),从头部和数据项删除任何双引号,即const header = content[0].split(',').map(function(str) { return _.trim(str, '"'); });return _.zipObject(header, row.split(',').map(function(str) { return _.trim(str, '"'); }));
CharlesA


3

我从node-csvtojson开始,但是它给我的链接带来了太多的依赖。

基于brnd的问题和答案,我使用了node-csvunderscore.js

var attribs;
var json:
csv()
    .from.string(csvString)
    .transform(function(row) {
        if (!attribs) {
            attribs = row;
            return null;
        }
        return row;
     })
    .to.array(function(rows) {
        json = _.map(rows, function(row) {
            return _.object(attribs, row);
        });
     });

异步和下划线对您来说太多了吗?
斯宾塞

3
@Spencer,在我发布之时,依赖关系有所不同:github.com/Keyang/node-csvtojson/blob/…进行express进行csv转换感到不自然
xverges 2015年

哦,是的,这是一个疯狂的依赖。我的错。
斯宾塞

2

我有一个非常简单的解决方案,可以使用csvtojson模块从控制台上的csv打印json。

// require csvtojson
var csv = require("csvtojson");

const csvFilePath='customer-data.csv' //file path of csv
csv()
.fromFile(csvFilePath)``
.then((jsonObj)=>{
    console.log(jsonObj);
})

1

Node-ETL软件包足以用于所有BI处理。

npm install node-etl; 

然后 :

var ETL=require('node-etl');
var output=ETL.extract('./data.csv',{
              headers:["a","b","c","d"],
              ignore:(line,index)=>index!==0, //ignore first line
 });

与该库的链接已死-也许它已移至Github上的其他位置(或已分叉?)。请更新链接。
最高

谢谢@RohitParte。这是我在NodeJ中的第一个模块之一。虽然某些功能可以正常使用,但缺少许多功能。我变得非常忙于其他事情(可靠性工程,DevOps等)。
Abdennour TOUMI

1

我已经使用csvtojson库将csv字符串转换为json数组。它具有多种功能,可以帮助您转换为JSON。
它还支持读取文件和文件流。

解析可能包含comma(,)或任何其他定界符的csv时要小心。要删除定界符,请在此处查看我的答案。


1

第1步:

安装节点模块:npm install csvtojson --save

第2步:

var Converter = require("csvtojson").Converter;

var converter = new Converter({});

converter.fromFile("./path-to-your-file.csv",function(err,result){

    if(err){
        console.log("Error");
        console.log(err);  
    } 
    var data = result;

    //to check json
    console.log(data);
});

1

如果你想只是一个命令行转换,对我来说最快捷,最干净的解决方案是使用csvtojson通过NPX(默认情况下在node.js中包括)

$ npx csvtojson ./data.csv > data.json


1

使用ES6

const toJSON = csv => {
    const lines = csv.split('\n')
    const result = []
    const headers = lines[0].split(',')

    lines.map(l => {
        const obj = {}
        const line = l.split(',')

        headers.map((h, i) => {
            obj[h] = line[i]
        })

        result.push(obj)
    })

    return JSON.stringify(result)
}

const csv = `name,email,age
francis,francis@gmail.com,33
matty,mm@gmail.com,29`

const data = toJSON(csv)

console.log(data)

输出量

// [{"name":"name","email":"email","age":"age"},{"name":"francis","email":"francis@gmail.com","age":"33"},{"name":"matty","email":"mm@gmail.com","age":"29"}]


0

使用csv解析器库,我在这里详细说明如何使用它。

var csv = require('csv');
csv.parse(csvText, {columns: true}, function(err, data){
    console.log(JSON.stringify(data, null, 2));
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.