NodeJS 使用json2csv将大量对象转换为csv

xmd2e60i  于 2022-12-12  发布在  Node.js
关注(0)|答案(1)|浏览(232)

我需要将一个大的JSON数组(可以有超过100k个位置)转换为CSV。这个数组是直接在应用程序中创建的,它不是上传文件的结果。
查看documentation,我曾考虑过使用解析器,但它显示:
For that reason is rarely a good reason to use it until your data is very small or your application doesn't do anything else.
因为数据不小,我的应用程序将做其他事情,而不是创建csv,我不认为这将是最好的方法,但我可能误解了文档。
是否可以对已经创建的数据(而不是数据流)使用其他选项(async parser或transform)?

仅供参考:这是一个嵌套应用程序,但我使用的是node.js库。
更新:我试着用一个超过300k位的数组插入,结果很顺利。

iyr7buue

iyr7buue1#

为什么需要任何外部模块?使用原生JSON.parse()函数将JSON转换为javascript对象的javascript数组是小菜一碟。

let jsontxt=await fs.readFile('mythings.json','uft8');
    let mythings = JSON.parse(jsontxt);
    if (!Array.isArray(mythings)) throw "Oooops, stranger things happen!"

然后,将javascript数组转换为CSV非常简单。最明显和荒谬的情况是将数组的每个元素Map为一个字符串,该字符串是对象元素的JSON表示。最终得到的是一个无用的CSV,其中只有一列包含原始数组的每个元素。然后将得到的字符串数组连接为一个字符串。用换行符\n分隔。它没有什么用处,但是,见鬼,它是一个CSV!

let csvtxt = mythings.map(JSON.stringify).join("\n");
 await fs.writeFile("mythings.csv",csvtxt,"utf8");

现在,你可以感觉到你 * 几乎 * 在那里。把无用的Map函数替换成你自己的

let csvtxt = mythings.map(mapElementToColumns).join("\n");

并在数组对象的字段和csv的列之间选择一个良好的Map。

function mapElementToColumns(element) {
   return `${JSON.stringify(element.id)},${JSON.stringify(element.name)},${JSON.stringify(element.value)}`;
 }

或者更彻底地说

function mapElementToColumns(fieldNames) {
    return function (element) {
      let fields = fieldnames.map(n => element[n] ? JSON.stringify(element[n]) : '""');
      return fields.join(',');
    }
  }

可以在Map中调用

mythings.map(mapElementToColumns(["id","name","element"])).join("\n");

最后,您可能决定对“所有对象中的所有字段”使用自动化方法;这要求原始数组中的所有对象都维护一个类似的字段模式。
提取数组第一个对象的所有字段,并将它们用作csv * 的标题行,* 用作提取其余元素的模板。

let fieldnames = Object.keys(mythings[0]);

然后使用此字段名称数组作为map函数的参数

let csvtxt= mythings.map(mapElementToColumns(fieldnames)).join("\n");

并将其作为CSV头预先添加

csvtxt.unshift(fieldnames.join(','))

把所有的碎片拼在一起...

function mapElementToColumns(fieldNames) {
  return function (element) {
    let fields = fieldnames.map(n => element[n] ? JSON.stringify(element[n]) : '""');
    return fields.join(',');
  }
}

let jsontxt=await fs.readFile('mythings.json','uft8');
let mythings = JSON.parse(jsontxt);
if (!Array.isArray(mythings)) throw "Oooops, stranger things happen!";
let fieldnames = Object.keys(mythings[0]);
let csvtxt= mythings.map(mapElementToColumns(fieldnames)).join("\n");
csvtxt.unshift(fieldnames.join(','));
await fs.writeFile("mythings.csv",csvtxt,"utf8");

就这样,很漂亮吧?

相关问题