javascriptjquerydatatableexport-to-pdfpdfmake

Add Custom Title of Table using before every table while exporting multiple tables in a single PDF file using PDFMake


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: enter image description here

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>


Solution

  • 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:

    enter image description here

    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.