What is the best way to convert HTML to PDF using Angular?

Currently, I am working with Angular and I have a requirement to convert an HTML table into a PDF format. Below is the code snippet from my component.ts file:

downloadPDF() {
    const doc = new jsPDF();
    const specialElememtHandlers = {
        '#editor'(element, renderer) {
            return true;
        }
    };

    doc.fromHTML(this.content.nativeElement.innerHTML, 15, 15, {
        width: 190,
        elementHandlers: specialElememtHandlers
    });
    doc.save('test.pdf');
}

Here is my corresponding HTML code:

<button (click)="downloadPDF()">Save as PDF</button>

Although I can successfully download a PDF file, unfortunately, it appears completely white.

Answer №1

To begin, start by installing the following packages:

npm install jspdf

Next, you'll also need to install the html2canvas package.

npm install html2canvas

After installation, import these packages into your component using the import statement.

import * as jspdf from 'jspdf';  
import html2canvas from 'html2canvas'; 

In your TypeScript code:

import { Component, OnInit, ElementRef ,ViewChild} from '@angular/core';  
import * as jspdf from 'jspdf';  
import html2canvas from 'html2canvas';  

@Component({  
  selector: 'app-htmltopdf',  
  templateUrl: './htmltopdf.component.html',  
  styleUrls: ['./htmltopdf.component.css']  
})  
export class HtmltopdfComponent{  
  public captureScreen()  
  {  
    var data = document.getElementById('contentToConvert');  //Id of the table
    html2canvas(data).then(canvas => {  
      // Few necessary setting options  
      let imgWidth = 208;   
      let pageHeight = 295;    
      let imgHeight = canvas.height * imgWidth / canvas.width;  
      let heightLeft = imgHeight;  

      const contentDataURL = canvas.toDataURL('image/png')  
      let pdf = new jspdf('p', 'mm', 'a4'); // A4 size page of PDF  
      let position = 0;  
      pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight)  
      pdf.save('MYPdf.pdf'); // Generated PDF   
    });  
  }  
}

Answer №2

If you need to convert HTML templates to PDF, consider utilizing the 'PrintJS' library. Check out PrintJS here!

Answer №3

Start by installing the following package:

npm install jspdf
npm install <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cca4b8a1a0feafada2baadbf8cfde2fce2fce1ada0bca4ade2fdfe">[email protected]</a> //make sure to use this specific html2canvas version.

Next, import it into your component using the import statement(app.component.ts).

import * as jspdf from 'jspdf';  
import html2canvas from 'html2canvas'; 

Include in app.component.html

<div class="abc" id="content">
    <h1>Hello World!</h1>
    <button (click)="Screen()">Create PDF</button>
</div>

Now add functionality to app.component.ts

Screen()
{  
    var data = document.getElementById('content');  
    html2canvas(data).then(canvas => {  
        // Necessary settings  
        var imgWidth = 208;   
        var pageHeight = 295;    
        var imgHeight = canvas.height * imgWidth / canvas.width;  
        var heightLeft = imgHeight;  

        const contentDataURL = canvas.toDataURL('image/png')  
        let pdf = new jspdf('p', 'mm', 'a4'); // A4 size PDF page  
        var position = 0;  
        pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight)  
        pdf.save('MyPDF.pdf'); // Downloaded PDF   
    });  
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing Lodash debounce in VueJs watch feature while incorporating Typescript

When working with VueJS in Javascript, I can achieve the following: import debounce from "lodash/debounce"; ... watch: { variable: debounce(function() { console.log('wow'); }, 500) } However, when attempting to do the same in VueJS us ...

The ipcRenderer is failing to be activated

Looking to establish IPC communication between my React component and the main Electron process. Check out the code snippet below: export default class A extends React.Component{ ..... openFile = () => { console.log('test'); ipcRende ...

Navigating with dynamic angular2 routes?

I'm looking to redirect to another component using the path provided, but I also need to pass along the variable this.a. How can I accomplish this so that I can access the value of this variable in the other component? Component.ts import {Componen ...

Why is it that the changes I make in the parent component do not reflect in my Angular component?

As I embarked on creating a custom select component, I began with the input below: @Input() options: SelectOption<UserRole>[] = []; The parent component (user editor) utilizes this select component and provides the options as shown below: roleOption ...

After importing RxJS, the error "toPromise is not a function" is encountered

I am trying to utilize the Promise operator Firstly, I imported rxjs: import 'rxjs/add/operator/toPromise'; then in my component, I implemented it ngOnInit() { this.EJnames= this.dataservice.getResults(); this.generalinfosservice.get ...

Modify the view to display the router outlet as a sidebar

Hello, I am trying to figure out why I am unable to access a child route in my application. I have a sidebar where I want to display a list, and if I want to add or edit an item, I would like the view to change within the sidebar from the list to a form a ...

Troubleshooting Angular form validation and ngClass in the presence of multiple conditions

I need help applying the Bootstrap is-invalid class to a textarea when two specific conditions are met upon form submission. Below is the code I have so far. My HTML Code: <textarea class="form-control" rows="5" placeholder="Add Text" ...

Looking for a way to detect changes in a select menu using Angular?

How can I determine with the openedChange event if there have been any changes to the select box items when the mat select panel is closed or opened? Currently, I am only able to detect if the panel is open or closed. I would like to be able to detect any ...

The elements mat-toolbar, mat-sidenav, and mat-sidenav-container are unrecognized

I've encountered an issue while trying to implement mat-toolbar in my project: mat-menu.component.html: <mat-toolbar color="primary"> <span>Responsive Navigation</span> <span class="example-spacer"></span> < ...

Is there a way to incorporate an icon into the heading of an accordion-group in ngx-bootstrap?

Is it possible to include an icon in the heading of an accordion-group using ngx-bootstrap? For instance: <accordion-group heading="<i class='fa fa-users'></i> Users"> The content goes right in the template. </accordion ...

Making a synchronous call to a web API using JQuery

Understanding JQuery promises and deferred objects has been a bit of a challenge for me, so please bear with me. I should also mention that my application is built using React, Typescript, and ES6. Let's imagine we have an array of objects: [{ Objec ...

Describing an Object with some typed properties

Is there a method to specify only a portion of the object type, while allowing the rest to be of any type? The primary objective is to have support for intelliSense for the specified part, with the added bonus of type-checking support. To demonstrate, let& ...

The Http.get() function is running smoothly, yet encountering issues when it comes to functionality within the build (Release/Debug)

Currently, I am facing an issue with fetching data from a simple API. Strangely, the functionality works perfectly fine when testing in ionic serve (browser). However, upon building the app, the HTTP call fails to work. Below is the snippet of my code: th ...

Having trouble with Angular routing when attempting to directly access a specific URL path?

Seeking help with my routing setup in Angular. Using v12 of Angular. Encountering a 404 Not Found error when trying to access the direct URL for "register" at somesite.com/register. Uncertain if this is a server or Angular issue. Here is my router module ...

Webpack 5 is failing to bundle re-exports correctly

Whilst bundling my web application, I've come across an issue with re-exports of certain modules not behaving as expected. Despite trying various optimization settings, I have been unsuccessful in resolving this issue. Setup Here's the setup tha ...

An error occurred when trying to access object references within a function

Here is a snippet of my code: const fn1 = (param1: string, param2: string, param3: string): Promise<void> => {return new Promise()} const fn2 = (param1: string, param2: string): void => {return} const options = { option1: fn1, option2: ...

Angular 14 introduces a new feature that automatically joins open SVG paths when dynamically rendered from a data object

I developed an application to convert SVG code into a JSON object that can be stored in a database. Another app was created to dynamically display the rendered result on a webpage. The rendering output appears as shown in this image: https://i.sstatic.net/ ...

Checking to see if a method in an Angular component is invoked during ngOninit()?

I am working towards creating spies for specific methods and verifying that these methods are called during ngOninit when the pagePurpose is set to Update. Currently, I am setting up the spies and initializing the component property within the describe blo ...

In Typescript, try/catch blocks do not capture return values

I am currently working on a function that performs database operations, with the implementation contained within a try/catch block. Here is an example: async function update({id, ...changes}): Promise<IUserResult> { try { //insert code here retu ...

Optimal approach for designing interfaces

I have a situation where I have an object retrieved from the database, which includes assignee and author ID properties that refer to user objects. As I transform a number into a user object, I am unsure about the best practice for defining the type of the ...