Downloading PDF File in Angular

  • Last updated Apr 25, 2024

In this tutorial, we will show you how to download a PDF file by making a REST API call in Angular, along with example code.

Follow these steps:

Configuring Angular's HttpClient

Import provideHttpClient and include provideHttpClient() in the list of providers within app.config.ts if you haven't already. For example:

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideClientHydration } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideClientHydration(),
    provideHttpClient(),
  ],
};
Creating an API service

Create a service to handle API calls using the Angular CLI:

ng generate service services/api

This will create a file named api.service.ts in the src/app/services folder.

Implementing API service

Open the src/app/api.service.ts file and implement the service with the necessary methods, such as GET or POST requests, depending on the API:

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  private apiBaseUrl = 'http://localhost:8080'; // Example API URL, replace with your API URL

  constructor(private http: HttpClient) {}

  private httpOptions: Object = { 
    headers: new HttpHeaders({
      'Access-Control-Allow-Origin': '*',
      'ContentType': 'application/json'
    }),
  };
 
  // GET Request
  get(endpoint: string, options?: any): Observable<any> {
    if (!options) {
      options = this.httpOptions;
    }
    return this.http.get(`${this.apiBaseUrl}/${endpoint}`, options);
  }

  // POST Request
  post(endpoint: string, data: any, options?: any): Observable<any> {
    if (!options) {
      options = this.httpOptions;
    }
    return this.http.post(`${this.apiBaseUrl}/${endpoint}`, data, options);
  }
  
}
Using the API service to download PDF File

Open the src/app/your.component.ts file (For example, src/app/document.component.ts) and use the ApiService to make API call in the component:

import { Component, OnInit } from '@angular/core';
import { ApiService } from '../services/api.service';
import { HttpHeaders, HttpResponse } from '@angular/common/http';

@Component({
  selector: 'app-document',
  standalone: true,
  imports: [],
  templateUrl: './document.component.html',
  styleUrl: './document.component.css',
})
export class DocumentComponent implements OnInit {
  constructor(private apiService: ApiService) {}

  ngOnInit(): void {}

  headers = new HttpHeaders({
    'Access-Control-Allow-Origin': '*',
    'ContentType': 'application/json',
  });

  downloadPdf() {
    const endpoint = 'download-pdf'; // replace with your API endpoint
    const postData = { documentId: 1 }; // replace with your data
    let options: Object = {
      headers: this.headers,
      responseType: 'arraybuffer',
      observe: 'response',
    };
    
    this.apiService.post(endpoint, postData, options).subscribe({
      next: (data: HttpResponse<any>) => {
        const filename = this.extractFilenameFromContentDisposition(data);
        const blob = new Blob([data.body], { type: 'application/pdf' });
        const link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = filename;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      },
      error: (err) => {
        console.log(err);
      },
      complete() {
        console.log('complete...');
      },
    });
  }

  extractFilenameFromContentDisposition(data: any): string {
    var headers = data.headers;
    var contentDisposition = headers.get('Content-Disposition');
    const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/i.exec(contentDisposition);
    return matches && matches[1] ? decodeURIComponent(matches[1].replace(/['"]/g, '')) : '';
  }
  
}

This is a basic example. Make sure to replace the API URL and adjust the endpoint names and data based on your API requirements.