Build a JsPDF-Autotable Dynamic Rows & Columns HTML5 Tables Generator in PDF Document Using Javascript

Build a jsPDF-Autotable Dynamic Rows & Columns HTML5 Tables Generator in PDF Document Using Javascript

<h3>
  <div>jsPDF-AutoTable: Multi-section table</div>
  <div>Wrap table columns in the same page</div>
  <hr>
</h3>
 
<label>
  <b>Number of rows</b>
  <input type="number" id="rows" value="70">
</label>
 
<label>
  <b>Number of sections</b>
  <input type="number" id="sections" value="3">
</label>
 
<label>
  <b>Number of Tables</b>
  <input type="number" id="tables" value="3">
</label>
 
<button id="download">Download PDF</button>
<script>
// https://github.com/simonbengtsson/jsPDF-AutoTable/issues/626
function createRows(count) {
  const rows = [];
  for (let i = 1; i <= count; i++) {
    rows.push([i, `Name ${i}`, `Email ${i}`])
  }
  return rows;
}
 
function generatePDF() {
  const doc = new jsPDF('p', 'mm', 'a4');
 
    // overall margin
    const margin = {
      left: 15,
      right: 15,
      top: 20,
      bottom: 20,
    };
 
    const tablesCount = parseInt(document.getElementById('tables').value);
    const rowsCount = parseInt(document.getElementById('rows').value);
 
    // number of table sections in the page
    const sections = parseInt(document.getElementById('sections').value);
 
    // space between each section
    const spacing = 5;
 
    // calculate each section width
    const printWidht = doc.internal.pageSize.width - (margin.left + margin.right);
    const sectionWidth = (printWidht - ((sections - 1) * spacing)) / sections;
 
    // add an initial empty page that will be delete later,
    // it is needed for the first setPage(previous_page) call
    doc.addPage();
 
    let currentSection;
    let nextSection = 1;
    let startY = margin.top;
 
    for (let i = 0; i < tablesCount; i++) {
      doc.autoTable({
        theme: i % 2 ? 'grid' : 'striped',
        head: [['ID', 'Name', 'Email']],
        body: createRows(rowsCount),
        tableWidth: sectionWidth,
        margin: {
          left: margin.left + ((nextSection - 1) * (sectionWidth + spacing)),
          top: margin.top,
          bottom: margin.bottom,
        },
        startY,
        rowPageBreak: 'avoid', // avoid breaking rows into multiple sections
        didDrawPage({table, pageNumber, pageCount}) {
          currentSection = nextSection;
          nextSection = (nextSection % sections) + 1;
 
          // set left margin which will controll x position of next section
          const shift = (nextSection - 1) * (sectionWidth + spacing)
          table.settings.margin.left = margin.left + shift;
 
          // if next section is not the fist, move to previous page so when
          // autoTable calls addPage() it will still be the same current page
          if (nextSection > 1) {
            doc.setPage(doc.internal.getNumberOfPages() - 1);
          }
        }
      });
 
      // activate last page for further printing
      doc.setPage(doc.internal.getNumberOfPages());
 
      // if there's remaining vertical space in page: start printing next table from the current section
      const remainingVSpace = doc.internal.pageSize.height - margin.bottom - doc.lastAutoTable.finalY;
      if (remainingVSpace > 25) {
        nextSection = currentSection;
        startY = doc.lastAutoTable.finalY + 10;
      } else {
        startY = margin.top;
        if (nextSection == 1) doc.addPage();
      }
    }
    
    // delete unused empty page
    doc.deletePage(1);
 
  return doc;
}
 
document.getElementById("download").addEventListener('click', function() {
  generatePDF().save('multi-section table.pdf');
});
 
</script>

Share on:

Hi, I'm Ranjith a full-time Blogger, YouTuber, Affiliate Marketer, & founder of Coding Diksha. Here, I post about programming to help developers.

Leave a Comment