Ankita
Ankita

Reputation: 623

Angular 2 Download a Zip format file

I have a Node JS Rest get service which send the zip folder created on my server in binary encoded format. But unable to download this on client. I am unable to open the zip.

Server controller

botsController.exportBot = (req,res) =>{
    let botId = req.params.botId;
    zipFolder("...pathtoZip/", "pathToFolder/my.zip", function(err) {
        if(err) {

            res.statusCode = 500;
            return res.send({
                success: false,
                message: "Something went wrong while fetching the bot data",
                err_details: err
            });

        } else {
            let filetext;
            let zipFolder= "pathToFolder/my.zip";

            if (fs.existsSync(zipFolder)) {
                filetext = fs.readFileSync(zipFolder, "utf-8");//tried encoding binary
            }

            var headers = {
                'Content-Type':  'application/octet-stream',//tried application/zip
                'Content-Disposition': "attachment; filename=" + botId + '.zip'
            };
            res.writeHead(200, headers);
            return res.end(filetext,"binary");

        }
    });

And on angular js Service I have fetch the data. And on component I have downloaded it.But download zip is corrupted it gives error unable to open the zip.

Angular 2 Service

  exportBot() {
    let token = localStorage.token;
    let headerObj = {
      'Authorization': token,
      responseType: ResponseContentType.ArrayBuffer
    };
    let headers = new Headers(headerObj);

    return this.http.get("export/botId", { headers: headers })
      .map((res) => new Blob([res['_body']], { type: 'application/zip' }))
      .catch(this.errorHandler);

  }

And on component end

exportBot() {
        this.loader = false;
        this.botdataservice.exportBot()
            .subscribe(res => {
                console.log(`excel data: ${res}`);
                window.open(window.URL.createObjectURL(res));
            },
            err => {
               console.log(err); 
            })
        }

Upvotes: 0

Views: 4035

Answers (2)

Vinod Louis
Vinod Louis

Reputation: 4876

You can convert your file to base64 by using btoa(unescape(encodeURIComponent(binarydata))) or in case of array buffer try btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));

Either can even send base64 file from your node server

filetext = fs.readFileSync(zipFolder);

return res.end(new Buffer(filetext ).toString('base64'));

in that case change your headers

and use following code to download it

var base64Str = "UEsDBAoAAgAAAMWqM0z4bm0cBQAAAAUAAAAJAAAAdmlub2QudHh0dmlub2RQSwECFAAKAAIAAADFqjNM+G5tHAUAAAAFAAAACQAkAAAAAAABACAAAAAAAAAAdmlub2QudHh0CgAgAAAAAAABABgAUCMddj2R0wFA/Bx2PZHTAWCGE3Y9kdMBUEsFBgAAAAABAAEAWwAAACwAAAAAAA==";

var elem = window.document.createElement('a');
        elem.href = "data:application/zip;base64,"+base64Str
        elem.download = "my.zip";        
        document.body.appendChild(elem);
        elem.click();        
        document.body.removeChild(elem);

Upvotes: 1

H.abidi
H.abidi

Reputation: 585

In your package.json add the dependency :

"file-saver": "^1.3.3",

And you can use the file saver on your get request as below :

public getBlob(url: string): Observable<Blob> {
    this.showLoader();
    return this.http.get(url, {responseType: 'blob'})
      .catch(this.onCatch)
      .do(res => {
        this.onSuccess(res);
      }, (error: any) => {
        this.onError(error);
      })
      .finally(() => {
        this.onEnd();
      });
  }

and the method to download :

  downloadFile(fileid: string) {
    return this._http.getBlob(this._http.backendURL.downloadFile.replace(':fileid', fileid))
  }

And the you call the Filesaver when subscribing data as this :

 downloadFile() {
    this._downloadFileService.downloadFile(this.model.fileid)
      .subscribe(
        data => {
          FileSaver.saveAs(data, this.form.getRawValue().title);
        }
      );
  }

I hope this can help.

Upvotes: 2

Related Questions