Generating reports, invoices, blog content, documents, guidelines, forms, etc in PDF form is a common use case of any business application.
In this article, we will use JavaScript Library to generate PDF in the browser.
In this article, we will use PDFMake to export a PDF in an angular application. We will create the Invoice Generator Angular application with PDFMake. In this app, We will get the invoice details from the form and generate the PDF.
Before we start with application development let’s see an introduction about PDFMake.
PDFMake is a popular client-side and server-side pdf generation javascript library. It provides various features like adding tables, columns, lists, links, images, styling, headers/footers, document meta-information, and all other important PDF generation features.
It also provides some extraordinary features like adding QR Code, Watermark, Table of Content, Encryption and Access Privileges.
PDFMake has around 9.8 K stars and 1.8 K forks on GitHub.
Now, let’s see How to generate PDF with PDFMake in Angular using the Invoice Generator demo application.
Let’s start with a step-by-step implementation of client-side pdf generation in angular.
We will create a new angular application using the following Angular CLI command.
Note: If you want to generate PDF in your existing application then skip this step.
ng new [application-name]
Execute the following command to Install the PDFMake library.
npm install --save pdfmake
Once it is installed, to use PDFMake in the browser we need to import pdfmake.js and vfs_fonts.js file. Add the following statements on top of the component or service where you want to use PDFMake.
In our application, we will generate a PDF in the AppComponent . So we will add the following two statements on top of the AppComponent .
import pdfMake from "pdfmake/build/pdfmake"; import pdfFonts from "pdfmake/build/vfs_fonts"; pdfMake.vfs = pdfFonts.pdfMake.vfs;
PDFMake follows the declarative approach. It means you’ll never have to calculate positions manually or use commands like writeText(text, x, y) , moveDown etc…, as you would with a lot of other libraries. – From PDFMake Official Document
The most fundamental concept to be mastered is the document definition object. The document definition object is a kind of JSON object where you provide all your PDF configuration with different keys. Like content, column, table, ul, image, style, etc.
For example, we can generate a simple PDF with header and content as follows
import < Component >from '@angular/core'; import pdfMake from "pdfmake/build/pdfmake"; import pdfFonts from "pdfmake/build/vfs_fonts"; pdfMake.vfs = pdfFonts.pdfMake.vfs; export class AppComponent < generatePDF() < let docDefinition = < header: 'C#Corner PDF Header', content: 'Sample PDF generated with Angular and PDFMake for C#Corner Blog' >; pdfMake.createPdf(docDefinition).open(); > >
In generatePDF() we have added a simple document definition object to generate a simple PDF. pdfMake has createPdf(docDefinition) method to create PDF from document definition object and open() method to open created PDF in browser. It also has other inbuilt methods to download and print PDFs.
pdfMake.createPDF(docDefinition).open(); pdfMake.createPDF(docDefinition).download(); pdfMake.createPDF(docDefinition).print();
If you can generate this PDF then Great ✨✨✨. You have successfully set up the PDFMake in Angular application. If you are facing any issue then check the above steps again, if it is not resolved comment in the below comment section.
Our basic application setup is done. Now let’s start with building an invoice generator application.
We will first design the invoice form in app.component.html, from where we will get the customer details, order details, and additional details.
This page will also have three buttons – Download Invoice, Print Invoice, and Open Invoice.
NameAddressEmail IDContact No.Order DetailsProduct Price Quantity Amount Download Invoice
We will create an invoice object in AppComponent and bind it with invoice form using two-way data binding. We will add addProduct() method to add product in invoice and update generatePdf() method to get action argument and execute the related pdfMake method.
/*** app.component.ts ***/ // . class Product < name: string; price: number; qty: number; >class Invoice < customerName: string; address: string; contactNo: number; email: string; products: Product[] = []; additionalDetails: string; constructor()< // Initially one empty product row we will show this.products.push(new Product()); >> @Component(< selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] >) export class AppComponent < invoice = new Invoice(); generatePDF(action = 'open') < let docDefinition = < header: 'C#Corner PDF Header', content: 'Sample PDF generated with Angular and PDFMake for C#Corner Blog' >; if(action==='download')< pdfMake.createPdf(docDefinition).download(); >else if(action === 'print')< pdfMake.createPdf(docDefinition).print(); >else < pdfMake.createPdf(docDefinition).open(); >> addProduct() < this.invoice.products.push(new Product()); >>
Now let’s configure the document definition object to generate the PDF in the required layout and format.
We will update docDefinition object in generatePDF() method as below to show Invoice Header. To add multiple lines in PDF, we can use the content property of the document definition object as an array form, as shown below. We have also added some styling here.
let docDefinition = < content: [ < text: 'ELECTRONIC SHOP', fontSize: 16, alignment: 'center', color: '#047886' >, < text: 'INVOICE', fontSize: 20, bold: true, alignment: 'center', decoration: 'underline', color: 'skyblue' >>
The way we write common CSS with .class in CSS file, and apply it at multiple places on HTML file, in the same way pdfMake allows us to create common styles, which we can use on multiple lines. For example, we will create here a section header line and create a common style for the same.
let docDefinition = < content: [ // Previous configuration < text: 'Customer Details', style: 'sectionHeader' >], styles: < sectionHeader: < bold: true, decoration: 'underline', fontSize: 14, margin: [0, 15, 0, 15] >> >
As you can see here, we have created a common style in styles property of document definition object and used it on customer details line with the style property.
We can add columns in pdf with columns property of PDFMake as shown below. For this application we will create two columns, in one column we will show customer details and in another column, we will show the current date and random bill number.
let docDefinition = < content: [ // Previous configuration < columns: [ [ < text: this.invoice.customerName, bold: true >, < text: this.invoice.address >, < text: this.invoice.email >, < text: this.invoice.contactNo >], [ < text: `Date: $`, alignment: 'right' >, < text: `Bill No : $<((Math.random() * 1000).toFixed(0))>`, alignment: 'right' > ] ] >, ], // Common Styles >
We can create a table in PDF with table property of the document definition object. We will show order products in table form as shown below :
let docDefinition = < content: [ // Previous configuration < text: 'Order Details', style: 'sectionHeader' >, < table: < headerRows: 1, widths: ['*', 'auto', 'auto', 'auto'], body: [ ['Product', 'Price', 'Quantity', 'Amount'], . this.invoice.products.map(p =>([p.name, p.price, p.qty, (p.price * p.qty).toFixed(2)])), [< text: 'Total Amount', colSpan: 3 >, <>, <>, this.invoice.products.reduce((sum, p) => sum + (p.qty * p.price), 0).toFixed(2)] ] > > ], // Common Styles >
We can add the QR Code in a row with qr property as shown below, In our application, QR Code will be generated from customerName .
let docDefinition = < content: [ // Previous Configuration < columns: [ [< qr: `$`, fit: '50' >], [< text: 'Signature', alignment: 'right', italics: true >], ] >, ], // Common Styles >
We can add the unordered and ordered list in PDF with ul and ol property of PDFMake document definition object. We will create a terms and conditions list as below,
let docDefinition = < content: [ // Previous Configuration < ul: [ 'Order can be return in max 10 days.', 'Warrenty of the product will be subject to the manufacturer terms and conditions.', 'This is system generated invoice.', ], >], // Common Styles >
Great ✨✨✨ We are done with Invoice Generator Implementation.
If you feel this application is useful to you, give us a ⭐ on GitHub.
Check out the live running application: Angular PDFMake Invoice Generator
In this article, we have discussed the various approaches to generating a PDF in an application. We have implemented the Invoice Generator application to demonstrate client-side pdf generation in angular with pdfmake.
I hope you like this article. Give your valuable feedback and suggestions in the below comment section.
December 4, 2017
July 23, 2020
August 25, 2019
I am a Full Stack Developer, Blogger and Open-Source Contributor. Nowadays, majorly working on Front End Technologies.