I’m trying to export from a data table into a CSV file. Here is my whole function. It downloads a file, but it shows the whole code for the table and not separating any of the data out. When I say whole code I mean everything within ‘table /table’
function displayDataTable(index){ $("#pageOverlay").empty(); html = "<div id='volumeChartDiv'><h4>Data Table</h4><table id='dataTable' class='table table-bordered table-striped dataTable' role='grid'><thead><tr role='row'><th>header1</th><th>header2</th><th>header3</th></tr></thead><tbody><tr><td>cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr><tr><td>bell2-1</td><td>bell2-2</td><td>bell2-3</td></tr><tr><td>fell3-1</td><td>fell3-2</td><td>fell3-3</td></tr></tbody></table><input type='button' value='Close' onclick='closeOverlay()'> <input type='button' id='exportDataTable' value='Export Table'></div>"; $("#pageOverlay").html(html); // export data function $("#exportDataTable").click(function (e) { window.open('data:application/vnd.ms-excel,' + $('.dataTable').html()); e.preventDefault(); }); openOverlay(); }
Answer
CSV format cannot accept $('.dataTable').html()
as .html()
is not a structured data, it’s not even data, just a silly hmtl.
You have to get data from your table, make a string representing CSV format, and download it, As you don’t show your table data structure here’s working demo below
$('#export').click(function() { var titles = []; var data = []; /* * Get the table headers, this will be CSV headers * The count of headers will be CSV string separator */ $('.dataTable th').each(function() { titles.push($(this).text()); }); /* * Get the actual data, this will contain all the data, in 1 array */ $('.dataTable td').each(function() { data.push($(this).text()); }); /* * Convert our data to CSV string */ var CSVString = prepCSVRow(titles, titles.length, ''); CSVString = prepCSVRow(data, titles.length, CSVString); /* * Make CSV downloadable */ var downloadLink = document.createElement("a"); var blob = new Blob(["ufeff", CSVString]); var url = URL.createObjectURL(blob); downloadLink.href = url; downloadLink.download = "data.csv"; /* * Actually download CSV */ document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); }); /* * Convert data array to CSV string * @param arr {Array} - the actual data * @param columnCount {Number} - the amount to split the data into columns * @param initial {String} - initial string to append to CSV string * return {String} - ready CSV string */ function prepCSVRow(arr, columnCount, initial) { var row = ''; // this will hold data var delimeter = ','; // data slice separator, in excel it's `;`, in usual CSv it's `,` var newLine = 'rn'; // newline separator for CSV row /* * Convert [1,2,3,4] into [[1,2], [3,4]] while count is 2 * @param _arr {Array} - the actual array to split * @param _count {Number} - the amount to split * return {Array} - splitted array */ function splitArray(_arr, _count) { var splitted = []; var result = []; _arr.forEach(function(item, idx) { if ((idx + 1) % _count === 0) { splitted.push(item); result.push(splitted); splitted = []; } else { splitted.push(item); } }); return result; } var plainArr = splitArray(arr, columnCount); // don't know how to explain this // you just have to like follow the code // and you understand, it's pretty simple // it converts `['a', 'b', 'c']` to `a,b,c` string plainArr.forEach(function(arrItem) { arrItem.forEach(function(item, idx) { row += item + ((idx + 1) === arrItem.length ? '' : delimeter); }); row += newLine; }); return initial + row; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="export">export</button> <table class="dataTable"> <tr> <th>Company</th> <th>Contact</th> <th>Country</th> </tr> <tr> <td>Alfreds Futterkiste</td> <td>Maria Anders</td> <td>Germany</td> </tr> <tr> <td>Centro comercial Moctezuma</td> <td>Francisco Chang</td> <td>Mexico</td> </tr> <tr> <td>Ernst Handel</td> <td>Roland Mendel</td> <td>Austria</td> </tr> <tr> <td>Island Trading</td> <td>Helen Bennett</td> <td>UK</td> </tr> <tr> <td>Laughing Bacchus Winecellars</td> <td>Yoshi Tannamuri</td> <td>Canada</td> </tr> <tr> <td>Magazzini Alimentari Riuniti</td> <td>Giovanni Rovelli</td> <td>Italy</td> </tr> </table>
If you find any bugs, comment below, i’ll fix them