0

Suppose I have this loop code.

for (var i = 0; i < originList.length; i++) {
          var results = response.rows[i].elements;
          for (var j = 0; j < results.length; j++) {
            outputDiv.innerHTML += results[j].distance.text + ',';
          }
        }

I want to export the outputDiv.innerHTML into CSV with this code, but it doesn't work.

function downloadFile(fileName, urlData) {

var aLink = document.createElement('a');
aLink.download = fileName;
aLink.href = urlData;

var event = new MouseEvent('click');
aLink.dispatchEvent(event);
}

downloadFile('output.csv', 'outputDiv.innerHTML/csv;charset=UTF-8,' + encodeURIComponent(outputDiv.innerHTML));

What should I do? I'm new at this. Thank you.

3
  • 2
    Make sure your div contents has comma containing strings. Since we cannot see the contents. Commented Jun 16, 2019 at 3:01
  • I've already put outputDiv.innerHTML = ""; in the beggining of the code Commented Jun 16, 2019 at 3:07
  • Welcome to SO @MarinaRamosa. If possible, please include sample code where downloadFile is called and sample HTML. Commented Jun 16, 2019 at 6:04

3 Answers 3

1

This solution is in JavaScript. I added an event listener to the button so when it is clicked, it will grab the outerHTML of <table>.

outerHTML essentially includes the opening and closing tags of the element as well as the content whereas innerHTML does not include the opening and closing tags.

From MDN Web Docs

The outerHTML attribute of the Element DOM interface gets the serialized HTML fragment describing the element including its descendants. It can also be set to replace the element with nodes parsed from the given string.

When the innerText is extracted from the all rows and columns. download_csv is called.

You can download the data using a Blob object which is a file-like object of immutable, raw data.

document.querySelector("button").addEventListener("click", function () {
  let html = document.querySelector("table").outerHTML;
  exportToCSV(html, "table.csv");
});

function exportToCSV(html, filename) {
  let csv = [];
  
  // grab all rows inside table
  let rows = document.querySelectorAll("table tr");
  let row, cols;
  
  for (let i = 0; i < rows.length; i++) {
    row = []; // will hold innerText of all columns
    // retrieve all columns of row
    cols = rows[i].querySelectorAll("td, th");
    
    for (let j = 0; j < cols.length; j++){
      // push column innerText
      row.push(cols[j].innerText);
    }
    
    // push all innerText into CSV
    csv.push(row.join(","));		
  }
  
  console.log("Extracted content from html:",csv);
  // Download CSV
  download_csv(csv.join("\n"), filename);
}

function download_csv(csv, filename) {
  let csvFile;
  let downloadLink;

  // CSV FILE
  csvFile = new Blob([csv], {type: "text/csv"});

  // create an element and set the file name.
  downloadLink = document.createElement("a");
  downloadLink.download = filename;

  // We have to create a link to the file
  downloadLink.href = window.URL.createObjectURL(csvFile);
  
  // prevent link from being shown
  downloadLink.style.display = "none";
  
  // Add the link to your DOM
  document.body.appendChild(downloadLink);

  // start the download
  downloadLink.click();
}
<table>
    <tr><th>Name</th><th>Age</th><th>Country</th></tr>
    <tr><td>Tony</td><td>26</td><td>USA</td></tr>
    <tr><td>Levi</td><td>19</td><td>Spain</td></tr>
    <tr><td>Calvin</td><td>32</td><td>Russia</td></tr>
</table>
<button>Export HTML table to CSV file</button>

Sign up to request clarification or add additional context in comments.

Comments

0

I do not know what are you trying to achieve in your last line, but that does not look like a dataURL, a dataURL looks like:

data:[][;base64],

Now that being said, the idea is to create an object url through a combination of Blob and window.URL.createObjectURL:

 function dL(input,fileName){
     var blob = new Blob(input,{type:"text/csv"}),
         url = window.URL.createObjectURL(blob),
         aElem = document.createElement("a"),
         fileName = "deogenResults.txt";
     aElem.setAttribute("href",url);
     aElem.setAttribute("download",fileName);
     if (window.navigator.constructor.prototype.hasOwnProperty("msSaveBlob")) {
        window.navigator.msSaveBlob(blob,fileName);
     } else if ("download" in aElem) {
        aElem.click();
     } else {
        window.open(url,"_blank");
     }
        setTimeout(function(){window.URL.revokeObjectURL(url)},2000);
}

Use it like this: dL(outputDiv.innerHTML,"someName")

It is important to remind you that some browsers might not allow click to trigger on an element that is NOT in the DOM yet, in that case you might want to append the a element to the body, set it invisible and then remove it inside setTimeout.

I wrote it in plain ES5, you can adapt with const,Promise instead of setTimeout etc declarations accordingly.

Comments

0

A good answer here by dandavis:

It uses a library by http://danml.com/js/download.js you make sure your div contents contains comma seperated content.

var csv = jQuery(".list").map(function(a, i) {
  return $.trim($(this).text()).split(/\s*\n\s*/).join(",");
}).toArray().join("\r\n");

alert(csv); // Contents
// Download
// download(csv, "tabledata.csv", "text/csv"); 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://danml.com/js/download.js"></script> <!-- CSV -->
<div class="list">
  1, 2, 3
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.