File upload and download in angular 4 typescript

后端 未结 7 1768
一个人的身影
一个人的身影 2020-12-13 10:58

How can I download (.exe file which is in root path) and Upload a file from Angular 4?
I am new to Angular4 and typescript and .NET Core Web API.

I h

7条回答
  •  自闭症患者
    2020-12-13 11:12

    Download any file from the server using Angular 8+ and ASP.NET CORE 2+ version.

    Controller implementation to download the file:

    
        [HttpGet]
            [Route("download")]
            public async Task Download([FromQuery] string file) {
                var uploads = Path.Combine(_hostingEnvironment.WebRootPath, "uploads");
                var filePath = Path.Combine(uploads, file);
                if (!System.IO.File.Exists(filePath))
                    return NotFound();
        
                var memory = new MemoryStream();
                using (var stream = new FileStream(filePath, FileMode.Open))
                {
                    await stream.CopyToAsync(memory);
                }
                memory.Position = 0;
        
                return File(memory, GetContentType(filePath), file); 
            }
    
    

    Create angular service

    
        import { Injectable } from '@angular/core';
        import { HttpClient, HttpRequest, HttpEvent, HttpResponse } from '@angular/common/http';
        import { Observable } from 'rxjs';
         
        @Injectable()
        export class DownloadService {
          private baseApiUrl: string;
          private apiDownloadUrl: string;
          private apiUploadUrl: string;
          private apiFileUrl: string;
         
          constructor(private httpClient: HttpClient) {
            this.baseApiUrl = 'http://localhost:5001/api/';
            this.apiDownloadUrl = this.baseApiUrl + 'download';
            this.apiUploadUrl = this.baseApiUrl + 'upload';
            this.apiFileUrl = this.baseApiUrl + 'files';
          }
         
          public downloadFile(file: string): Observable> {
            return this.httpClient.request(new HttpRequest(
              'GET',
              `${this.apiDownloadUrl}?file=${file}`,
              null,
              {
                reportProgress: true,
                responseType: 'blob'
              }));
          }
         }
    
    

    Create a model in angular

    
        export interface ProgressStatus {
          status: ProgressStatusEnum;
          percentage?: number;
        }
         
        export enum ProgressStatusEnum {
          START, COMPLETE, IN_PROGRESS, ERROR
        }
    
    

    Create a component to download a file

    
        

    Create a child component to download a file. Following code in typescript file:

    
        import { Component, Input, Output, EventEmitter } from '@angular/core';
        import { HttpEventType } from '@angular/common/http';
        import { UploadDownloadService } from 'src/app/services/upload-download.service';
        import { ProgressStatus, ProgressStatusEnum } from 'src/app/models/progress-status.model';
         
        @Component({
          selector: 'app-download',
          templateUrl: 'download.component.html'
        })
         
        export class DownloadComponent {
          @Input() public disabled: boolean;
          @Input() public fileName: string;
          @Output() public downloadStatus: EventEmitter;
         
          constructor(private service: UploadDownloadService) {
            this.downloadStatus = new EventEmitter();
          }
         
          public download() {
            this.downloadStatus.emit( {status: ProgressStatusEnum.START});
            this.service.downloadFile(this.fileName).subscribe(
              data => {
                switch (data.type) {
                  case HttpEventType.DownloadProgress:
                    this.downloadStatus.emit( {status: ProgressStatusEnum.IN_PROGRESS, percentage: Math.round((data.loaded / data.total) * 100)});
                    break;
                  case HttpEventType.Response:
                    this.downloadStatus.emit( {status: ProgressStatusEnum.COMPLETE});
                    const downloadedFile = new Blob([data.body], { type: data.body.type });
                    const a = document.createElement('a');
                    a.setAttribute('style', 'display:none;');
                    document.body.appendChild(a);
                    a.download = this.fileName;
                    a.href = URL.createObjectURL(downloadedFile);
                    a.target = '_blank';
                    a.click();
                    document.body.removeChild(a);
                    break;
                }
              },
              error => {
                this.downloadStatus.emit( {status: ProgressStatusEnum.ERROR});
              }
            );
          }
        }
    
    

    Add the following implementation in parent component:

    
        
        

    progress {{percentage}}%

    Add the following implementation in parent typescript component:

    
        import { Component, OnInit } from '@angular/core';
        import { UploadDownloadService } from 'src/app/services/upload-download.service';
        import { ProgressStatusEnum, ProgressStatus } from 'src/app/models/progress-status.model';
         
        @Component({
          selector: 'app-filemanager',
          templateUrl: './file-manager.component.html'
        })
        export class FileManagerComponent implements OnInit {
         
          public files: string[];
          public fileInDownload: string;
          public percentage: number;
          public showProgress: boolean;
          public showDownloadError: boolean;
          public showUploadError: boolean;
         
          constructor(private service: UploadDownloadService) { }
         
          ngOnInit() {
            this.getFiles();
          }
         
          private getFiles() {
            this.service.getFiles().subscribe(
              data => {
                this.files = data;
              }
            );
          }
         
          public downloadStatus(event: ProgressStatus) {
            switch (event.status) {
              case ProgressStatusEnum.START:
                this.showDownloadError = false;
                break;
              case ProgressStatusEnum.IN_PROGRESS:
                this.showProgress = true;
                this.percentage = event.percentage;
                break;
              case ProgressStatusEnum.COMPLETE:
                this.showProgress = false;
                break;
              case ProgressStatusEnum.ERROR:
                this.showProgress = false;
                this.showDownloadError = true;
                break;
            }
          }
        }
    
    

    DONE!

提交回复
热议问题