0

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,,,,,,,,,
James Wilson
  • 103
  • 1
  • 2
  • have a look at [How to export javascript array to CSV file](https://stackoverflow.com/a/14966131/2417602). – vikscool Aug 31 '18 at 09:41
  • Thanks for that. I have read that already, but I was unable to put it to use. My skills are not good enough to work out how to use it for my situation. – James Wilson Aug 31 '18 at 09:51

2 Answers2

2

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>
vikscool
  • 1,263
  • 1
  • 10
  • 21
0

One way is - Formatting should just be outputting all the individual lines (TableHeader + all your datatable lines) into an array, then joining the array into 1 long string with an 'end of line' symbol(which may or may not happen automatically, you might need to play with this). Then you put that resultant string into a link/button on your page.

so something along the lines of:

    var OutString = [];
    // your existing code here for defining the headers
    OutString[0] = TableHeader
 for (var i = 1; i < LineCount; ++i) { // looping mechanism through pickup from the page
// your existing code here for picking up the details
      OutString[i] = dataTable
     }
    TestFunc += OutString.join(''); // or whatever you want your end of line to be
    OutPutLine = '<a href="data:text/plain;charset=UTF-8, ' + encodeURIComponent(TestFunc) + '" download="' + decodeURIComponent(escape('your file name here')) +'">{optional button etc here}</a>';

Then write OutPutLine to your page element.

Louise
  • 362
  • 1
  • 7
  • 16
  • Thanks - I'm getting "Uncaught ReferenceError: LineCount is not defined" – James Wilson Aug 31 '18 at 10:16
  • oh i'm so sorry, i forgot to put that bit in. do you have a way of counting how many items in the page you will be picking up before you start (in which case that will be linecount)? otherwise we need to work out some way of telling when youve done them all. if datacolumn is the number of items you are picking up, then you can either hardcode the loop as 3 (assuming the index starts at 0) or we can count the items in dataColumn. – Louise Aug 31 '18 at 10:30
  • so either ' var LineCount = dataColumn.length; for (var i = 1; i < LineCount; ++i)' or 'for (var i = 1; i <3; ++i)'' – Louise Aug 31 '18 at 10:33