1

I want to save an array of objects to a CSV file, I have tried the following code based on this answer, but my code didn't work well, can you please tell me how can I fix it? thanks in advance.

<template>
  <div @click="saveLogs()">save csv</div>
</template>

<script>
export default {
  name: "App",
  components: {},
  methods: {
    /****************************************
     * https://stackoverflow.com/a/68146412
     ****************************************/
    arrayToCsv(data) {
      return data
        .map(
          (row) =>
            row
              .map(String) // convert every value to String
              .map((v) => v.replaceAll('"', '""')) // escape double colons
              .map((v) => `"${v}"`) // quote it
              .join(",") // comma-separated
        )
        .join("\r\n"); // rows starting on new lines
    },
    /**************************************************************
     * downloadBlob(csv, 'export.csv', 'text/csv;charset=utf-8;')
     *************************************************************/
    downloadBlob(content, filename, contentType) {
      // Create a blob
      var blob = new Blob([content], { type: contentType });
      var url = URL.createObjectURL(blob);

      // Create a link to download it
      var pom = document.createElement("a");
      pom.href = url;
      pom.setAttribute("download", filename);
      pom.click();
    },
    saveLogs() {
      const myLogs = this.arrayToCsv([
        { act_id: 44, actor: "robot_arm", color: "yellow", lego: "yb1", pick: {x: 1, y: 2, z:5} },
        { act_id: 44, actor: "robot_arm", color: "yellow", lego: "yb2", pick: {x: 1, y: 2, z:5} },
      ]);
      this.downloadBlob(myLogs, "./gui_logs.csv", "text/csv;charset=utf-8;");
      console.log("Logs has been saved");
    },
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
Bilal
  • 3,191
  • 4
  • 21
  • 49

2 Answers2

0

Thanks to @traynor suggestion here is the full answer:

/* https://stackoverflow.com/a/58769574 */
arrayToCsv(data) {
    const array = [Object.keys(data[0])].concat(data)

    return array.map(it => {
        return Object.values(it).toString()
    }).join('\n');
},

/* https://stackoverflow.com/a/68146412 */
/* downloadBlob(csv, 'export.csv', 'text/csv;charset=utf-8;')*/
downloadBlob(content, filename, contentType) {
    // Create a blob
    var blob = new Blob([content], { type: contentType });
    var url = URL.createObjectURL(blob);

    // Create a link to download it
    var pom = document.createElement('a');
    pom.href = url;
    pom.setAttribute('download', filename);
    pom.click();
},

/* store.js
logs: [
        {
            time_stamp: new Date().toISOString(),
            message: " ============{ Logs }============",
            color: "white",
            name: 0,
        }
    ],
*/
saveLogs() { 
    const myLogs = this.arrayToCsv(store.logs);
    this.downloadBlob(myLogs, './gui_logs.csv', 'text/csv;charset=utf-8;');
    console.log("Logs has been saved");
}
Bilal
  • 3,191
  • 4
  • 21
  • 49
-1

You try to do it like it's a 2D array, but it's an array of JSON objects. Like @traynor said, read this :

You can read this too :

Also consider using npm library like csv-writer (install with npm i csv-writer). You can find out an example here.

When downloading the file, I suggest you to set content-type to 'text/csv' and filename without './'. After clicking a link you should remove it like that : pom.remove()

Alexis
  • 34
  • 4