Convert HTML table to CSV in jQuery

Recently I was tasked with converting a HTML table into CSV format. If you're new to CSV it stands for 'Comma Seperated Values', so ultimately we'll be converting the table into a big string of values seperated by commas. The issue then is providing this as a download compatible in all major browsers (the biggest issue being IE, surprisingly!). At the time of writing this solution worked in IE9, Firefox 26 and Chrome 32.

I will go through the code step by step, otherwise you can download a copy of the solution below:

Download Solution

Start by creating a HTML table and a download link (both with appropriate ID's for referencing later). Finally add an iframe, which will be used for the Internet Explorer download functionality.

Now we will create a script which will generate the string of table data and provide it as a downloadable CSV file.

Firstly we add an event listener for the click event of our button:


$("#btnExport ").on('click', function (event) {

});

Then we grab our table and find out how many rows and columns it has:


//Get table
var table = $("#table")[0];

//Get number of rows/columns
var rowLength = table.rows.length;
var colLength = table.rows[0].cells.length;

We then declare a string to fill with the table data, and proceed to get the column headers. This is achieved by looping through each cell in the first row, and seperating the values with a comma. The reason we use .innerHTML.split(",").join("") on the cell is to remove any commas present in the string, to avoid issues with the CSV generation further down the line.


//Declare string to fill with table data
var tableString = "";

//Get column headers
for (var i = 0; i < colLength; i++) {
    tableString += table.rows[0].cells[i].innerHTML.split(",").join("") + ",";
}

tableString = tableString.substring(0, tableString.length - 1);
tableString += "\r\n";

We then do the same for row data:


//Get row data
for (var j = 1; j < rowLength; j++) {
    for (var k = 0; k < colLength; k++) {
        tableString += table.rows[j].cells[k].innerHTML.split(",").join("") + ",";
    }
    tableString += "\r\n";
}

Finally we have a string of comma seperated values from our HTML table. The real issue now is providing it as a download. To do this we will be checking which browser the user is running and providing a download using one of two methods:


//Save file
if (navigator.appName == "Microsoft Internet Explorer") {
    //Optional: If you run into delimiter issues (where the commas are not interpreted and all data is one cell), then use this line to manually specify the delimeter
     tableString = 'sep=,\r\n' + tableString;

     myFrame.document.open("text/html", "replace");
     myFrame.document.write(tableString);
     myFrame.document.close();
     myFrame.focus();
     myFrame.document.execCommand('SaveAs', true, 'data.csv');
 } else {
    csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(tableString);
     $(event.target).attr({
         'href': csvData,
         'target': '_blank',
         'download': 'my_data.csv'
     });
 }
 

If it is Internet Explorer, we are filling our iFrame with the html, and using document.execCommand to provide the contents of this iFrame as a download. If it isn't IE, we are simply setting the href, target and download attributed of the link we just clicked.

This solution is one of many and has been influenced from many sources online, but the two I wish to give credit to for being the most significant contributors are the following:

http://www.paessler.com/knowledgebase/en/topic/2293-i-have-trouble-opening-csv-files-with-microsoft-excel-is-there-a-quick-way-to-fix-this http://paxcel.net/blog/savedownload-file-using-html5-javascript-the-download-attribute-2/

Comments (0)