简体   繁体   English

如何使用 Node.js 将 JSON 数组转换为 CSV?

[英]How to convert JSON array to CSV using Node.js?

I want to convert json which has value array.我想转换具有值数组的 json 。 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 的建议。

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-csvhttps://github.com/wdavidw/node-csvhttps://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!');
    }
  });
});

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.json in 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.parse method:无论您是从本地文件读取 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 EDIT BELOW请参阅下面的编辑

/* 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 .map and .join on the child arrays.虽然前面的代码肯定有效,但没有必要在子数组上使用.map.join As @Relu demonstrates , a single .join on the parent array is sufficient because JavaScript will automatically convert the child arrays into comma-separated strings by default since .join must return a string and cannot contain any child arrays.正如@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.我喜欢在我的 Node.js 脚本中添加大量的console.log()消息。

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!');
});

After several hours trying to use the library and I ended up write my own.在尝试使用该库几个小时后,我最终编写了自己的库。 https://github.com/KhanhPham2411/simple-node-csv https://github.com/KhanhPham2411/simple-node-csv

import { SimpleNodeCsv } from './simple-node-csv';

SimpleNodeCsv.obj2csv({a: 1, b:2}, ",");

// output
// "a","b"
// 1,2

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');
  });
});

https://github.com/kauegimenes/jsonexport https://github.com/kauegimenes/jsonexport

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  "

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

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