<html>
<head>
<meta name="description" content="Export with customisable file name" />
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/jszip-2.5.0/dt-1.11.4/b-2.2.2/b-html5-2.2.2/rg-1.1.4/datatables.min.css"/>
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/jszip-2.5.0/dt-1.11.4/b-2.2.2/b-html5-2.2.2/rg-1.1.4/datatables.min.js"></script> <meta charset=utf-8 />
<title>DataTables - JS Bin</title>
</head>
<body>
<div class="container">
<table id="example" class="display nowrap" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td>$3,120</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Director</td>
<td>Edinburgh</td>
<td>63</td>
<td>2011/07/25</td>
<td>$5,300</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>2009/01/12</td>
<td>$4,800</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>2012/03/29</td>
<td>$3,600</td>
</tr>
<tr>
<td>Jenna Elliott</td>
<td>Financial Controller</td>
<td>Edinburgh</td>
<td>33</td>
<td>2008/11/28</td>
<td>$5,300</td>
</tr>
<tr>
<td>Brielle Williamson</td>
<td>Integration Specialist</td>
<td>New York</td>
<td>61</td>
<td>2012/12/02</td>
<td>$4,525</td>
</tr>
<tr>
<td>Herrod Chandler</td>
<td>Sales Assistant</td>
<td>San Francisco</td>
<td>59</td>
<td>2012/08/06</td>
<td>$4,080</td>
</tr>
<tr>
<td>Rhona Davidson</td>
<td>Integration Specialist</td>
<td>Edinburgh</td>
<td>55</td>
<td>2010/10/14</td>
<td>$6,730</td>
</tr>
<tr>
<td>Colleen Hurst</td>
<td>Javascript Developer</td>
<td>San Francisco</td>
<td>39</td>
<td>2009/09/15</td>
<td>$5,000</td>
</tr>
<tr>
<td>Sonya Frost</td>
<td>Software Engineer</td>
<td>Edinburgh</td>
<td>23</td>
<td>2008/12/13</td>
<td>$3,600</td>
</tr>
<tr>
<td>Jena Gaines</td>
<td>System Architect</td>
<td>London</td>
<td>30</td>
<td>2008/12/19</td>
<td>$5,000</td>
</tr>
<tr>
<td>Quinn Flynn</td>
<td>Financial Controller</td>
<td>Edinburgh</td>
<td>22</td>
<td>2013/03/03</td>
<td>$4,200</td>
</tr>
<tr>
<td>Charde Marshall</td>
<td>Regional Director</td>
<td>San Francisco</td>
<td>36</td>
<td>2008/10/16</td>
<td>$5,300</td>
</tr>
<tr>
<td>Haley Kennedy</td>
<td>Senior Marketing Designer</td>
<td>London</td>
<td>43</td>
<td>2012/12/18</td>
<td>$4,800</td>
</tr>
<tr>
<td>Tatyana Fitzpatrick</td>
<td>Regional Director</td>
<td>London</td>
<td>19</td>
<td>2010/03/17</td>
<td>$2,875</td>
</tr>
<tr>
<td>Michael Silva</td>
<td>Senior Marketing Designer</td>
<td>London</td>
<td>66</td>
<td>2012/11/27</td>
<td>$3,750</td>
</tr>
<tr>
<td>Paul Byrd</td>
<td>Javascript Developer</td>
<td>New York</td>
<td>64</td>
<td>2010/06/09</td>
<td>$5,000</td>
</tr>
<tr>
<td>Gloria Little</td>
<td>Systems Administrator</td>
<td>New York</td>
<td>59</td>
<td>2009/04/10</td>
<td>$3,120</td>
</tr>
<tr>
<td>Bradley Greer</td>
<td>Software Engineer</td>
<td>London</td>
<td>41</td>
<td>2012/10/13</td>
<td>$3,120</td>
</tr>
<tr>
<td>Dai Rios</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>35</td>
<td>2012/09/26</td>
<td>$4,200</td>
</tr>
<tr>
<td>Jenette Caldwell</td>
<td>Financial Controller</td>
<td>New York</td>
<td>30</td>
<td>2011/09/03</td>
<td>$4,965</td>
</tr>
<tr>
<td>Yuri Berry</td>
<td>System Architect</td>
<td>New York</td>
<td>40</td>
<td>2009/06/25</td>
<td>$3,600</td>
</tr>
<tr>
<td>Caesar Vance</td>
<td>Technical Author</td>
<td>New York</td>
<td>21</td>
<td>2011/12/12</td>
<td>$4,965</td>
</tr>
<tr>
<td>Doris Wilder</td>
<td>Sales Assistant</td>
<td>Edinburgh</td>
<td>23</td>
<td>2010/09/20</td>
<td>$4,965</td>
</tr>
<tr>
<td>Angelica Ramos</td>
<td>System Architect</td>
<td>London</td>
<td>36</td>
<td>2009/10/09</td>
<td>$2,875</td>
</tr>
<tr>
<td>Gavin Joyce</td>
<td>Developer</td>
<td>Edinburgh</td>
<td>42</td>
<td>2010/12/22</td>
<td>$4,525</td>
</tr>
<tr>
<td>Jennifer Chang</td>
<td>Regional Director</td>
<td>London</td>
<td>28</td>
<td>2010/11/14</td>
<td>$4,080</td>
</tr>
<tr>
<td>Brenden Wagner</td>
<td>Software Engineer</td>
<td>San Francisco</td>
<td>18</td>
<td>2011/06/07</td>
<td>$3,750</td>
</tr>
<tr>
<td>Ebony Grimes</td>
<td>Software Engineer</td>
<td>San Francisco</td>
<td>48</td>
<td>2010/03/11</td>
<td>$2,875</td>
</tr>
<tr>
<td>Russell Chavez</td>
<td>Director</td>
<td>Edinburgh</td>
<td>20</td>
<td>2011/08/14</td>
<td>$3,600</td>
</tr>
<tr>
<td>Michelle House</td>
<td>Integration Specialist</td>
<td>Edinburgh</td>
<td>37</td>
<td>2011/06/02</td>
<td>$3,750</td>
</tr>
<tr>
<td>Suki Burks</td>
<td>Developer</td>
<td>London</td>
<td>53</td>
<td>2009/10/22</td>
<td>$2,875</td>
</tr>
<tr>
<td>Prescott Bartlett</td>
<td>Technical Author</td>
<td>London</td>
<td>27</td>
<td>2011/05/07</td>
<td>$6,730</td>
</tr>
<tr>
<td>Gavin Cortez</td>
<td>Technical Author</td>
<td>San Francisco</td>
<td>22</td>
<td>2008/10/26</td>
<td>$6,730</td>
</tr>
<tr>
<td>Martena Mccray</td>
<td>Integration Specialist</td>
<td>Edinburgh</td>
<td>46</td>
<td>2011/03/09</td>
<td>$4,080</td>
</tr>
<tr>
<td>Unity Butler</td>
<td>Senior Marketing Designer</td>
<td>San Francisco</td>
<td>47</td>
<td>2009/12/09</td>
<td>$3,750</td>
</tr>
<tr>
<td>Howard Hatfield</td>
<td>Financial Controller</td>
<td>San Francisco</td>
<td>51</td>
<td>2008/12/16</td>
<td>$4,080</td>
</tr>
<tr>
<td>Hope Fuentes</td>
<td>Financial Controller</td>
<td>San Francisco</td>
<td>41</td>
<td>2010/02/12</td>
<td>$4,200</td>
</tr>
<tr>
<td>Vivian Harrell</td>
<td>System Architect</td>
<td>San Francisco</td>
<td>62</td>
<td>2009/02/14</td>
<td>$4,965</td>
</tr>
<tr>
<td>Timothy Mooney</td>
<td>Financial Controller</td>
<td>London</td>
<td>37</td>
<td>2008/12/11</td>
<td>$4,200</td>
</tr>
<tr>
<td>Jackson Bradshaw</td>
<td>Director</td>
<td>New York</td>
<td>65</td>
<td>2008/09/26</td>
<td>$5,000</td>
</tr>
<tr>
<td>Miriam Weiss</td>
<td>Support Engineer</td>
<td>Edinburgh</td>
<td>64</td>
<td>2011/02/03</td>
<td>$4,965</td>
</tr>
<tr>
<td>Bruno Nash</td>
<td>Software Engineer</td>
<td>London</td>
<td>38</td>
<td>2011/05/03</td>
<td>$4,200</td>
</tr>
<tr>
<td>Odessa Jackson</td>
<td>Support Engineer</td>
<td>Edinburgh</td>
<td>37</td>
<td>2009/08/19</td>
<td>$3,600</td>
</tr>
<tr>
<td>Thor Walton</td>
<td>Developer</td>
<td>New York</td>
<td>61</td>
<td>2013/08/11</td>
<td>$3,600</td>
</tr>
<tr>
<td>Finn Camacho</td>
<td>Support Engineer</td>
<td>San Francisco</td>
<td>47</td>
<td>2009/07/07</td>
<td>$4,800</td>
</tr>
<tr>
<td>Elton Baldwin</td>
<td>Data Coordinator</td>
<td>Edinburgh</td>
<td>64</td>
<td>2012/04/09</td>
<td>$6,730</td>
</tr>
<tr>
<td>Zenaida Frank</td>
<td>Software Engineer</td>
<td>New York</td>
<td>63</td>
<td>2010/01/04</td>
<td>$4,800</td>
</tr>
<tr>
<td>Zorita Serrano</td>
<td>Software Engineer</td>
<td>San Francisco</td>
<td>56</td>
<td>2012/06/01</td>
<td>$5,300</td>
</tr>
<tr>
<td>Jennifer Acosta</td>
<td>Javascript Developer</td>
<td>Edinburgh</td>
<td>43</td>
<td>2013/02/01</td>
<td>$2,875</td>
</tr>
<tr>
<td>Cara Stevens</td>
<td>Sales Assistant</td>
<td>New York</td>
<td>46</td>
<td>2011/12/06</td>
<td>$4,800</td>
</tr>
<tr>
<td>Hermione Butler</td>
<td>Director</td>
<td>London</td>
<td>47</td>
<td>2011/03/21</td>
<td>$4,080</td>
</tr>
<tr>
<td>Lael Greer</td>
<td>Systems Administrator</td>
<td>London</td>
<td>21</td>
<td>2009/02/27</td>
<td>$3,120</td>
</tr>
<tr>
<td>Jonas Alexander</td>
<td>Developer</td>
<td>San Francisco</td>
<td>30</td>
<td>2010/07/14</td>
<td>$5,300</td>
</tr>
<tr>
<td>Shad Decker</td>
<td>Regional Director</td>
<td>Edinburgh</td>
<td>51</td>
<td>2008/11/13</td>
<td>$5,300</td>
</tr>
<tr>
<td>Michael Bruce</td>
<td>Javascript Developer</td>
<td>Edinburgh</td>
<td>29</td>
<td>2011/06/27</td>
<td>$4,080</td>
</tr>
<tr>
<td>Donna Snider</td>
<td>System Architect</td>
<td>New York</td>
<td>27</td>
<td>2011/01/25</td>
<td>$3,120</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
body {
font: 90%/1.45em "Helvetica Neue", HelveticaNeue, Verdana, Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
color: #333;
background-color: #fff;
}
$(document).ready(function() {
function getHeaderNames(dt) {
// Gets header names.
//params:
// dt: Datatable API.
//Returns:
// Array of column header names.
var header = dt.columns().header().toArray();
var names = [];
header.forEach(function(th) {
names.push($(th).html());
});
return names;
}
function getFooterNames(dt) {
// Gets header names.
//params:
// dt: Datatable API.
//Returns:
// Array of column header names.
var footer = dt.columns().footer().toArray();
var names = [];
footer.forEach(function(th) {
names.push($(th).html());
});
return names;
}
function buildCols(data) {
// Builds cols XML.
//To do: deifne widths for each column.
//Params:
// data: row data.
//Returns:
// String of XML formatted column widths.
var cols = '<cols>';
for (i=0; i<data.length; i++) {
colNum = i + 1;
cols += '<col min="' + colNum + '" max="' + colNum + '" width="20" customWidth="1"/>';
}
cols += '</cols>';
return cols;
}
function buildRow(data, rowNum, styleNum) {
// Builds row XML.
//Params:
// data: Row data.
// rowNum: Excel row number.
// styleNum: style number or empty string for no style.
//Returns:
// String of XML formatted row.
var style = styleNum ? ' s="' + styleNum + '"' : '';
var row = '<row r="' + rowNum + '">';
for (i=0; i<data.length; i++) {
colNum = (i + 10).toString(36).toUpperCase(); // Convert to alpha
var cr = colNum + rowNum;
row += '<c t="inlineStr" r="' + cr + '"' + style + '>' +
'<is>' +
'<t>' + data[i] + '</t>' +
'</is>' +
'</c>';
}
row += '</row>';
return row;
}
function getTableData(groupName, title, button, dt) {
// Processes Datatable row data to build sheet.
//Params:
// dt: Datatable API.
// title: Title displayed at top of SS or empty str for no title.
//Returns:
// String of XML formatted worksheet.
//console.log('getTableData', groupName);
var dataSrc = getDataSrc( dt );
var header = getHeaderNames(dt);
var rowNum = 1;
var mergeCells = [];
var mergeCol = ((header.length - 1) + 10).toString(36).toUpperCase();
var ws = '';
var selectorModifier = {};
if (button.exportOptions.hasOwnProperty('modifier') ) {
selectorModifier = button.exportOptions.modifier;
}
ws += buildCols(header);
ws += '<sheetData>';
// Print button.title
if (button.title.length > 0) {
if (button.title === '*') {
button.title = document.getElementsByTagName("title")[0].innerHTML;
}
ws += buildRow([button.title], rowNum, 51);
mergeCells.push('<mergeCell ref="A' +rowNum + ':' + mergeCol + '' +rowNum + '"/>');
rowNum++;
}
// Print button.messageTop
if (button.messageTop.length > 0 && button.messageTop.length != '*') {
ws += buildRow([button.messageTop], rowNum, 51);
mergeCells.push('<mergeCell ref="A' +rowNum + ':' + mergeCol + '' +rowNum + '"/>');
rowNum++;
}
// All rows on one page with group names separating groups
if ( Array.isArray( groupName ) ) {
if (button.header) {
ws += buildRow(header, rowNum, 2);
rowNum++;
}
var currentGroup = '';
// Loop through each row to append to sheet.
table.rows(selectorModifier).every( function ( rowIdx, tableLoop, rowLoop ) {
var data = this.data();
if ( data[dataSrc] !== currentGroup ) {
currentGroup = data[dataSrc];
ws += buildRow([currentGroup], rowNum, 51);
mergeCells.push('<mergeCell ref="A' +rowNum + ':' + mergeCol + '' +rowNum + '"/>');
rowNum++;
}
// If data is object based then it needs to be converted
// to an array before sending to buildRow()
ws += buildRow(data, rowNum, '');
rowNum++;
} );
} else {
// Place each group on individual sheets
if ( title ) {
ws += buildRow([title], rowNum, 51);
mergeCells.push('<mergeCell ref="A' +rowNum + ':' + mergeCol + '' +rowNum + '"/>');
rowNum++;
}
if (button.header) {
ws += buildRow(header, rowNum, 2);
rowNum++;
}
// Loop through each row to append to sheet.
table.rows(
function ( idx, data, node ) {
return data[ dataSrc ] === groupName ?
true : false;
},
selectorModifier
).every( function ( rowIdx, tableLoop, rowLoop ) {
var data = this.data();
// If data is object based then it needs to be converted
// to an array before sending to buildRow()
ws += buildRow(data, rowNum, '');
rowNum++;
} );
}
// Output footer
if (button.footer) {
ws += buildRow(getFooterNames(dt), rowNum, 2);
rowNum++;
}
// Print button.messageBottom
if (button.messageBottom.length > 0 && button.messageBottom.length != '*') {
ws += buildRow([button.messageBottom], rowNum, 51);
mergeCells.push('<mergeCell ref="A' +rowNum + ':' + mergeCol + '' +rowNum + '"/>');
rowNum++;
}
mergeCellsElement = '';
if (mergeCells) {
mergeCellsElement = '<mergeCells count="' + mergeCells.length + '">'+
mergeCells +
'</mergeCells>';
}
ws += '</sheetData>' + mergeCellsElement;
return ws;
}
function setSheetName(xlsx, name) {
// Changes tab title for sheet.
//Params:
// xlsx: xlxs worksheet object.
// name: name for sheet.
if (name.length > 0) {
var source = xlsx.xl['workbook.xml'].getElementsByTagName('sheet')[0];
source.setAttribute('name', name);
}
}
function addSheet(xlsx, groupName, title, name, sheetId, button, dt) {
//Clones sheet from Sheet1 to build new sheet.
//Params:
// xlsx: xlsx object.
// table: table ID.
// title: Title for top row or blank if no title.
// name: Name of new sheet.
// sheetId: string containing sheetId for new sheet.
//Returns:
// Updated sheet object.
//Add sheet2 to [Content_Types].xml => <Types>
//============================================
var source = xlsx['[Content_Types].xml'].getElementsByTagName('Override')[1];
var clone = source.cloneNode(true);
clone.setAttribute('PartName','/xl/worksheets/sheet' + sheetId + '.xml');
xlsx['[Content_Types].xml'].getElementsByTagName('Types')[0].appendChild(clone);
//Add sheet relationship to xl/_rels/workbook.xml.rels => Relationships
//=====================================================================
var source = xlsx.xl._rels['workbook.xml.rels'].getElementsByTagName('Relationship')[0];
var clone = source.cloneNode(true);
clone.setAttribute('Id','rId'+sheetId+1);
clone.setAttribute('Target','worksheets/sheet' + sheetId + '.xml');
xlsx.xl._rels['workbook.xml.rels'].getElementsByTagName('Relationships')[0].appendChild(clone);
//Add second sheet to xl/workbook.xml => <workbook><sheets>
//=========================================================
var source = xlsx.xl['workbook.xml'].getElementsByTagName('sheet')[0];
var clone = source.cloneNode(true);
clone.setAttribute('name', name);
clone.setAttribute('sheetId', sheetId);
clone.setAttribute('r:id','rId'+sheetId+1);
xlsx.xl['workbook.xml'].getElementsByTagName('sheets')[0].appendChild(clone);
//Add sheet2.xml to xl/worksheets
//===============================
var newSheet = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+
'<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" mc:Ignorable="x14ac">'+
getTableData(groupName, title, button, dt) +
'</worksheet>';
xlsx.xl.worksheets['sheet' + sheetId + '.xml'] = $.parseXML(newSheet);
}
function updateSheet1(xlsx, groupName, title, button, dt) {
//console.log('updateSheet', groupName);
// Get number of columns to remove last hidden index column.
var numColumns = dt.columns().header().count();
var newSheet = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+
'<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" mc:Ignorable="x14ac">'+
getTableData(groupName, title, button, dt) +
'</worksheet>';
// Get sheet.
var sheet = xlsx.xl.worksheets['sheet1.xml'] = $.parseXML(newSheet);
if ( Array.isArray( groupName ) ) {
setSheetName( xlsx, button.sheetName ? button.sheetName : document.getElementsByTagName("title")[0].innerHTML );
} else {
setSheetName( xlsx, groupName );
}
}
function getDataSrc(dt) {
// Return the RowGroup dataSrc
var dataSrc = dt.rowGroup().dataSrc();
// If multi level use only the first level
if ( Array .isArray( dataSrc ) ) {
dataSrc = dataSrc[0];
}
return dataSrc;
}
var table = $('#example').DataTable({
rowGroup: {
dataSrc: 2
},
order: [[2, 'asc']],
dom: 'Bfrtip',
buttons: [
{
extend: 'excelHtml5',
messageTop: 'This is the top',
messageBottom: 'This is the bottom',
footer: true
},
{
extend: 'excelHtml5',
text: 'RowGroup Excel',
// Options supported by RowGroup customize function
title: '',
header: true,
messageTop: 'This is the top',
messageBottom: 'This is the bottom',
sheetName: 'Single Sheet',
footer: true,
exportOptions: {
modifier: {
search: 'applied',
}
},
customize: function( xlsx, button, dt ) {
//console.log(button);
multiSheet = true; // Export all groups in one sheet or multiple
var dataSrc = getDataSrc( dt );
// Get unique values from rowGroup.dataSrc column
var groupNames = [ new Set( dt.column( dataSrc ).data().toArray() )];
//console.log('Groups:', groupNames);
if (multiSheet) {
// Export each group in their own sheet
var sheetId = 1;
// Get row data belonging to each group
groupNames.forEach(function (groupName, index) {
if (sheetId === 1) {
// First sheet is already built, just update it
updateSheet1( xlsx, groupName, groupName, button, dt );
} else {
// Create new sheet for remaining groups
addSheet( xlsx, groupName, groupName, groupName, sheetId, button, dt );
}
sheetId++;
});
} else {
// All groups shown on one page
updateSheet1( xlsx, groupNames, '', button, dt );
}
},
}]
});
});
You can jump to the latest bin by adding /latest
to your URL
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + [ | Indents selected lines |
ctrl + ] | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Clone Bin |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |