如何通过分离对象的项目符号将对象转换为Excel / csv文件中具有多个工作表的csv文件

时间:2019-08-01 04:44:38

标签: javascript object vue.js export-to-csv

我需要一些建议,通过将每个项目符号分隔到csv / excel文件中的新工作表中,将下面的对象转换为csv文件。

var data = {
  DeviceA: {
    smokeSensor: [
      {
        '190501': {
          '0001': 200,
          '0002': 300
        },
      },
      {
        '190502': {
          '0001': 20,
          '0002': 30
        },
      }
    ],
    fireSensor: [
      {
        '190501': {
          '0001': 700,
          '0002': 750
        },
      },
      {
        '190502': {
          '0001': 780,
          '0002': 630
        },
      }
    ]
  },
  DeviceB: {
    smokeSensor: [
      {
        '190601': {
          '0001': 100,
          '0002': 110
        },
      },
      {
        '190602': {
          '0001': 120,
          '0002': 130
        },
      }
    ],
    fireSensor: [
      {
        '190601': {
          '0001': 600,
          '0002': 522
        },
      }
    ]
  },
};

目前,我已经完成了用自己的方式转换数据并获得excel文件的结果。

var data = { deviceA: { smokeSensor: [ { '190501': { '0001': 200, '0002': 300 }, }, { '190502': { '0001': 20, '0002': 30 }, } ], fireSensor: [ { '190501': { '0001': 700, '0002': 750 }, }, { '190502': { '0001': 780, '0002': 630 }, } ] }, deviceB: { smokeSensor: [ { '190601': { '0001': 100, '0002': 110 }, }, { '190602': { '0001': 120, '0002': 130 }, } ], fireSensor: [ { '190601': { '0001': 600, '0002': 522 }, } ] }, };

const dataToCSV = data => {
  const rows = [];

  for (const device in data) {
    rows.push(
      [device.replace(/^./, m => m.toUpperCase())], 
      ["Date/Time", ...Object.keys(data[device])]
    );
    const groups = {};
    let longest = 0;

    for (const sensor in data[device]) {  
      for (const time of data[device][sensor]) {
        const k = Object.keys(time)[0];

        for (const hm in time[k]) {
          const groupKey = `${k} ${hm.replace(/(\d\d)(\d\d)/, "$1:$2")}`;

          if (!(groupKey in groups)) {
            groups[groupKey] = [groupKey];
          }

          groups[groupKey].push("" + time[k][hm]);
          longest = Math.max(longest, groups[groupKey].length);
        }
      }
    }

    for (const group of Object.values(groups)) {
      while (group.length < longest) { 
        group.push("");
      }

      rows.push(group);
    }

    rows.push([""]);
  }

  return rows.slice(0, -1);
};

const rows = dataToCSV(data)

/* const rows = [
  ["DeviceA"]
  ["Date/Time", "smokeSensor", "fireSensor"],
  ["190501 00:01", "200", "700"],
  ["190501 00:02", "300", "750"],
  ["190502 00:01", "20", "780"],
  ["190502 00:02", "30", "630"],
  [""],
  ["DeviceB"],
  ["Date/Time", "smokeSensor", "fireSensor"],
  ["190501 00:01", "100", "600"],
  ["190501 00:02", "110", "522"],
  ["190502 00:01", "120", ""],
  ["190502 00:02", "130", ""],
];
*/

function exportToCSV(rows) {
      let csvContent = ""
      rows.forEach(function(rowArray) {
          let row = rowArray.join(",")
          csvContent += row + "\r\n"
      });
      var link = document.createElement("a")
      document.body.appendChild(link)
      // var blob = new Blob([csvContent], {type: "text/csv"}); 
      var blob = new Blob([csvContent], {type: "xls/xlsx"})
      var url = window.URL.createObjectURL(blob)
      link.setAttribute("href", url)
      link.setAttribute("download", "my_data.csv")
      link.click() /* Download the data file named "my_data.csv". */
      $('#loading-modal').modal('hide');
},

exportToCSV(rows)

以上似乎都可以。但是,如果我有超过1000条记录的大量数据,那么所有这些都显示在一个工作表文件中,那么我就无法向下滚动以查看DeviceB,对吗?因此,我想将DeviceB分离到excel文件中的新表中。我必须从exportToCSV函数做些什么?

1 个答案:

答案 0 :(得分:0)

您需要将行声明为object(rows = {})。循环数据数组时,请使用键名(deviceA,deviceB...)并使用键名将该键名声明为数组。

我已经更改了您的代码并创建了代码段。

请参见下面的屏幕截图和代码段

enter image description here

var data = {"deviceA":{"smokeSensor":[{"190501":{"0001":200,"0002":300}},{"190502":{"0001":20,"0002":30}}],"fireSensor":[{"190501":{"0001":700,"0002":750}},{"190502":{"0001":780,"0002":630}}]},"deviceB":{"smokeSensor":[{"190601":{"0001":100,"0002":110}},{"190602":{"0001":120,"0002":130}}],"fireSensor":[{"190601":{"0001":600,"0002":522}}]}};

const dataToCSV = data => {
    const rows = {};

    for (const device in data) {
        let keyName = device.replace(/^./, m => m.toUpperCase());
        rows[keyName] = [
            ["Date/Time", ...Object.keys(data[device])]
        ];
        const groups = {};
        let longest = 0;

        for (const sensor in data[device]) {
            for (const time of data[device][sensor]) {
                const k = Object.keys(time)[0];

                for (const hm in time[k]) {
                    const groupKey = `${k} ${hm.replace(/(\d\d)(\d\d)/, "$1:$2")}`;

                    if (!(groupKey in groups)) {
                        groups[groupKey] = [groupKey];
                    }

                    groups[groupKey].push("" + time[k][hm]);
                    longest = Math.max(longest, groups[groupKey].length);
                }
            }
        }

        for (const group of Object.values(groups)) {
            while (group.length < longest) {
                group.push("");
            }

            rows[keyName].push(group);
        }
    }

    return rows;
}

const rowObject = dataToCSV(data);

function exportToCSV(rows, keyName) {
    let csvContent = ""
    rows.forEach(function(rowArray) {
        let row = rowArray.join(",")
        csvContent += row + "\r\n"
    });
    var blob = new Blob([csvContent], {
        type: "xls/xlsx"
    });
    var url = window.URL.createObjectURL(blob);
    $('#container').append(`<a download="${keyName}.csv"  href="${url}">Click to Download : ${keyName}</a>`);
}
for (let key in rowObject) {
    exportToCSV(rowObject[key], key);
}
#container a{
    display: inline-block;
    width: 100%;
    background-color: #3c3c3c;
    color: #fff;
    padding: 10px 20px;
    margin: 5px 0px;
    text-decoration: none;
}

#container a:hover{
  color:#ffa;
  text-decoration: underline; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="container"></div>