如何使用 Node.js 将 JSON 数组转换为 CSV?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38244285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert JSON array to CSV using Node.js?
提问by arjun kori
I want to convert json which has value array. response.json
我想转换具有值数组的json。 响应文件
{
"rows": [
[
"New Visitor",
"(not set)",
"(not set)",
"0"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile",
]
]
}
Now i want to convert this data into. name.csv
现在我想将这些数据转换成。 名称.csv
"New Visitor","(not set)","(not set)","0"
"New Visitor","(not set)","(not set)","mobile"
"New Visitor","(not set)","(not set)","mobile"
"New Visitor","(not set)","(not set)","mobile"
Please give me suggetions using Node.js.
请给我使用 Node.js 的建议。
回答by Relu Mesaros
Do it yourself like this:
像这样自己做:
'use strict';
var fs = require('fs');
let myObj = {
"rows": [
[
"New , Visitor",
"(not set)",
"(not set)",
"0"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile",
]
]
}
// 1. One way - if you want the results to be in double quotes and you have comas inside
// choose another string to temporally replace commas if necessary
let stringToReplaceComas = '!!!!';
myObj.rows.map((singleRow) => {
singleRow.map((value, index) => {
singleRow[index] = value.replace(/,/g, stringToReplaceComas);
})
})
let csv = `"${myObj.rows.join('"\n"').replace(/,/g, '","')}"`;
// // or like this
// let csv = `"${myObj.rows.join('"\n"').split(',').join('","')}"`;
csv = csv.replace(new RegExp(`${stringToReplaceComas}`, 'g'), ',');
// // 2. Another way - if you don't need the double quotes in the generated csv and you don't have comas in rows' values
// let csv = myObj.rows.join('\n')
fs.writeFile('name.csv', csv, 'utf8', function(err) {
if (err) {
console.log('Some error occured - file either not saved or corrupted file saved.');
} else {
console.log('It\'s saved!');
}
});
Use libraries
使用库
ex. https://github.com/mrodrig/json-2-csv, https://github.com/wdavidw/node-csv, https://github.com/wdavidw/node-csv-stringify
前任。https://github.com/mrodrig/json-2-csv,https://github.com/wdavidw/node-csv,https://github.com/wdavidw/node-csv-stringify
an example using json-2-csv (https://github.com/mrodrig/json-2-csv)
使用 json-2-csv 的示例(https://github.com/mrodrig/json-2-csv)
'use strict';
const converter = require('json-2-csv');
let myObj = {
"rows": [
{
value1: "New Visitor",
value2: "(not set)",
value3: "(not set)",
value4: "0"
},
{
value1: "New Visitor",
value2: "(not set)",
value3: "(not set)",
value4: "mobile"
},
{
value1: "New Visitor",
value2: "(not set)",
value3: "(not set)",
value4: "mobile"
},
{
value1: "New Visitor",
value2: "(not set)",
value3: "(not set)",
value4: "mobile",
}
]
}
let json2csvCallback = function (err, csv) {
if (err) throw err;
fs.writeFile('name.csv', csv, 'utf8', function(err) {
if (err) {
console.log('Some error occured - file either not saved or corrupted file saved.');
} else {
console.log('It\'s saved!');
}
});
};
converter.json2csv(myObj.rows, json2csvCallback, {
prependHeader: false // removes the generated header of "value1,value2,value3,value4" (in case you don't want it)
});
an example using csv-stringify (https://github.com/wdavidw/node-csv-stringify)
使用 csv-stringify 的示例(https://github.com/wdavidw/node-csv-stringify)
'use strict';
var stringify = require('csv-stringify');
var fs = require('fs');
let myObj = {
"rows": [
[
"New Visitor",
"(not set)",
"(not set)",
"0"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile",
]
]
}
stringify(myObj.rows, function(err, output) {
fs.writeFile('name.csv', output, 'utf8', function(err) {
if (err) {
console.log('Some error occured - file either not saved or corrupted file saved.');
} else {
console.log('It\'s saved!');
}
});
});
回答by gfullam
Three easy steps: Read. Convert. Write.
三个简单的步骤:阅读。转变。写。
Step 1: Read.
第一步:阅读。
If you need to read the JSON from a file (as indicated by your inclusion of the filename response.jsonin your post), you will require the Node.js FileSystem API:
如果您需要从文件中读取 JSON(如您response.json在帖子中包含文件名所示),您将需要Node.js FileSystem API:
const fs = require('fs'); // Require Node.js FileSystem API.
const JSONFile = fs.readFileSync('response.json'); // Read the file synchronously.
Note: If you prefer, you can read the file asynchronously with fs.readFile()and perform the conversion in a callback function.
注意:如果您愿意,您可以异步读取文件fs.readFile()并在回调函数中执行转换。
Step 2: Convert.
第 2 步:转换。
Whether you read your JSON from a local file or GET it from a server, you will need to parse it into a Plain Old JavaScript Object first using the JSON.parsemethod:
无论您是从本地文件读取 JSON 还是从服务器获取它,您都需要首先使用以下JSON.parse方法将其解析为普通的旧 JavaScript 对象:
const JSONasPOJO = JSON.parse(JSONFile); // Parse JSON into POJO.
Then perform a series of joins on the child arrays and parent array:
SEE EDITBELOW
然后的子阵列和父阵列加入上执行一系列:
SEE EDITBELOW
/* THIS IS UNNECESSARY FOR "COMMA" SEPARATED VALUES
const CSVString = JSONasPOJO
.rows // Get `rows`, which is an array.
.map( // Map returns a new array.
row => row.join(',') // Each child array becomes a comma-separated string.
)
.join('\n'); // Parent array becomes a newline-separated string...
// ...of comma-separated strings.
// It is now a single CSV string!
*/
EDIT:
编辑:
While the previous code certainly works, it is unnecessary to use .mapand .joinon the child arrays. As @Relu demonstrates, a single .joinon the parent array is sufficient because JavaScript will automatically convert the child arrays into comma-separated strings by default since .joinmust return a string and cannot contain any child arrays.
虽然前面的代码确实有效,但没有必要在子数组上使用.map和.join。正如@Relu 演示的那样,.join父数组上的单个数组就足够了,因为默认情况下 JavaScript 会自动将子数组转换为逗号分隔的字符串,因为它.join必须返回一个字符串并且不能包含任何子数组。
You could use the above pattern if you want to join the child arrays with something other than a comma.
如果你想用逗号以外的东西连接子数组,你可以使用上面的模式。
Otherwise:
除此以外:
var CSVString = JSONasPOJO.rows.join('\n'); // Array becomes a newline-separated...
// ...string of comma-separated strings.
// It is now a single CSV string!
Here, we can see that conversion in action:
在这里,我们可以看到这种转换在起作用:
const JSONasPOJO = {
"rows": [
[
"New Visitor",
"(not set)",
"(not set)",
"0"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile"
],
[
"New Visitor",
"(not set)",
"(not set)",
"mobile" // NOTE: Here I removed a trailing comma,
// ...which is invalid JSON!
]
]
}
const CSVString = JSONasPOJO.rows.join('\n');
console.log(CSVString);
Step 3: Write.
第三步:写。
Using the FileSystem API again, write to a file, and log an error or a success message:
再次使用 FileSystem API,写入文件,并记录错误或成功消息:
fs.writeFile('name.csv', CSVString, err => {
if (err) return console.log(err);
console.log('FILE SUCCESSFULLY WRITTEN!\n');
});
Note: Here, I demonstrate the asynchronous pattern using a callback to log my error and success messages. If you prefer, you can write the file synchronously with fs.writeFileSync().
注意:在这里,我演示了使用回调记录我的错误和成功消息的异步模式。如果您愿意,可以使用fs.writeFileSync().
Putting it all together
把这一切放在一起
I like to add plenty of console.log()messages to my Node.js scripts.
我喜欢在console.log()我的 Node.js 脚本中添加大量消息。
const fs = require('fs');
const inFilename = 'response.json',
outFilename = 'name.csv';
console.log(`Preparing to read from ${inFilename} …`);
const JSONContents = fs.readFileSync(inFilename);
console.log(`READ:\n${JSONContents}`);
console.log('Preparing to parse as JSON …');
const JSONasPOJO = JSON.parse(JSONContents);
console.log(`PARSED:\n${JSONasPOJO}`);
console.log('Preparing to convert into CSV …');
const CSVString = JSONasPOJO.rows.join('\n');
console.log(`CONVERTED:\n${CSVString}`);
console.log(`Preparing to write to ${outFilename} …`);
fs.writeFile(outFilename, CSVString, err => {
if (err) return console.error(err);
console.log('FILE SUCCESSFULLY WRITTEN!');
});
回答by Kauê Gimenes
I don't know about you guys, but i like small packages that just work as expected without a lot of extra configuration, try using jsonexport, i think its the best module for this, works really well with objects, arrays, .. and its fast!
我不了解你们,但我喜欢无需大量额外配置即可按预期工作的小包,尝试使用 jsonexport,我认为它是最好的模块,适用于对象、数组等。它很快!
Install
安装
npm i --save jsonexport
Usage
用法
const jsonexport = require('jsonexport');
const fs = require('fs');
jsonexport([{
value1: "New Visitor",
value2: "(not set)",
value3: "(not set)",
value4: "0"
},
{
value1: "New Visitor",
value2: "(not set)",
value3: "(not set)",
value4: "mobile"
},
{
value1: "New Visitor",
value2: "(not set)",
value3: "(not set)",
value4: "mobile"
},
{
value1: "New Visitor",
value2: "(not set)",
value3: "(not set)",
value4: "mobile",
}], function(err, csv) {
if (err) return console.error(err);
fs.writeFile('output.csv', csv, function(err) {
if (err) return console.error(err);
console.log('output.csv saved');
});
});
回答by Manuel Spigolon
I would like to share the easiest way to build a csv string from a json array:
我想分享从 json 数组构建 csv 字符串的最简单方法:
const data = [
{ a: 1, b: new Date(), c: 'a text' },
{
a: 1, b: new Date(), c: `string
with
return
carrier
and emoji
`
}
]
const header = Object.keys(data[0]).map(_ => JSON.stringify(_)).join(';') + '\n'
const outData = data.reduce((acc, row) => {
return acc + Object.values(row).map(_ => JSON.stringify(_)).join(';') + '\n'
}, header)
console.log(outData)
Will print this string:
将打印此字符串:
"a";"b";"c"
1;"2020-03-25T08:49:04.280Z";"a text"
1;"2020-03-25T08:49:04.280Z";"string\n with\n return\n carrier\n and emoji \n "

