2

I'm trying to download a file on the click of a button in Angular. The file that gets downloaded but is 0 KB in size and does not open.

This is the code that I have so far in Angular and Spring MVC

Angular :

public downloadFile(fileName:string){
    console.log("ready to download");
    let param:any = {'messageId':this.loadedMessageService.messageId, 'attachmentName':fileName}
    this.http.get(`https://fakeurl.com/abc/getFile`,{params:param,responseType:'blob'}).subscribe(
      (data) => {
        let b:Blob = new Blob([data])
        //,{type: 'application/octet-stream',}
       // const fileName :string= "RL.xlsx" 
        var url = window.URL.createObjectURL(b);
        const a : HTMLAnchorElement = document.createElement('a') as HTMLAnchorElement;
       // const a = document.createElement('a');
        document.body.appendChild(a);
        a.href = url;
        a.download = fileName; 
        a.click();
        document.body.removeChild(a);
       URL.revokeObjectURL(url);
      }
    )
  }

Spring MVC :

@GetMapping(value = "/getFile")
     public @ResponseBody byte[] getFile() throws IOException {
           try {
                return messageAttachmentService.getFile(Integer.parseInt(request.getParameter("messageId")), request.getParameter("attachmentName"));
           } catch (NumberFormatException e) {
                StringWriter sw = new StringWriter();
                e.printStackTrace(new PrintWriter(sw));
                logger.error(sw.toString());
           } catch (Exception e) {
                StringWriter sw = new StringWriter();
                e.printStackTrace(new PrintWriter(sw));
                logger.error(sw.toString());
           }
           return null;
     }

Right now when I click the button, the file gets downloaded but it's 0 KB in size and does not open. I was using type as application/octet-stream before since the file to be downloaded could be either a PDF or text file or xls. I referred to other questions too and tried changing the response type to arraybuffer. That didn't solve the issue either. What is wrong with my code?

Akshat Sood
  • 345
  • 2
  • 7
  • 19
  • What happens if you leave the Angular part out and go directly to your backend download URL from browser? – Tarmo May 14 '19 at 06:42
  • In that case, I get the entire file downloaded with 'file' extension. If I try to open that with Acrobat Reader (since I'm testing with a pdf), it opens fine. – Akshat Sood May 14 '19 at 06:45
  • Ok. In that case the server side code is probably irrelevant. Why do you want to go Angular HTTP library/subscribe way with a file download. Wouldn't it be easier to just go to the download link the old fashion way and everything just works? – Tarmo May 14 '19 at 06:48
  • what is the output of console.log(data) on angular side? – rajesh-nitc May 14 '19 at 06:53
  • might be duplicate refer here : https://stackoverflow.com/questions/35138424/how-do-i-download-a-file-with-angular2 – Senthil May 14 '19 at 07:08

2 Answers2

2

You can try with file-saver package. It is easy to use.

import * as FileSaver from 'file-saver';

const blob: any = new Blob([data], { type: 'octet/stream' });
saveAs(blob, "hello world.txt");
Adrita Sharma
  • 21,581
  • 10
  • 69
  • 79
0

You can try like this.

  public downloadFile(fileName:string){
    console.log("ready to download");
    let param:any = {'messageId':this.loadedMessageService.messageId, 'attachmentName':fileName}
    this.http.get(`https://fakeurl.com/abc/getFile`,{params:param,responseType:'blob'}).subscribe(
      (data) => {
          const a = document.createElement('a');
          document.body.appendChild(a);
          const blob: any = new Blob([data], { type: 'octet/stream' });
          const url = window.URL.createObjectURL(blob);
          a.href = url;
          a.download = data.fileName;
          a.click();
          window.URL.revokeObjectURL(url);
      }
    )
  }
Yash Rami
  • 2,276
  • 1
  • 10
  • 16
  • I would be nice if you would add your reasoning why OP's solution does not work and yours does. Just a blob of code is not a good answer as it's hard to understand why this might solve anything. – Tarmo May 14 '19 at 06:50