How to generate pdf in angular with the table and image from Client-side | Server-side

Pdf generate from angular with table images

To generate pdf from the client side with images. We need to convert the image to base 64. Let’s see how to convert images to base64 from our table data.

Example – My case table data look like:

tabledata = [{
    img: 'https://i.picsum.photos/id/258/536/354.jpg',
    name: 'Joseph',
    domain: 'Angular 9'
  },
  {
    img: 'https://i.picsum.photos/id/258/536/354.jpg',
    name: 'Vani',
    domain: 'Angular 8'
  }, {
    img: 'https://i.picsum.photos/id/258/536/354.jpg',
    name: 'Raj',
    domain: 'React.js'
  },
  ];

We need to convert the image  from Image URL to base64

Base64 conversion function code:

convertImagetoBase64(url, callback) {
    const xhr = new XMLHttpRequest();
    xhr.onload = () => {
      const reader = new FileReader();
      reader.onloadend = () => {
        callback(reader.result);
      };
      reader.readAsDataURL(xhr.response);
    };
    xhr.open('GET', url);
    xhr.responseType = 'blob';
    xhr.send();
  }

Let convert the image URL to base64 before we bind to the table in HTML.

  this.tabledata.forEach(elem => {
      this.convertImagetoBase64(elem.img, (b64Img) => {
        elem.img = b64Img;
      });

After that we applying to HTML. If you don’t want to show in HTML of pdf generation you can simply apply style display: none to the table but your table will generate in pdf.

I have a different table in HTML.

<style>
    td, th{
        border:1px solid #ccc;
        padding:10px 15px;
    }
</style>
 
<table id="pdfConvert">
    <thead>
        <tr><th>Head 1</th>
        <th>Head 2</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>value 00</td>
            <td>value 01</td>
        </tr>
        <tr>
            <td>value 10</td>
            <td>value 11</td>
        </tr>
    </tbody>
</table>
 
 
<table id="imgTable" style=”display:none”>
    <thead>
        <tr><th>Name</th>
        <th>Domain</th>
        <th>Image</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let data of tabledata">
            <td>{{data.name}}</td>
            <td>{{data.domain}}</td>
            <td><img src="{{data.img}}" width="100" height="100" /></td>
        </tr>
       
    </tbody>
</table>
 
<button (click)="generatePdf()">Generate Pdf</button>

Each table has a id. This id attribute is the reference for generating pdf.

Before Generation, we need to install 

npm install jspdf jspdf-autotable

For more reference: https://github.com/simonbengtsson/jsPDF-AutoTable

Let import the jspdf and jspdf-autoble to your .ts file

component.ts file:

import jsPDF from 'jspdf';
import 'jspdf-autotable';

Then generate pdf function look like:

generatePdf() {
    const doc = new jsPDF('l');
    // Heading
    doc.autoTable({
      columnStyles: {
        0: { cellWidth: 40, fillColor: '#fff', fontStyle: 'bold', fontSize: '11', textColor: '#000' },
        1: { cellWidth: 20, fillColor: '#fff', fontStyle: 'normal', fontSize: '11', textColor: '#fc0' },
        2: { fillColor: '#fff', fontStyle: 'normal', fontSize: '11', textColor: '#000' },
 
      }, // Cells in first column centered and green
      body: [
        ['Main Heading', 'Date', new Date()]
      ],
    });
    // Table 1
    doc.autoTable({
      html: '#pdfConvert'
    });
 
    // Table 2
    doc.autoTable({
      html: '#imgTable',
      bodyStyles: { minCellHeight: 20 },
      theme: 'grid',
      styles: { valign: 'middle', overflow: 'linebreak', halign: 'center', minCellHeight: 21 },
      pageBreak: 'avoid',
      columnStyles: {
        2: { cellWidth: 22, minCellHeight: 22 },
      },
      headStyles: { fillColor: '#f2f2f2', textColor: '#000', fontStyle: 'bold', lineWidth: 0.5, lineColor: '#ccc' },
      didDrawCell: (data) => {
        if (data.column.index === 2 && data.cell.section === 'body') {
          const td = data.cell.raw;
          const img = td.getElementsByTagName('img')[0];
          // let dim = data.cell.height - data.cell.padding('vertical');
          // let textPos = data.cell.textPos;
          doc.addImage(img.src, data.cell.x + 1, data.cell.y + 1, 19, 19);
 
        }
      }
    });
    // Table 3
    doc.autoTable({
      styles: { lineColor: 'red' },
      theme: 'grid',
      html: '#pdfConvert'
    });
 
    doc.save('yourpdfname.pdf');
 
  }

Then try to generate the pdf. 

Issue from cors policy.

Note: If you face any issue like the above image. This is just a CORS policy issue. This is about the image URL is not belongs to you. You don’t use the copyrighted image. Use your own image URL or some free lorem ipsum image URL.

Thanks for reading. I hope this will helpful to you. Have a nice day. If you have any queries your inputs are welcome in comment sections.

Leave a Reply

Your email address will not be published. Required fields are marked *