Angular 9|8|7 Download PDF Files in Browser Instead of Opening in New Tab Quick Solution

In this Angular 9/8/7/6 tutorial, we’ll learn how to add download links for PDF files to download them in the file system instead of opening in a new tab.

In Angular application, we may have a form where a user can upload documents in PDF formats and also can view and download the same in view mode.

By default when we add a link to PDF files in HTML, they open in a new tab from a user can download. This behavior is common in Chrome and Mozilla which are the most used web browsers.

In this tutorial, we will discuss how to force download PDF files in the user’s file systems when we click on a link instead of opening it in a new Tab. Along with that, we will also learn a bonus tip on how we can open a PDF file in tab starting from a specified page number.

So let’s get started!

Here we assume that you already have an Angular project up & running, if not you can create a new Angular project using the Ng CLI tool.

Install FileSaver.js

To enable the download of PDF files, we need to install FileSaver package by running following NPM command in terminal:

$ npm install file-saver

After installing the above package, move to the component or service to create a method to download PDF files.

Here we have a basic component, where we will add a button to download PDF.

 

Import FileSaver using require()

In the basic.component.ts file first, add the following code at the top of the component class.

// basic.component.ts
import { Component, OnInit } from '@angular/core';

declare var require: any
const FileSaver = require('file-saver');

...
...

As we are importing file-saver class methods using require, we need to declare it with type any otherwise Typescript will throw an error as shown below:

ERROR in src/app/basic/basic.component.ts(3,19): error TS2591: Cannot find name ‘require’. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.

 

Download PDF Method

Now add the following method to download PDF links using FileSaver.saveAs() method:

  downloadPdf() {
    const pdfUrl = './assets/sample.pdf';
    const pdfName = 'your_pdf_file';
    FileSaver.saveAs(pdfUrl, pdfName);
  }

Above we have passed two arguments with the file path and file name.

 

You can dynamically pass both name and path in the method as well:

  downloadPdf(pdfUrl: string, pdfName: string ) {
    //const pdfUrl = './assets/sample.pdf';
    //const pdfName = 'your_pdf_file';
    FileSaver.saveAs(pdfUrl, pdfName);
  }

 

Download Link in HTML

Use in HTML directly:

<a 
  href="javascript:void(0)" 
  style="cursor:pointer"
  (click)="downloadPdf('./assets/sample.pdf','your_pdf_file')">
  Download PDF
</a>

 

Bonus Tip!

How to open PDFs in the viewer starting from the specified Page number?

You may have a view for PDF files as shown below:

To open a PDF file at specific page use #page=3 parameter after pdf file like:

https://file-examples.com/wp-content/uploads/2017/10/file-example_PDF_500_kB.pdf#page=3

// basic.component.ts
import { Component, OnInit } from '@angular/core';

declare var require: any
const FileSaver = require('file-saver');

@Component({
  selector: 'app-basic',
  templateUrl: './basic.component.html',
  styleUrls: ['./basic.component.css']
})
export class BasicComponent implements OnInit {

  pdfFiles = [
    {
      name:'PDF File One',
      startPage: 2,
      path: './assets/sample1.pdf'
    },
    {
      name:'PDF File Two',
      startPage: 4,
      path: './assets/sample2.pdf'
    },
    
  ]

  constructor() { }

  ngOnInit() {
  }

  downloadPdf(pdfUrl: string, pdfName: string ) {
    //const pdfUrl = './assets/sample.pdf';
    //const pdfName = 'your_pdf_file';
    FileSaver.saveAs(pdfUrl, pdfName);
  }

  openDoc(pdfUrl: string, startPage: number ) {
    window.open(pdfUrl + '#page=' + startPage, '_blank', '', true);
  }

}

In HTML template use table with bootstrap CSS styles:

<table class="table">
    <thead>
        <tr>
            <th scope="col">Name</th>
            <th scope="col">Start Page</th>
            <th scope="col">View</th>
            <th scope="col">Download</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let item of pdfFiles">
            <th scope="row">{{ item.name }}</th>
            <td>{{ item.startPage }}</td>
            <td>
                <button type="button" class="btn btn-primary btn-sm" (click)="openDoc(item.path, item.startPage)">
                    View
                </button>
            </td>
            <td>
                <button type="button" class="btn btn-success btn-sm" (click)="downloadPdf(item.path, item.name)">
                    Save
                </button>
            </td>
        </tr>
    </tbody>
</table>

That’s it!

Make sure to have PDF file paths on the same server otherwise your server may throw CORS error while downloading the PDF file.

Subscribe
Notify of
1 Comment
Newest
Oldest Most Voted
Inline Feedbacks
View all comments

Is there a way to save all the pdfs into a zip file?