Search code examples
javascriptarrayscsvexport-to-csvbookmarklet

Convert a multidimensional array to columns of a CSV file in JavaScript and save using a browser bookmarklet


Using Javascript run within a browser using a bookmarklet, my objective is to gather data from links on a web page, then put this into a formatted CSV for download. The tasks as I see them are:

  1. Get the data
  2. Put it into arrays
  3. Format as CSV
  4. Export the data (either as a downloadable file, or load in the browser to save manually)

I have done 1 and 2, giving me an array of arrays as columns for the table. I'm stuck on 3 and 4. Here's a sample of the data:

// test data for 'const' column (length of array will be variable)
var dataColumn = ["tt0468569", "tt0111161", "tt1795369", "tt7738450"];

// making arrays for other columns in export table (most of the other columns will be empty)
var emptyArray = Array(dataColumn.length).fill('')
var titleType = Array(dataColumn.length).fill('Feature Film')

// make array of arrays (columns) ready to export as csv
var dataTable = [emptyArray,dataColumn,emptyArray,emptyArray,emptyArray,emptyArray,titleType,emptyArray,emptyArray,emptyArray,emptyArray,emptyArray,emptyArray,emptyArray,emptyArray,emptyArray];

// column headers for table
var tableHeaders = ["position","const","created","modified","description","Title","Title type","Directors","You rated","IMDb Rating","Runtime (mins)","Year","Genres","Num. Votes","Release Date (month/day/year)","URL"]

And my desired output:

position,const,created,modified,description,Title,Title type,Directors,You rated,IMDb Rating,Runtime (mins),Year,Genres,Num. Votes,Release Date (month/day/year),URL
,tt0468569,,,,,Feature Film,,,,,,,,,
,tt0111161,,,,,Feature Film,,,,,,,,,
,tt1795369,,,,,Feature Film,,,,,,,,,
,tt7738450,,,,,Feature Film,,,,,,,,,

Solution

  • You are almost done on creating the array, just need to change the approach for creating the tableData. Instead of appending the tableData with a set of arrays as empty array and title array you need to map them accordingly.

    Take a look at the snippet below:

    function downloadExcel() {
      var dataColumn = ["tt0468569", "tt0111161", "tt1795369", "tt7738450"];
      var tableHeaders = ["position", "const", "created", "modified", "description", "Title", "Title type", "Directors", "You rated", "IMDb Rating", "Runtime (mins)", "Year", "Genres", "Num. Votes", "Release Date (month/day/year)", "URL"];
    
      //now a container for the excel data i.e. tableHeaders+datacreated:
      var dataTable = new Array();
      dataTable.push(tableHeaders);
    
      //now looping around the data
      dataColumn.forEach(function(col) {
        dataTable.push(['', col, '', '', '', '', 'Feature Film', '', '', '', '', '', '', '', '', '']);
      });
    
      //now converting the array given into a `csv` content
      let csvContent = "data:text/csv;charset=utf-8,";
      dataTable.forEach(function(rowArray) {
        let row = rowArray.join(",");
        csvContent += row + "\r\n";
      });
    
      //calling the csv download via anchor tag(link) so we can provide a name for the file
      var encodedUri = encodeURI(csvContent);
      var link = document.createElement("a");
      link.setAttribute("href", encodedUri);
      link.style.display = 'none';
      link.setAttribute("download", "myCSV.csv"); //change it to give your own name
      link.innerHTML = "Click Here to download";
      document.body.appendChild(link); // Required for FF
    
      link.click();
      link.remove(); //removing the link after the download
    }
    <button onclick="downloadExcel()">Click me to Download excel</button>