【问题标题】:Node / Javascript : How to write out an array of key values pairs to a csv file, with the keys as the header?Node / Javascript:如何将键值对数组写入csv文件,键为标题?
【发布时间】:2019-12-25 19:40:19
【问题描述】:

使用 Node.js,如何从包含键值对的数组中写出 csv 文件?

这是我想写出的键/值对的示例数组。

function testWriteCsv() {
    const arr = []
    const kp1 = []
    const kp2 = []
    const kp3 = []

    kp1['FIRST_NAME'] = 'First Name1';
    kp1['LAST_NAME'] = 'First Name1';

    kp2['FIRST_NAME'] = 'First Name2';
    kp2['LAST_NAME'] = 'First Name2';

    kp3['FIRST_NAME'] = 'First Name3';
    kp3['LAST_NAME'] = 'First Name3';

    arr.push(kp1)
    arr.push(kp2)
    arr.push(kp3)

    console.log('arr', arr)

    // now I want to write out a .csv file of the above data, with header:
    // FIRST_NAME,LAST_NAME
}

我按照示例尝试使用以下库,但它们都不适用于键值对数组。

以下库都没有我可以传递键/值对数组并帮助写出 .csv 的函数。

我尝试使用以下库来扭曲数组、交互、做各种事情,但它们都不起作用。

fs
fast-csv
convert-array-to-csv
csv-writer

我会问,如果你以前做过,并且有一个完整的例子,请分享,将不胜感激。

谢谢。


更新:

这是一个解决方案的完整工作示例:

const fs = require('fs');

function testWriteCsv() {
    const arr = [];
    const kp1 = [];
    const kp2 = [];
    const kp3 = [];

    kp1['FIRST_NAME'] = 'First Name1';
    kp1['LAST_NAME'] = 'First Name1';

    kp2['FIRST_NAME'] = 'First Name2';
    kp2['LAST_NAME'] = 'First Name2';

    kp3['FIRST_NAME'] = 'First Name3';
    kp3['LAST_NAME'] = 'First Name3';

    arr.push(kp1);
    arr.push(kp2);
    arr.push(kp3);

    // 'output' will hold the full csv result to be written to file
    const headers = Object.keys(arr[0]);
    let output = headers.join() + '\n';

    for (let kv of arr) {
        let values = Object.values(kv).join() + '\n';
        output += values
    }

    // Write to a file
    fs.writeFile("test.csv", output, function (err) {
        if (err) return console.log(err);
        console.log("The file was saved!");
    });
}

testWriteCsv()

【问题讨论】:

    标签: javascript arrays node.js csv key-value


    【解决方案1】:

    使用您提到的其中一个库可能会做得更好,但我猜您的问题是将数组解构为可以保存到文件中的字符串,所以我留下一个简单的例子:

    // Required for writing into file (writeFile())
    const fs = require('fs');
    
    // Constructing the array (same as original)
    const arr = [];
    const kp1 = [];
    const kp2 = [];
    const kp3 = [];
    
    kp1['FIRST_NAME'] = 'First Name1';
    kp1['LAST_NAME'] = 'Last Name1';
    
    kp2['FIRST_NAME'] = 'First Name2';
    kp2['LAST_NAME'] = 'Last Name2';
    
    kp3['FIRST_NAME'] = 'First Name3';
    kp3['LAST_NAME'] = 'Last Name3';
    
    arr.push(kp1);
    arr.push(kp2);
    arr.push(kp3);
    
    // Output will hold the whole text, starting with the Header
    output = Object.keys(arr[0]).join(',') + '\n';
    
    // Add line by line to the output
    for(kp of arr) {
        output += Object.values(kp).join(',') + '\n';
    }
    
    // Write to a file
    fs.writeFile("test.csv", output, function(err) {
        if(err) return console.log(err);
        console.log("The file was saved!");
    }); 
    

    这将生成以下输出变量(并将其保存到文件中):

    FIRST_NAME,LAST_NAME
    First Name1,Last Name1
    First Name2,Last Name2
    First Name3,Last Name3
    

    如果这对您有用,您可以将逻辑拆分为单独的函数或使用您认为合适的库。

    // 编辑

    生成输出的老方法,供参考:

    // Get headers from the keys from the first child of the array (arr[0] would be kp1)
    let [col1, col2] = Object.keys(arr[0]);
    
    // Output will hold the whole text, starting with the Header
    output = col1 + ',' + col2 + '\n';
    
    // Add line by line to the output
    for(let i = 0; i < arr.length; i++) {
        output += arr[i][col1] + ',' + arr[i][col2] + '\n';
    }
    

    【讨论】:

    • 太棒了,我会试试这个。但是,有没有办法让任何库都可以从键/值对中的键生成标头? (而不是在变量输出中指定)?
    • 嗨,遗憾的是我不使用 javascript,所以我不知道库,但是你可以使用 keys() 方法从数组本身获取它们,但你不是定义的那个钥匙?如果不是这种情况,我可以添加如何从数组中获取它,但@Ayyub 的答案似乎是一个更好的选择。
    • 我修改了答案以使用您提到的 key() 方法从数组中获取键。祝你好运。
    • 太棒了,这行得通。我没有定义密钥。它被定义为数据库中的列名,由其他人创建(确定列名)。所以我查询数据库,读入一个键/值对,将每一行添加到一个数组中,然后我对数据进行一些处理,并希望将一些字段写入 .csv。对我来说,从数据库标题值中编码标题是有问题的,因为 db 列名可能会改变。修改后的代码我试试看,非常感谢。
    • 哦,我明白了,但是如果您从数据库中获取标题,然后自己创建数组,那么在某些时候您将列名保存在变量上,您可以使用那些除非我理解错了,但无论如何,上面的代码应该仍然有效。我仍然会考虑使用 json 结构而不是数组创建变量的可能性,然后使用 Yash 的建议,您可以创建一个关于如何形成 json 并显示获取数据时的一些代码的单独问题。不管怎样,当然是你的选择,很高兴我能帮上忙!
    【解决方案2】:

    您可以使用此代码传递键值对并将其转换为 CSV。

    需要库npm install jsonexport

    代码:

        var jsonexport = require('jsonexport');
    
        const arr = []
        const kp1 = {}
        const kp2 = {}
        const kp3 = {}
    
        kp1['FIRST_NAME'] = 'First Name1';
        kp1['LAST_NAME'] = 'First Name1';
    
        kp2['FIRST_NAME'] = 'First Name2';
        kp2['LAST_NAME'] = 'First Name2';
    
        kp3['FIRST_NAME'] = 'First Name3';
        kp3['LAST_NAME'] = 'First Name3';
    
        arr.push(kp1)
        arr.push(kp2)
        arr.push(kp3)
    
        console.log('arr', arr)
    
        jsonexport(arr,function(err, csv){
        if(err) return console.log(err);
        console.log(csv);
    });
    

    输出:

    FIRST_NAME,LAST_NAME
    First Name1,First Name1
    First Name2,First Name2
    First Name3,First Name3
    

    希望对你有帮助:)

    【讨论】:

    • 太好了,让我试试看。
    • 跟进。谢谢,但这没有用。如果您复制/粘贴键/值对数组并传递给函数:jsonexport(arr, ..., it prints nothing and fails. 在您给出的示例中,联系人不是示例(arr) 中给出的键值对数组。
    • 给我几分钟,我会解决的。如果您只是将 kP1 kp2 kp3 转换为具有 'kP1 = {}' 等其余 2 个,它将正常工作。将分享代码。
    • @user10664542 我已经更新了代码请看一下。
    【解决方案3】:

    csv-writer 库是为这种类型的用例而设计的。使用您的示例代码,您可以像这样使用csv-writer

    const createCsvWriter = require('csv-writer').createObjectCsvWriter
    
    function testWriteCsv() {
      const arr = []
      const kp1 = []
      const kp2 = []
      const kp3 = []
    
      kp1['FIRST_NAME'] = 'First Name1';
      kp1['LAST_NAME'] = 'First Name1';
    
      kp2['FIRST_NAME'] = 'First Name2';
      kp2['LAST_NAME'] = 'First Name2';
    
      kp3['FIRST_NAME'] = 'First Name3';
      kp3['LAST_NAME'] = 'First Name3';
    
      arr.push(kp1)
      arr.push(kp2)
      arr.push(kp3)
    
      console.log('arr', arr)
    
      // now I want to write out a .csv file of the above data, with header:
      // FIRST_NAME,LAST_NAME
      const csvWriter = createCsvWriter({
        path: 'file.csv',
        header: [
          {id: 'FIRST_NAME', title: 'FIRST_NAME'},
          {id: 'LAST_NAME', title: 'LAST_NAME'}
        ]
      })
      return csvWriter.writeRecords(arr)
    }
    
    testWriteCsv().then(() => console.log('Finished'))
    

    输出file.csv应该有以下内容。

    FIRST_NAME,LAST_NAME
    First Name1,First Name1
    First Name2,First Name2
    First Name3,First Name3
    

    【讨论】:

      【解决方案4】:

      您可以使用xlsx 节点模块。它也可以通过 cdn 获得。 通过键/值对数组,您的意思是对象数组或数组数组,我正在为两者提供示例。

      首先映射您的对象数组。创建一个表字符串并将该表字符串提供给 xlsx 模块。它可以将字符串转换为 xlsx 或 csv

      您可以通过将任何列标题包装在

      中来放置它

      例如:

      const xlsx = require('xlsx')
      let arr = [
      {
          firstname: 'First Name1',
          lastname: 'last Name1'
      },{
          firstname: 'First Name2',
          lastname: 'last Name2'
      },{
          firstname: 'First Name3',
          lastname: 'last Name3'
      },{
          firstname: 'First Name4',
          lastname: 'last Name4'
      }
      ]
      // if you have array of objects
      let tablerows = arr.map((arr, index) => {
      return "<tr><td>" + arr.firstname + '</td><td>' + arr.lastname + '</td></tr>'
      }
      
      //if you have array of array as you described in question
      let tablerows = arr.map((arr, index) => {
      return "<tr><td>" + arr.FIRST_NAME + '</td><td>' + arr.LAST_NAME + '</td></tr>'
      }
      
      let table = '<table>\
               <thead>\
               <tr>\
                  <th>First Name</th>\
                  <th>Last Name</th>\
              </tr>\
              </thead>' + tablerows.join('') + '</table>'
      
      let workbook = xlsx.read(table, { type: 'string' });
      xlsx.writeFile(workbook, "filename.csv")
      

      【讨论】:

      • 谢谢,但这不起作用。您在示例中提供的 arr 不是键/值对数组。另外我不确定 是什么,
        从未见过,我不理解该代码的语法,我在任何 node.js 中都找不到它搜索文档后的任何地方的文档。然而,这很有价值,让我知道我将研究的 xlsx 库,因为我有一些即将到来的 .xlsx 处理要做。
      猜你喜欢
      • 2014-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-21
      • 1970-01-01
      • 1970-01-01
      • 2016-07-24
      相关资源
      最近更新 更多