繁体   English   中英

Node.js中的大型CSV到JSON / Object

[英]Large CSV to JSON/Object in Node.js

我正在尝试做一些似乎不仅要完成相当简单的事情,而且要做一个足够普通的任务,以便有可用的简单包。 我希望获取一个大型CSV文件(从关系数据库表导出)并将其转换为JavaScript对象数组。 此外,我想将其导出到.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},
...
]

我已经尝试了几个节点CSV解析器,流式传输器,自称为CSV到JSON的库,但我似乎无法得到我想要的结果,或者如果我能它只能在文件较小的情况下工作。 我的文件大小接近1 GB,行数约为40 m(可创建40 m对象)。 我希望它需要流输入和/或输出以避免内存问题。

以下是我尝试过的软件包:

我正在使用Node 0.10.6,并希望了解如何轻松完成此操作。 滚动我自己可能是最好的,但我不知道从哪里开始使用Node的所有流功能,特别是因为他们在0.10.x中更改了API。

检查node.js csvtojson模块,该模块可用作库,命令行工具或Web服务器插件。 https://www.npmjs.org/package/csvtojson 源代码可以在https://github.com/Keyang/node-csvtojson找到

或从NPM回购安装:

npm install -g csvtojson

它支持任何大小的csv数据/字段类型/嵌套的json等。一堆功能。

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

var csvConverter=new Converter({constructResult:false, toArrayString:true}); // The constructResult parameter=false will turn off final result construction in memory for stream feature. toArrayString will stream out a normal JSON array object.

var readStream=require("fs").createReadStream("inputData.csv"); 

var writeStream=require("fs").createWriteStream("outpuData.json");

readStream.pipe(csvConverter).pipe(writeStream);

您还可以将其用作cli工具:

csvtojson myCSVFile.csv

虽然这远不是​​一个完整的答案,但您可以将您的解决方案建立在https://github.com/dominictarr/event-stream上 自述文件中的改编示例:

    var es = require('event-stream')
    es.pipeline(                         //connect streams together with `pipe`
      process.openStdin(),              //open stdin
      es.split(),                       //split stream to break on newlines
      es.map(function (data, callback) { //turn this async function into a stream
        callback(null
          , JSON.stringify(parseCSVLine(data)))  // deal with one line of CSV data
      }), 
      process.stdout
      )

在那之后,我希望你在每一行都有一堆字符串化的JSON对象。 这就需要将其转换为一个数组,你可能能够做的和追加,以结束每一行,在最后删除它,然后添加[]来开始和文件的末尾。

必须配置parseCSVLine函数以将CSV值分配给正确的对象属性。 在传递文件的第一行之后,这可以相当容易地完成。

我注意到库没有在0.10上测试过(至少没有用Travis测试),所以要小心。 也许你自己在源代码上运行npm test

我发现使用csvtojson读取csv数据更简单的方法。

这是代码:

 var Converter = require("csvtojson").Converter; var converter = new Converter({}); converter.fromFile("sample.csv",function(err,result){ var csvData = JSON.stringify ([ {resultdata : result[0]}, {resultdata : result[1]}, {resultdata : result[2]}, {resultdata : result[3]}, {resultdata : result[4]} ]); csvData = JSON.parse(csvData); console.log(csvData); }); 

或者您可以轻松地执行此操作:

 var Converter = require("csvtojson").Converter; var converter = new Converter({}); converter.fromFile("sample.csv",function(err,result){ console.log(result); }); 

这是第一个代码的结果:

 [ { resultdata: { 'Header 1': 'A_1', 'Header 2': 'B_1', 'Header 3': 'C_1', 'Header 4': 'D_1', 'Header 5': 'E_1' } }, { resultdata: { 'Header 1': 'A_2', 'Header 2': 'B_2', 'Header 3': 'C_2', 'Header 4': 'D_2', 'Header 5': 'E_2' } }, { resultdata: { 'Header 1': 'A_3', 'Header 2': 'B_3', 'Header 3': 'C_3', 'Header 4': 'D_3', 'Header 5': 'E_3' } }, { resultdata: { 'Header 1': 'A_4', 'Header 2': 'B_4', 'Header 3': 'C_4', 'Header 4': 'D_4', 'Header 5': 'E_4' } }, { resultdata: { 'Header 1': 'A_5', 'Header 2': 'B_5', 'Header 3': 'C_5', 'Header 4': 'D_5', 'Header 5': 'E_5' } } ] 

此代码的来源位于: https//www.npmjs.com/package/csvtojson#installation

我希望你有所了解。

我建议你自己实现逻辑。 Node.js实际上非常擅长这类任务。

以下解决方案是使用流,因为它们不会炸毁你的记忆。

安装依赖项

npm install through2 split2 --save

import through2 from 'through2'
import split2 from 'split2'

fs.createReadStream('<yourFilePath>')
  // Read line by line
  .pipe(split2())
  // Parse CSV line
  .pipe(parseCSV()) 
  // Process your Records
  .pipe(processRecord()) 

const parseCSV = () => {
  let templateKeys = []
  let parseHeadline = true
  return through2.obj((data, enc, cb) => {
    if (parseHeadline) {
      templateKeys = data
        .toString()
        .split(';')
      parseHeadline = false
      return cb(null, null)
    }
    const entries = data
      .toString()
      .split(';')
    const obj = {}
    templateKeys.forEach((el, index) => {
      obj[el] = entries[index]
    })
    return cb(null, obj)
  })
}

const processRecord = () => {
  return through2.obj(function (data, enc, cb) {
    // Implement your own processing 
    // logic here e.g.:
    MyDB
      .insert(data)
      .then(() => cb())
      .catch(cb)
  })
}

有关此主题的更多信息,请访问Stefan Baumgartners关于此主题的优秀教程

您可以使用流来处理大文件。 这是你需要做的。 这应该工作得很好。

npm i --save csv2json fs-extra // install the modules

const csv2json = require('csv2json');
const fs = require('fs-extra');

const source = fs.createReadStream(__dirname + '/data.csv');
const output = fs.createWriteStream(__dirname + '/result.json');
 source
   .pipe(csv2json())
   .pipe(output );

嗯......很多解决方案,我将再添加一个scramjet

$ npm install --save scramjet

然后

process.stdin.pipe(
    new (require("scramjet").StringStream)("utf-8")
)
    .CSVParse()
    .toJSONArray()
    .pipe(process.stdout)

这将导致您以流式方式描述的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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