【问题标题】:Generate a csv file from a javascript array of objects从对象的 javascript 数组生成 csv 文件
【发布时间】:2017-11-07 21:06:57
【问题描述】:

我知道这是一个已经回答的问题,但找不到适合我的解决方案。

我有一个 HTML 按钮,当点击它时,会在 typescript(基本上是 javascript)中生成一个对象数组,我想生成一个将被下载的 csv 文件。

以下是 javascript 对象数组的示例:

    var items = [
              { "name": "Item 1", "color": "Green", "size": "X-Large" },
              { "name": "Item 2", "color": "Green", "size": "X-Large" },
              { "name": "Item 3", "color": "Green", "size": "X-Large" }];

    // Loop the array of objects
for(let row = 0; row < items.length; row++){
    let keysAmount = Object.keys(items[row]).length
    let keysCounter = 0

    // If this is the first row, generate the headings
    if(row === 0){

       // Loop each property of the object
       for(let key in items[row]){

                           // This is to not add a comma at the last cell
                           // The '\n' adds a new line
           csv += key + (keysCounter+1 < keysAmount ? ',' : '\r\n' )
           keysCounter++
       }
    }else{
       for(let key in items[row]){
           csv += items[row][key] + (keysCounter+1 < keysAmount ? ',' : '\r\n' )
           keysCounter++
       }
    }

    keysCounter = 0
}
console.log(csv)

var hiddenElement = document.createElement('a');
        hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
        hiddenElement.target = '_blank';
        hiddenElement.download = 'people.csv';
        hiddenElement.click();

我尝试了这个示例代码,但在我的情况下,它创建了 csv 文件,但没有在 csv 文件中正确插入 csv 字符串,csv 字符串包含由逗号分隔的元素行,每一行由换行,但是这里每行的所有数据都位于 csv 文件的一个单元格中,我该如何使每行的每个值都位于不同的单元格中?

这是它的 csv 字符串:

    name,color,size
Item 2,Green,X-Large
Item 3,Green,X-Large

【问题讨论】:

  • this.ConvertToCSV(data) 是您制作的自定义函数吗?你能告诉我们它的作用吗?
  • 什么是ConvertToCSV?它的输出是什么样的?
  • 另外,如果问题在console.log 中很明显,为什么不从问题中排除其余的下载代码呢?这似乎无关紧要。
  • 这里是convertToCSV(data)函数,我刚刚添加了它,该函数将对象数组转换为csv字符串
  • 我更新了代码,我正在取得进展,但我仍然没有得到我想要的结果

标签: javascript arrays json object export-to-csv


【解决方案1】:

CSV 只是一个文件, 每个单元格用逗号分隔,每一行用新行分隔。您想将每一列命名为对象的键。如果我理解正确:

{ "name": "Item 1", "color": "Green", "size": "X-Large" }

将是:

---------------------------
| name   | color |   size  |
---------------------------
| Item 1 | Green | X-Large |
---------------------------

更新:这是更新版本。

因此,您可以使用 HTML5 中的 File API 循环您的数组并相应地生成 csv:

let csv

// Loop the array of objects
for(let row = 0; row < items.length; row++){
    let keysAmount = Object.keys(items[row]).length
    let keysCounter = 0

    // If this is the first row, generate the headings
    if(row === 0){

       // Loop each property of the object
       for(let key in items[row]){

                           // This is to not add a comma at the last cell
                           // The '\r\n' adds a new line
           csv += key + (keysCounter+1 < keysAmount ? ',' : '\r\n' )
           keysCounter++
       }
    }else{
       for(let key in items[row]){
           csv += items[row][key] + (keysCounter+1 < keysAmount ? ',' : '\r\n' )
           keysCounter++
       }
    }

    keysCounter = 0
}

// Once we are done looping, download the .csv by creating a link
let link = document.createElement('a')
link.id = 'download-csv'
link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(csv));
link.setAttribute('download', 'yourfiletextgoeshere.csv');
document.body.appendChild(link)
document.querySelector('#download-csv').click()

顺便说一句,如果您使用的是 TypeScript,那么最后一行 document.querySelector('#download-csv').click() 必须是 &lt;HTMLElement&gt;document.querySelector('#download-csv').click() 让我知道它是否对你有用。

TypeScript 和 javascript 的小提琴(它只更改最后一行): https://jsfiddle.net/0p8revuh/4/

更新:要查看在 excel 中正确格式化的文件,每个逗号分隔值的单元格,请执行以下操作:

  1. 您将在多行中看到您的数据。只需单击“A”列即可选择所有行:

  2. 转到您的 Excel 并单击顶部的Data:

  3. 点击Text to columns:

  4. 选择分隔符:

  5. 点击下一步并激活comma:

  6. 单击next 和finish。现在您应该能够看到您的数据格式正确。

【讨论】:

  • 首先感谢您的帮助,我尝试了代码并收到错误消息,提示“类型元素上不存在点击”,最后一行代码
  • 你能在 chrome 开发工具上执行document.querySelector("#download-csv") 看看你是否得到链接?
  • 是的,它有效,我得到了链接,这就是我得到的 跨度>
  • 然后你应该可以用document.querySelector("#download-csv").click()点击它来下载。它对我有用。也可以试试typeof document.querySelector('#download-csv')
  • 它说它是一个对象
【解决方案2】:

有效!但是代码的方式看起来比较复杂,不容易理解。我觉得下面的代码可能有点清楚了。

另外,我通知我们需要正确保留对象键,例如,如果我们想要全部大写,我们需要将对象名称保留在大写中,但对象键的属性我不喜欢大写。大多数时候它应该是小写的。在这种情况下,这个解决方案也可能会有所帮助。

  let csvText = '';

    data.forEach((row, ind) => {
      if (!ind) {
        return (csvText += `${[
          'STOCK',
          'MAXPAIN',
          'CASH RATE',
          'FUTURE RATE',
          'PE',
          'PE OI',
          'CE',
          'CE OI',
          'PC RATIO MAX',
          'PC RATIO TOTAL'
        ].join(',')}\r\n`);
      }

      const properValues = [row.stock, row.option, row.strike, 0, row.put, row.put_oi, row.call, row.call_oi, 0, 0];

      return (csvText += `${properValues.join(',')}\r\n`);
    });

    console.log(csvText);

确保标题值和非标题值以相同的顺序返回;否则会被石化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    相关资源
    最近更新 更多