【问题标题】:JS: convert 2D object with keys to transposed csvJS:将带有键的 2D 对象转换为转置的 csv
【发布时间】:2015-07-01 02:13:19
【问题描述】:

我有一个返回 2D 对象的 ajax 调用,我希望能够将其转换为 .csv 文件供用户下载。

php代码:echo json_encode($results);

js函数,现在有console.log (JSON.parse(res));,所以我可以验证内容。

控制台日志显示:

Object {color: Object, animal: Object}
  color: Object
    1: "red"
    2: "white"
    3: "blue"
  animal: Object
    1: "cat"
    2: "dog"
    3: "mouse  

每个内部对象始终具有相同数量的元素(在本例中为 3)

我想将其转换为 csv,然后下载。 csv 的第一行将包含外部对象键(颜色、动物) csv 最终会像这样:

"color, animal"
"red, cat"
"white, dog"
"blue, mouse"

通过我查看过的解决方案,它们将对象的连接版本附加到每一行。我需要垂直转置数据。

我认为我需要遍历每个内部对象(获取每个对象的第 n 个元素,获取每个对象的第 n+1 个元素等)并构建我自己的 csv 字符串,但这看起来非常笨重。

有什么漂亮的数组/对象函数可以帮助我吗?

我能够创建和下载一个 .csv 文件,只是这个数据转置逻辑让我卡住了。

编辑:我没有尝试将 csv 字符串转换为数组,也没有尝试转置 2D 数组(它是 2D 对象)。

澄清 在我对 php 文件的 ajax 调用中,我发送了一个来自用户输入的 ["color", "animal"] 数组。 php 文件读取这个数组并根据这个数组收集数据。收集数据后,它会返回一个二维数组,内部数组是新数据。因此:

[color[red, white, blue], animal[cat,dog,mouse]]

【问题讨论】:

  • 不是骗子。请参阅我上面的编辑评论。
  • 能不能把php代码发过来的json数据也贴一下? (console.log(res))
  • 什么是二维对象?
  • 这是原始输出(json 数据)@Kaiido {"color":{"1":"red","2":"white","3":"blue"},"animal":{"1":"cat","2":"dog","3":"mouse"}}

标签: javascript arrays csv object


【解决方案1】:

你可以试试这样的:

var rep = JSON.parse('{"color":{"1":"red","2":"white","3":"blue"},"animal":{"1":"cat","2":"dog","3":"mouse"}}')
function toCSV(jsonObject) {
  var csv = [];
  for (var i in jsonObject) {
    if (jsonObject.hasOwnProperty(i)) {
      var title = i.indexOf(' ')>-1? '"'+i+'"': i;
      csv[0] ? csv[0].push(title) : csv[0] = [title];
      var k = Object.keys(jsonObject[i]);
      for (var j = 0; j < k.length; j++) {
        var val = jsonObject[i][k[j]].indexOf(' ')>-1? '"'+jsonObject[i][k[j]]+'"': jsonObject[i][k[j]];;
        csv[j+1] ? csv[j + 1].push(val) : csv[j+1] = [val];
      }
    }
  }
  return csv.join('\n');
}

document.body.innerHTML = toCSV(rep).replace(/\n/g, '<br>');

【讨论】:

  • JSON 数据为{"color":{"1":"red","2":"white","3":"blue"},"animal":{"1":"cat","2":"dog","3":"mouse"}}
  • 接近 - 现在我返回了更多数据(在 csv 中,它应该显示为 4 列数据,每列有 1 行标题和 20 行数据),一些输入数据没有进入输出。我认为一些指数计数器略有偏离。例如第 1 行(标题):4 个条目,第 2-7 行:4 个条目,第 8-14 行:3 个条目,第 15 行:1 个条目,第 16-18 行:1 个条目,第 19-21 行:0 个条目。跨度>
  • 再一次,您能否将原始 json 发布在 pastebin 之类的某个地方,以便我更新?
  • 哦,重新阅读您的评论,我觉得问题可能确实是空输入。有没有办法让你的 php 代码总是输出一个字符串,甚至是空的? (20:"")
  • 所有数据都是非空白的。似乎有一个模式。在第一列的前 7 行之后,它停止处理。在第二列中的 14 行之后,它停止处理,然后是 18 行,然后是 15 行。我使用了不同的数据,但结果相同。 link to pastebin
【解决方案2】:
var k = JSON.parse('{"color":{"1":"red","2":"white","3":"blue"},"animal":{"1":"cat","2":"dog","3":"‌mouse"}, "price":{"1":"1000","2":"2000","3":"3000"}}');

var finalStr = '';
//Extract Top Columns Name
var keyList = [];
for(each in k) {
    keyList.push(each)
}
//Join them accordingly
finalStr = '"' + keyList.join(", ") + '"\n'

//As you said - Each of the inner objects always has the same number of elements (in this case, 3)
var startRef = k[keyList[0]];

//for each key in ref object
for(each in startRef) {
    var arr = [];
    //extract value for that key in each child object 
    for(var i=0;i<keyList.length;i++) {
        arr.push(k[keyList[i]][each])
    }
    //Join them accordingly
    finalStr += '"' + arr.join(", ") + '"\n'
}
console.log(finalStr)

//Output
"color, animal, price"
"red, cat, 1000"
"white, dog, 2000"
"blue, ‌mouse, 3000"

【讨论】:

    【解决方案3】:

    根据您的问题,您说的是 console.log($result),这意味着我假设您正在尝试通过 AJAX 获取它。

    我建议您不要在客户端 JavaScript 上创建 CSV,而是从您的 PHP 代码中创建,只需为您的 php 文件添加一个超链接,其中包含带有 Content-Type 和 Content-Disposition 的 CSV 创建代码,因此浏览器将直接显示文件保存对话框。

    看到这个答案File is not being downloaded when requested through Ajax using JQuery

    简单地放一个超链接

    <a href="admin_ajax.php">Download</a>
    

    参考Force Download CSV File
    请参考Create a CSV File for a user in PHP

    -- 编辑--

    客户端 CSV 是可能的。

    但我推荐服务器端 CSV 的原因。

    • CSV 的大小可能会更大,这可能会使您的客户端大小基于 JSON 的循环消耗内存并可能降低浏览器性能。
    • GZIP 或反向代理压缩流量等服务器端压缩选项很简单,它会被浏览器自动解压,但客户端解压可能很简单
    • 如果您想提供额外的 PDF 选项或丰富的 XL​​SX 文件下载选项,使用 javascript 可能不太容易。

    【讨论】:

    • 从这些链接中,似乎所有数据都在服务器端收集,然后返回给客户端。就我而言,我需要先传递一些用户定义的输入(在这种情况下为颜色和动物),然后服务器才能确定要收集和返回的数据。如果我错了,请纠正我,我不知道这是否对我有帮助。这是一个有趣的策略,我将存储以备将来使用!也许我可以在 GET 请求中附加用户输入,修改超链接。 admin_ajax.php?a=color&amp;b=animal 有点 js。
    • 你去隐藏
      标记并将所有隐藏字段并填充并实际提交,但是获取 JSON 并形成 CSV 作为客户端可能不是更好的方法,那是我的点
    • 为什么不建议在客户端创建 csv?我测试了您的解决方案,以便了解它是如何工作的,所以现在我有了另一个可以在将来使用的策略。欣赏这个建议。我赞成这个答案,因为它确实提供了一个解决方案,只要我重新编写 php 代码来转置数据。
    猜你喜欢
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 2016-03-18
    相关资源
    最近更新 更多