I want to export multiple data tables into a single PDF file using PDFMake.
I’ve modified my code to generate PDF for multiple tables by taking reference from Here.
But In my case the PDF is generating only for one table(last table) even though I tried to generate the content for 2 tables statically.
I want to use a way using which I can be able to export a single PDF for multiple data tables as my tables are going to be generated dynamically that means I don’t know how much tables are going to be formed.
Attaching my code:
$(document).ready( function() {
var tables = document.querySelectorAll('.data-table');
//alert(tables[0].dataset.sheetname);
var tableArr = [];
tables.forEach((element, index) => {
$(element).DataTable();
tableArr.push(element.dataset.sheetname);
//alert(element.dataset.sheetname);
});
$('#ExportPdf').click(function(){
var config = {
className:"buttons-pdf buttons-html5",
customize:null,
download:"download",
exportOptions:{},
extension:".pdf",
filename:"*",
header:true,
namespace:".dt-button-2",
orientation:"portrait",
pageSize:"A4",
title:"*"
};
var tablesConverted = {};
tables.forEach((element, index) => {
var dataTable = $(element).DataTable();
//alert(element.dataset.sheetname);
var data = dataTable.buttons.exportData( config.exportOptions );
var info = dataTable.buttons.exportInfo( config );
var rows = [];
if (config.header) {
rows.push($.map(data.header, function (d) {
return {
text: typeof d === 'string' ? d : d+'',
style: 'tableHeader'
};
}));
}
for (var i=0, ien=data.body.length ; i<ien ; i++ ) {
rows.push($.map(data.body[i], function ( d ) {
return {
text: typeof d === 'string' ? d : d+'',
style: i % 2 ? 'tableBodyEven' : 'tableBodyOdd'
};
}));
}
tablesConverted[tables[index]]=rows;
});
console.log(tablesConverted);
var doc = {
pageSize: config.pageSize,
pageOrientation: config.orientation,
content: [
{
table: {
headerRows: 1,
body: tablesConverted[tables[1]],
},
layout: 'noBorders',
},
{
table: {
headerRows: 2,
body: tablesConverted[tables[2]],
},
layout: 'noBorders',
},
],
styles: {
tableHeader: {
bold: true,
fontSize: 11,
color: 'white',
fillColor: '#2d4154',
alignment: 'center'
},
tableBodyEven: {},
tableBodyOdd: {
fillColor: '#f3f3f3'
},
tableFooter: {
bold: true,
fontSize: 11,
color: 'white',
fillColor: '#2d4154'
},
title: {
alignment: 'center',
fontSize: 15
},
message: {}
},
defaultStyle: {
fontSize: 10
}
};
pdfMake.createPdf(doc).download('optionalName.pdf');
});
});
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
<button id="ExportPdf" type="button">Export All</button>
<table class="data-table" data-sheetname="Table 1" id="table-1">
<thead>
<tr>
<th data-exportname="Company">Company</th>
<th data-exportname="Contact">Contact</th>
<th data-exportname="Country">Country</th>
</tr>
</thead>
<tbody>
<tr>
<td data-exportname="Alfreds Futterkiste">Alfreds Futterkiste</td>
<td data-exportname="Maria Anders">Maria Anders</td>
<td data-exportname="Germany">Germany</td>
</tr>
<tr>
<td data-exportname="Centro comercial Moctezuma">Centro comercial Moctezuma</td>
<td data-exportname="Francisco Chang">Francisco Chang</td>
<td data-exportname="Mexico">Mexico</td>
</tr>
<tr>
<td data-exportname="Ernst Handel">Ernst Handel</td>
<td data-exportname="Roland Mendel">Roland Mendel</td>
<td data-exportname="Austria">Austria</td>
</tr>
</tbody>
</table>
<br>
<table class="data-table" data-sheetname="Table 2">
<thead>
<tr>
<th data-exportname="Company">Company</th>
<th data-exportname="Contact">Contact</th>
<th data-exportname="Country">Country</th>
</tr>
</thead>
<tbody>
<tr>
<td data-exportname="Alfreds Futterkiste">Alfreds Futterkiste</td>
<td data-exportname="Maria Anders">Maria Anders</td>
<td data-exportname="Germany">Germany</td>
</tr>
</tbody>
</table>
<br>
<table class="data-table" data-sheetname="Table 3">
<thead>
<tr>
<th data-exportname="Company">Company</th>
<th data-exportname="Contact">Contact</th>
<th data-exportname="Country">Country</th>
</tr>
</thead>
<tbody>
<tr>
<td data-exportname="Centro comercial Moctezuma">Centro comercial Moctezuma</td>
<td data-exportname="Francisco Chang">Francisco Chang</td>
<td data-exportname="Mexico">Mexico</td>
</tr>
<tr>
<td data-exportname="Ernst Handel">Ernst Handel</td>
<td data-exportname="Roland Mendel">Roland Mendel</td>
<td data-exportname="Austria">Austria</td>
</tr>
</tbody>
</table>
>Solution :
Create an array to store the PDF content for each table:
var tableContent = [];
Inside the table loop, generate the PDF content for each table using the code you already have and store it in the tableContent array:
tables.forEach((element, index) => {
var dataTable = $(element).DataTable();
var data = dataTable.buttons.exportData(config.exportOptions);
var info = dataTable.buttons.exportInfo(config);
var rows = [];
if (config.header) {
rows.push(
$.map(data.header, function(d) {
return {
text: typeof d === "string" ? d : d + "",
style: "tableHeader",
};
})
);
}
for (var i = 0, ien = data.body.length; i < ien; i++) {
rows.push(
$.map(data.body[i], function(d) {
return {
text: typeof d === "string" ? d : d + "",
style: i % 2 ? "tableBodyEven" : "tableBodyOdd",
};
})
);
}
tableContent.push({
table: {
headerRows: 1,
body: rows,
},
layout: "noBorders",
});
});
Once you have generated the PDF content for all tables, create a PDF document containing all the tables using the tableContent array:
var doc = {
pageSize: config.pageSize,
pageOrientation: config.orientation,
content: tableContent,
styles: {
// ...
},
defaultStyle: {
fontSize: 10,
},
};
pdfMake.createPdf(doc).download("optionalName.pdf");
With this updated code, you will be able to generate a PDF document containing all the tables dynamically.