I have a table in Jquery Datatables which has child and grandchild tables (A table with subtables that in turn have subtables) the table is formed as follows:
function cargarTabla() {
//Función interna para realizar un ajax y obtener las columnas
mvc.Datos.GetColumnas.post({ IdTabla: idTabla }, res => {
var datos = res;
datos = JSON.parse(datos);
var ruta = idTabla != 17 ? "/Datos/GetDatosPorPuesto?idPuesto=" + idPuesto : "/Datos/GetDatosDocumentacion?idLinea=" + idLinea;
table = $('#tablaDatos').DataTable({
"ajax": {
url: ruta,
dataSrc: function (data) {
return JSON.parse(data);
}
},
"bDestroy": true,
"language": {
"url": "//cdn.datatables.net/plug-ins/1.10.16/i18n/Spanish.json"
}, select: {
style: 'multi'
},
"iDisplayLength": 10,
"columns":
datos
,
"order": [[3, 'desc']],
"fnDrawCallback": function (oSettings) {
runAllCharts();
},
"columnDefs": [{
"render": function (data, type, row) {
return (data == 1) ? '<center><i class="fa fa-check"></i></center>' : ' <center><i class="fa fa-minus"></i></center>';
},
}]
});
//botones personalizados para exportacion
var buttons = new $.fn.dataTable.Buttons(table, {
buttons: [
{
exportOptions: {
columns: [ 1, 2, 3, 4, 5, 6,7,8,9,10,11,12]
},
orientation: 'landscape',
title: '',
text: '<i class="fa fa-3x fa-file-code" style="padding: 3px 3px 3px 3px"></i>',
className: 'btn btn-default jarvismetro-tile txt-color-white btnTablas',
attr: {
style: 'background-color:#203864;display:none',
id: 'exportJSON'
},
action: function (e, dt, button, config) {
var data = dt.buttons.exportData();
$.fn.dataTable.fileSave(
new Blob([JSON.stringify(data)]),
'Export.json'
);
}
},
{
exportOptions: {
columns: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
},
title: '',
extend: 'excel',
text: '<i class="fa fa-3x fa-file-excel" style="padding: 3px 3px 3px 3px"></i>',
className: 'btn btn-default jarvismetro-tile txt-color-white btnTablas',
attr: {
style: 'background-color:#203864;display:none',
id: 'exportXls'
}
}
]
}).container().appendTo($('#buttons'));
});
}
cargarTabla();
function to generate the subtable and the subsubtable:
$('#tablaDatos').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
try {
var d = row.data();
var parametros = d.Registros;
nieto = parametros;
var subtabla;
subtabla = '<table id = "child_details" cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<thead><tr>' +
'<th></th>' +
'<th>campo1</th>' +
'<th>campo2</th>' +
'<th>campo3</th>' +
'<th>campo4</th>' +
'<th>campo5</th>' +
'<th>campo6</th>' +
'<th class="hide">campo7</th>' +
'</tr></thead><tbody>';
$.each(parametros, function (index, value) {
subtabla += '<tr><td class="details-control"></td>';
subtabla += '<td>' + value.campo1 + '</td>';
subtabla += '<td>' + value.campo2 + '</td>';
subtabla += '<td>' + value.campo3 + '</td>';
subtabla += '<td>' + value.campo4 + '</td>';
subtabla += '<td>' + value.campo5 + '</td>';
//valores de la tabla nieta
subtabla += '<td class="hide">' + value.campo6 + '</td>';
subtabla += '<td>' + value.campo7 + '</td>';
});
subtabla += '</tbody></table>';
row.child(subtabla).show();
childTable = $('#child_details').DataTable({
searching: false,
paging: false,
info: false,
destroy: true
});
childTable
.on('select', function (e, dt, type, indexes) {
if (type === 'row') {
var data = childTable.rows(indexes).data();
// do something with the ID of the selected items
}
});
tr.addClass('shown');
} catch {
var d = childTable.row($(this).closest('tr')).data();
var parametros = JSON.parse(d[6]);
$.each(parametros, function (index, value) {
console.log(index, value);
if (index == "Aprietes") {
nieceTable = '<table id = "niece_details" cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<thead></thead><tbody>' +
'<tr><td>Apriete:</td>';
$.each(value, function () {
nieceTable += '<td>' + this.APRIETE + '</td>';
});
nieceTable += '</tr><tr><td>Par:</td>';
$.each(value, function () {
nieceTable += '<td>' + this.PAR + '</td>';
});
nieceTable += '</tr><tr><td>Angulo:</td>';
$.each(value, function () {
nieceTable += '<td>' + this.ANGULO + '</td>';
});
nieceTable += '</tr></tbody></table>';
} else {
nieceTable = '<table id = "niece_details" cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<thead><tr><th>Nombre</th><th>Valor</th></tr></thead><tbody>' +
'<tr><td>' + this.Title + '</td>' +
'<td> ' + this.Value + '</td>' +
'</tr></tbody></table>';
}
});
childTable.row($(this).closest('tr')).child(nieceTable).show();
var nieceTable = $('#niece_details').DataTable({
searching: false,
paging: false,
info: false,
destroy: true,
scrollY: '50px',
select: true,
});
nieceTable
.on('select', function (e, dt, type, indexes) {
if (type === 'row') {
var data = childTable.rows(indexes).data();
// do something with the ID of the selected items
}
});
tr.addClass('shown');
}
}
});
With this configuration, the export buttons are correctly shown to me, but when I press it, only the parent table is exported. I am using Html5 buttons To export I am using this library .
I have tried to get the child table through the action of the buttons with this but without success.
I can't do the same thing as the child table (add the fields hidden), I haven't been able to do it better.
How can I get the table and its respective subtables to be exported?
I am a more active user in the English speaking forum but today I decided to take a look around here, I must say that this took me a long time and that despite having done complex things in DataTables this was a headache but after a few how many cups of coffee and tests in jsfiddle I hope it will be useful.
JSON.stringify
to convert our object to a string in this way we can mold the data in the customizedData methodTo do this we must render on the cell that contains the child and grandchild elements in the columns section .
This element of our JSON contains the values of our child and grandchild table, here we indicate that we will return the encoded data when the type is of the export type and otherwise the default value of our icon will be displayed.
Finally, in the buttons section we must define the way in which the data will be modified, in this case I will show it as it would be seen if the child and grandchild tables were expanded, for this we created an array that would replace the body sub-array of our object.
In this section we must take into account that since the data attribute of our column is different from null , this will be taken into account to generate the document, so you can leave a space for each cell or add data so that the column that is equal to the number of record row.
Finally I did not decide to use the library that you mention in the question since I have never used it before and I preferred to use the libraries that DataTables provides to export.
I hope it helps, regards.