[英]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.