Angular 15 : How to Download HTML Section to PDF File?

When developing web applications, you might have come across a scenario where you need to allow users to download specific content of a PDF file.

In this tutorial, we will go through the process of downloading a Div container in HTML to a PDF file using an Angular application. Follow along as we cover each step, from setting up the Angular project to testing the final implementation.

Why Download a Div Container as a PDF in Angular?

Providing a feature to download a specific portion of a webpage as a PDF can be quite useful, especially when dealing with reports, invoices, or other printable documents. In Angular can easily achieve this task by using the npm modules like jsPDF and html2canvas.

 

How to Create PDF of HTML Div Container in Angular?

Follow these quick steps to download the PDF file of any HTML container on the page:

Step 1 – Setting Up the Angular Project
Step 2 – Styling the Div Container
Step 3 – Installing Dependencies
Step 4 – Integrating jsPDF and html2canvas
Step 5 – Creating the PDF Download Function
Step 6 – Adding the Download Button
Step 7 – Run the Angular App

 

Setting Up the Angular Project

To get started, create a new Angular project using the Angular CLI:

ng new div-to-pdf
cd div-to-pdf

Adding the HTML Template

In the app.component.html file, add a Div container that contains the content you want to convert to a PDF file:

<div id="content-to-download">
  <h1>My PDF Content - FreakyJolly.com</h1>
  <p>This is the content that will be downloaded as a PDF file.</p>
  <img src="../assets/logo.png" alt="" srcset="">
</div>

<button (click)="downloadPdf()">Download PDF</button>

 

Styling the Div Container

Style the Div container as you desire in the app.component.scss file:

#content-to-download {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  border: 1px solid #000;
  font-family: Arial, sans-serif;
}

 

Installing Dependencies

We will be using two libraries to help us with this task: jsPDF and html2canvas. Install them by running:

npm install jspdf html2canvas

Integrating jsPDF and html2canvas

In the app.component.ts file, import the libraries:

import { jsPDF } from 'jspdf';
import html2canvas from 'html2canvas';

 

Creating the PDF Download Function

To create the PDF download function, follow these steps:

  1. Capturing the Div Container: Get a reference to the Div container using its id attribute:
const content = document.getElementById('content-to-download');
  1. Converting the Div to a Canvas: Use the `html2canvas` function to convert the Div container into a canvas element:
html2canvas(content).then(canvas => {
  // Code to export the canvas as a PDF
});

 

  1. Exporting the Canvas as a PDF: Create a new jsPDF instance and add the canvas to it. Then, save the PDF file:
html2canvas(content).then((canvas) => {
      const pdf = new jsPDF('p', 'mm', 'a4');
      const imgData = canvas.toDataURL('image/png');
      const imgProps = pdf.getImageProperties(imgData);
      const pdfWidth = pdf.internal.pageSize.getWidth();
      const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;

      pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
      pdf.save('content.pdf');
    });

 

Adding the Download Button

In the app.component.html file, add a button that triggers the PDF download function when clicked:

<button (click)="downloadPdf()">Download PDF</button>

And in the app.component.ts file, add the downloadPdf method:

downloadPdf() {
    const content = document.getElementById('content-to-download');
    if (!content) {
      console.error('Element not found!');
      return;
    }
    html2canvas(content).then((canvas) => {
      const pdf = new jsPDF('p', 'mm', 'a4');
      const imgData = canvas.toDataURL('image/png');
      const imgProps = pdf.getImageProperties(imgData);
      const pdfWidth = pdf.internal.pageSize.getWidth();
      const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;

      pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
      pdf.save('content.pdf');
    });
  }

Run the Angular App

Run the Angular application using the command ng serve and open it in your browser. Click the “Download PDF” button to test if the Div container is successfully downloaded as a PDF file.

 

The above function is generating the PDF file, where you will notice a few issues as shown below:

There is no padding around content in the downloaded PDF.
The content of the PDF is a bit blurry, it’s of less quality.

 

How to Add Padding and Increase the quality of the PDF generated?

 

To add padding around the content in the PDF file and improve the quality of the PDF content, we will make a few changes to the downloadPdf() method.

1) Add padding to the canvas

Define the padding values for the top, right, bottom, and left sides.

const paddingTop = 50;
const paddingRight = 50;
const paddingBottom = 50;
const paddingLeft = 50;

2) Adjust the canvas size to include the padding

const canvasWidth = canvas.width + paddingLeft + paddingRight;
const canvasHeight = canvas.height + paddingTop + paddingBottom;

3) Create a new canvas with the adjusted size and draw the original canvas onto the new canvas with the specified padding

const newCanvas = document.createElement('canvas');
newCanvas.width = canvasWidth;
newCanvas.height = canvasHeight;
const ctx = newCanvas.getContext('2d');

if (ctx) {
  ctx.fillStyle = '#ffffff'; // Background color
  ctx.fillRect(0, 0, canvasWidth, canvasHeight);
  ctx.drawImage(canvas, paddingLeft, paddingTop);
}

4) We can Increase the quality of the rendered content by setting the scale option when calling html2canvas. A higher value will result in better quality but it may increase the processing time:

html2canvas(content, { scale: 3 }).then(canvas => {
  // ...
});

The updated downloadPdf() function will look like this:

downloadPdf() {
    const content = document.getElementById('content-to-download');

    if (!content) {
      console.error('Element not found!');
      return;
    }

    html2canvas(content, { scale: 3 }).then((canvas) => {
      const paddingTop = 50;
      const paddingRight = 50;
      const paddingBottom = 50;
      const paddingLeft = 50;

      const canvasWidth = canvas.width + paddingLeft + paddingRight;
      const canvasHeight = canvas.height + paddingTop + paddingBottom;

      const newCanvas = document.createElement('canvas');
      newCanvas.width = canvasWidth;
      newCanvas.height = canvasHeight;
      const ctx = newCanvas.getContext('2d');

      if (ctx) {
        ctx.fillStyle = '#ffffff'; // Background color
        ctx.fillRect(0, 0, canvasWidth, canvasHeight);
        ctx.drawImage(canvas, paddingLeft, paddingTop);
      }

      const pdf = new jsPDF('p', 'mm', 'a4');
      const imgData = newCanvas.toDataURL('image/png');
      const imgProps = pdf.getImageProperties(imgData);
      const pdfWidth = pdf.internal.pageSize.getWidth();
      const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;

      pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
      pdf.save('content.pdf');
    });
  }

This will create a PDF file as shown below with padding around content and increased content quality:

 

Conclusion

In this article, we’ve demonstrated how to download a Div container in HTML to a PDF file using an Angular application. By utilizing the jsPDF and html2canvas libraries, we’ve made it possible to convert specific content on a webpage into a downloadable PDF document.

 

FAQs

 

Can I download multiple Div containers in a single PDF?

Yes, you can capture multiple Div containers and add them to the PDF as separate pages or combine them into a single canvas before exporting.

 

Can I apply page breaks to the PDF?

Yes, you can use the jsPDF methods such as addPage to create new pages and manage the content accordingly.

 

How can I change the PDF orientation to landscape?

To change the orientation, modify the first argument in the jsPDF constructor from 'p' (portrait) to 'l' (landscape).

 

Can I use this approach with other frontend frameworks like React or Vue.js?

Yes, the process is similar for other frameworks. You’ll need to adapt the code to work with the specific framework’s syntax and structure.

 

Is it possible to download the PDF with a specific filename? Yes, you can pass the desired filename as an argument to the save method of the jsPDF instance, e.g., pdf.save('my-custom-filename.pdf').

Leave a Comment

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