I am working on a way to save an HTML table to a csv file. Ideally, this should be cross-browser, and I have gotten this to work on everything but Internet Explorer. However, I have gotten the obvious parts working. What remains is that I am unable to get a working csv file from my JavaScript because a byte order mark is prepended to the data I wish to download.
I have confirmed that this is the case by downloading the csv file in IE and everything else and used a hex editor to view the raw file, I can confirm the file that Internet Explorer downloaded prepends the unicode character "FFFE".
Please see the code below this does this. saveTable takes an "<a>" node that is located inside a table.
If anyone can help me disgnose the issue and offer some solution I'd be grateful. Please forgive any faux pas on my part, I don't think I've ever used a site of this nature before. So if you need me to provide any further information please do just let me know and I shall do my best to get it on here.
function findTable(node) { // Finds a nodes parent table.
return (node.nodeName !== "TABLE") ? findTable(node.parentNode) : node;
}
function saveTable(node) {
var csv = [];
var table = findTable(node);
var rows = table.getElementsByTagName("tr");
var header = [];
var csv = [];
for (var i = 0; i < rows.length; i++) {
if (i == 0) {
// Do csv stuff.
var dates = rows[i].getElementsByTagName("th");
for (var j = 0; j < dates.length; j++)
(j == 0) ? header.push("") : header.push(dates[j].innerHTML);
csv.push(header.join(","));
}
else {
var rowArray = [];
var jobName = rows[i].getElementsByTagName("th")[0].innerHTML;
var times = rows[i].getElementsByTagName("td");
rowArray.push(jobName);
for (var k = 0; k < times.length; k++)
rowArray.push(times[k].innerHTML);
csv.push(rowArray.join(","));
}
}
node.setAttribute("href", "data:text/csv;charset=utf-8," + csv.join("%0A"));
var fileName = "spreadsheet_data-" + (new Date).getTime() + ".csv";
if (node.download == "")
node.setAttribute("download", fileName);
else {
alert("Handle IE here!");
var bom = "\uFFFE";
var doc = document.open("application/octet-stream", "_blank");
var data = csv.join("\r\n");
doc.charset = "UTF-8";
doc.write(data.replace(bom, ""));
doc.focus();
doc.execCommand('SaveAs', false, fileName);
doc.close();
}
}
Table example, it's not the way I would have chosen to do it myself, but it's how the table is generated by another piece of software.
<table id='results' border='1'>
<tr><th><a href='#' onClick='saveTable(this);' id='download_link'>Download data</a></th><th>2013/05/09</th><th>2013/05/10</th><th>2013/05/10</th><th>2013/05/10</th><th>2013/05/10</th></tr>
<tr>
<th>\PDF\EXOVIGN.PDF</th><td>8.853</td><td>9.050</td><td>8.807</td><td>8.827</td><td>8.835</td></tr>
</table>
If you have no absolute requirement to do this client-side, it might save you a lot of hassle to send the file from the server instead.