I want to add custom data attribute(data-sheetname - in my case) as a title before every table while exporting it to the PDF using PDFMake. I've written a code that is generating a pdf for multiple tables in a single PDF sheet but I want to add titles before every table. Also there is no gapping after every table. So, want to add that too.
This is how my 3 tables in a PDF looks like:
Attaching my code:
$(document).ready( function() {
var tables = document.querySelectorAll('.data-table');
var tableArr = [];
var tableContent = [];
tables.forEach((element, index) => {
$(element).DataTable();
tableArr.push(element.dataset.sheetname);
});
$('#ExportPdf').click(function(){
var config = {
className:"buttons-pdf buttons-html5",
customize:null,
download:"download",
exportOptions:{
format: {
header: function (data, column, node){
if(node.dataset.exportname != null){
return node.dataset.exportname;
}
return data;
},
body: function (data, row, column, node) {
if(node.dataset.exportname != null){
return node.dataset.exportname;
}
return data;
}
}
},
extension:".pdf",
filename:"*",
header:true,
namespace:".dt-button-2",
orientation:"portrait",
pageSize:"A4",
title:"*"
};
var tablesConverted = {};
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: "lightHorizontalLines",
});
});
var doc = {
pageSize: config.pageSize,
pageOrientation: config.orientation,
content: tableContent,
styles: {
tableHeader: {
bold: true,
fontSize: 11,
color: 'white',
fillColor: '#2d4154',
alignment: 'left',
},
tableBodyEven: {},
tableBodyOdd: {
fillColor: '#f3f3f3'
},
tableFooter: {
bold: true,
fontSize: 11,
color: 'white',
fillColor: '#2d4154'
},
title: {
alignment: 'center',
fontSize: 15
},
message: {}
},
defaultStyle: {
fontSize: 10
}
};
if ( config.customize ) {
config.customize( doc, config );
}
pdfMake.createPdf(doc).download('optionalName.pdf');
});
});
<style>
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;
}
</style>
<!-- jQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Body -->
<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">Company1</th>
<th data-exportname="Contact">Contact1</th>
<th data-exportname="Country">Country1</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>
I think your code only needs two small changes:
Spacing:
You can add spacing between the tables by using margins. For example:
tableContent.push({
table: {
headerRows: 1,
body: rows
},
margin: [ 0, 2, 0, 20 ], // left, top, right, bottom
layout: "lightHorizontalLines",
});
Headings:
You can add the table headings by pushing them into your tableContent
array before you push the main table data:
// my new code:
tableContent.push(
{
text: tableArr[index]
}
);
// your existing code:
tableContent.push({
table: {
headerRows: 1,
body: rows
},
// etc...
(You already have the headings in your tableArr
array, so I used those.)
The end result is:
You can add more styles to the headings, of course - and adjust the margins as you prefer.
I am sure there are probably several different ways you could solve this. But I think this is one of the simpler approaches.