View/download pdf and excel file in angular using rest API in java spring MVC

Hey guys, in this post we are going to see how to show pdf file In browser and how to download excel and pdf file (we can’t view excel file in the web browser, because a browser is not capable to view excel file). Let’s do it step by step.
[At the bottom of this tutorial, you will get a link of the project to download]
For this demo, we are going to refer to our same previous example.
At very first, here we will create rest API in spring.



Following is the rest API

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.usit.mes.tap.services.prod.ProductProcess.bd.ProductProcessBusinessDeligate;
import com.usit.mes.tap.services.prod.ProductProcess.to.ProductProcess;
import com.usit.mes.tap.services.prod.ProductProcess.to.ResponseMessage;
     @RequestMapping(value = "/get/pdf/{fileName}", method = RequestMethod.GET)
     public Object getPdf(@PathVariable("fileName") String fileName) {
           logger.info("Service called: getPdf");
           File file;
           switch (fileName) {
           case "1":
                file = new File("F:\\pdfNecxelTest\\dummy.pdf");
                break;
           case "2":
                file = new File("F:\\pdfNecxelTest\\pdf-sample.pdf");
                break;
           case "3":
                file = new File("F:\\pdfNecxelTest\\sample.pdf");
                break;
           case "4":
                file = new File("F:\\pdfNecxelTest\\sample2.pdf");
                break;
           default:
                file = new File("F:\\pdfNecxelTest\\sample2.pdf");
                break;
           }
           try {
                FileInputStream fileInputStream = new FileInputStream(file);
                return IOUtils.toByteArray(fileInputStream);
           } catch (IOException e) {
                e.printStackTrace();
           }
           logger.info("Service completed: getPdf");
           return null;
     }

     @RequestMapping(value = "/get/excel/{fileName}", method = RequestMethod.GET)
     public Object getExcel(@PathVariable("fileName") String fileName) {
           logger.info("Service called: getExcel");
           File file;
           switch (fileName) {
           case "1":
                file = new File("F:\\pdfNecxelTest\\dummy.xls");
                break;
           case "2":
                file = new File("F:\\pdfNecxelTest\\pdf-sample.xls");
                break;
           case "3":
                file = new File("F:\\pdfNecxelTest\\sample.xls");
                break;
           case "4":
                file = new File("F:\\pdfNecxelTest\\sample2.xls");
                break;
           default:
                file = new File("F:\\pdfNecxelTest\\sample2.xls");
                break;
           }
           try {
                FileInputStream fileInputStream = new FileInputStream(file);
                return IOUtils.toByteArray(fileInputStream);
           } catch (IOException e) {
                e.printStackTrace();
           }
           logger.info("Service completed: getExcel");
           return null;
     }


Here in rest API we have just read the already existing files from our own machine and converted it to a byte array with help of apache commons' IOUtils.toByteArray method. Once we get byte stream, we send it to the response of rest call.
 So now what should we do at an angular side to catch that byte array and convert it back to the file properly.
Here is how we do it.
home.component.html
<div class="container card">
  <div class="row">
    <div class="col-lg-12">
      <h4 class="text-center"> <label for="">File Demo</label> </h4>
      <div class="form-group">
        &nbsp;<label for="select file">Select File</label>&nbsp;
        <select name="selectFile" id="selectFile" class="form-control-sm" [(ngModel)]="fileName">
          <option [value]="1">File 1</option>
          <option [value]="2">File 2</option>
          <option [value]="3">File 3</option>
          <option [value]="4">File 4</option>
        </select>&nbsp;
      </div>
      <div class="form-group">
        &nbsp;<label for="select file">Select Type</label>&nbsp;
        <select name="selectFileType" id="selectFileType" class="form-control-sm" [(ngModel)]="fileType">
          <option value="pdf">PDF</option>
          <option value="excel">Excel</option>
        </select>
      </div>
      <button class="btn btn-sm btn-primary" (click)="getFile()">View File</button>&nbsp;
      <button class="btn btn-sm btn-primary" (click)="getFileInNewWindow()">View File in New Window</button>
    </div>
    <div class="col-lg-12" style="height: 680px;"><object #pdfViewer type="application/pdf" width="100%"
        height="100%"></object></div>
  </div>
</div>


Here in HTML, we have created two drop downs to select file and file type as well
Then two buttons to display the file in the same window or in a new window, also we need one object element which will act as a container to show the pdf file on the same page.

home.component.ts
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { GetpdfService } from '../service/getpdf.service';

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

  @ViewChild('pdfViewer') pdfViewer: ElementRef;
  public fileName: string;
  public fileType: string;
  public fileList: string[] = [];

  constructor(private pdfService: GetpdfService) { }

  ngOnInit() {
  }

  getFile() {
    if (this.fileType == "pdf") {
      this.pdfService.getPdf(this.fileName, this.fileType).subscribe((responseMessage) => {
        let file = new Blob([responseMessage], { type: 'application/pdf' });
        var fileURL = URL.createObjectURL(file);
        this.pdfViewer.nativeElement.data = fileURL;
      })
    } else {

      this.pdfService.getExcel(this.fileName, this.fileType).subscribe((responseMessage) => {
        let file = new Blob([responseMessage], { type: 'application/vnd.ms-excel' });
        var fileURL = URL.createObjectURL(file);
        window.open(fileURL, "_blank");
      })
    }
  }

  getFileInNewWindow() {
    if (this.fileType == "pdf") {
      this.pdfService.getPdf(this.fileName, this.fileType).subscribe((responseMessage) => {
        let file = new Blob([responseMessage], { type: 'application/pdf' });
        var fileURL = URL.createObjectURL(file);
        window.open(fileURL);
      })
    } else {
      this.pdfService.getExcel(this.fileName, this.fileType).subscribe((responseMessage) => {
        let file = new Blob([responseMessage], { type: 'application/vnd.ms-excel' });
        var fileURL = URL.createObjectURL(file);
        window.open(fileURL);
      })
    }

  }

}

In typescript we have written two functions for, to display a file on the same page and to display a file in a new window.
In both cases we got an array of bytes from the server, we catch that bytes array and apply its type to it. so the view can understand what is it, and how to process its data.
And another important thing is, we took object element, and with the help of view child, we got a reference of the object. after that as soon as we get the byte array we assign it as a objects data so it can show on the page.

getpdf.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class GetpdfService {
  baseUrl: string = "http://localhost:8080/webservices/";

  constructor(private httpService: HttpClient) {
  }

  getPdf(fileName: string, fileType: string) {
    return this.httpService.get<any>(`${this.baseUrl}/get/pdf/${fileName}`, { responseType: 'arraybuffer' as 'json' });
  }

  getExcel(fileName: string, fileType: string) {
    return this.httpService.get<any>(`${this.baseUrl}/get/excel/${fileName}`, { responseType: 'arraybuffer' as 'json' });
  }
}


Here is the service to get data from the webserver.
That’s it, with the help of this code you will be able to view and download the pdf file.

this is the module file to let you know dependencies and imports.
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FirstPageComponent } from './first-page/first-page.component';
import { SecondPageComponent } from './second-page/second-page.component';
import { FormsModule } from '@angular/forms';
import { HomeComponent } from './home/home.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
declarations: [
AppComponent,
FirstPageComponent,
SecondPageComponent,
HomeComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Output

Hope you like it.
[here is the link to download the project get me the project]

Comments

  1. why excel file downloaded insted of view in broswer like pdf?

    ReplyDelete
    Replies
    1. because our browser have plugin to view the pdf, so it get's displayed in browser. but it is not the case with excel.

      Delete
  2. Thank my friend...

    ReplyDelete
  3. Why other PDF files are not working?

    ReplyDelete

Post a Comment