File upload and download in angular 4 typescript

后端 未结 7 1769
一个人的身影
一个人的身影 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:11

    its very simple component.html will look like

    <div class="form-group col-md-6" style="margin-left:50%;margin-top:-8%" >
        <input type="file" value="upload" accept=".jpg" (change)=fileUploader($event)>
    </div>
    

    while in the ts file, it will look like

    public fileUploader(event) {
        const elem = event.target;
        if (elem.files.length > 0) {
            console.log(elem.files[0]);
        }
        // ...
    }
    
    0 讨论(0)
  • 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

    
        <button
         [disabled]="disabled"
         class="button download"
         [ngClass]="{'disabled': disabled}"
         (click)="download()">download
    
    

    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:

    
        <app-download [disabled]="showProgress" [fileName]="file" (downloadStatus)="downloadStatus($event)">
        <p *ngIf="showProgress"> 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!

    0 讨论(0)
  • 2020-12-13 11:13

    For uploading file, we can post data in form of multipart/form-data. For that, we have to use the FormData class. Here is an example.

    Template:

    <form #yourForm="ngForm" (ngSubmit)="onSubmit()">
          <input type="text" [(ngModel)]="Name" name="Name"/>
          <input type="file" #fileupload [(ngModel)]="myFile" name="myFile" (change)="fileChange(fileupload.files)"/>
          <button type="submit">Submit</button>
    </form>
    

    Component:

    import { Http, Response, Headers, RequestOptions } from '@angular/http';
    /* When we select file */
    Name:string; 
    myFile:File; /* property of File type */
    fileChange(files: any){
        console.log(files);
    
        this.myFile = files[0].nativeElement;
    }
    
    /* Now send your form using FormData */
    onSubmit(): void {
        let _formData = new FormData();
        _formData.append("Name", this.Name);
        _formData.append("MyFile", this.myFile);
        let body = this._formData;
        let headers = new Headers();
        let options = new Options({
            headers: headers
        });
        this._http.post("http://example/api/YourAction", body, options)
          .map((response:Response) => <string>response.json())
          .subscribe((data) => this.message = data);
    }
    

    For API to upload file, see this:
    https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-2

    0 讨论(0)
  • 2020-12-13 11:14
    <form [formGroup]="uploadForm" (ngSubmit)="onSubmit()">
        Select image to upload:
        <input type="file" name="avatar" id="fileToUpload" formControlName="file1" (change)="fileEvent($event)">
        <input type="submit" value="Upload Image" name="submit">
    </form>
    
    import { Component, OnInit } from '@angular/core';
    import { FormControl, FormGroup } from '@angular/forms';
    import { HttpClient } from '@angular/common/http';
    @Component({
      selector: 'app-praveen',
      templateUrl: './praveen.component.html',
      styleUrls: ['./praveen.component.css']
    })
    export class PraveenComponent implements OnInit {
    
      constructor(private httpClient:HttpClient) { }
        uploadForm = new FormGroup ({
            file1: new FormControl()
        });
        filedata:any;
        fileEvent(e){
            this.filedata=e.target.files[0];
            console.log(e);
        }
        onSubmit() {
            let formdata = new FormData();
            console.log(this.uploadForm)
            formdata.append("avatar",this.filedata);
            this.httpClient
            .post<any>("http://localhost:3040/uploading",formdata)
            .subscribe((res)=>{console.log(res});
        }
      ngOnInit() {
      }
    
    }
    
    0 讨论(0)
  • 2020-12-13 11:15

    Please refer below code for file upload. html code:

    <div class="col-md-6">
         <label class="control-heading">Select File</label>
         <input type="file" [multiple]="multiple" #fileInput (change)="selectFile($event)">
         <input type="button" style="margin-top: 15px;" [disabled]="!isUploadEditable" class="data-entry-button btn-pink" (click)="uploadFile()" value="Upload" title="{{globalService.generateTooltip('upload attachment','Click to upload document.')}}" data-html="true" data-toggle="tooltip" data-placement="bottom" />
    </div>
    

    Component code:

    selectFile(event: any) {
        this.selectedFiles = event.target.files;
    }
    
    uploadFile() {
        this.currentFileUpload = this.selectedFiles.item(0);
        this.globalService.pushFileToStorage(this.currentFileUpload).subscribe(event => {
            if (event instanceof HttpResponse) {
                this.loadDocumentInfo();
                this.showNotification('Upload Attachment', 'File Uploaded Successfully', 'success');
                this.myInputVariable.nativeElement.value = "";
            }
        });
        this.selectedFiles = undefined;
    }
    

    Global service code:

    pushFileToStorage(file: File): Observable<HttpEvent<{}>> {
        const formdata: FormData = new FormData();
        formdata.append('file', file);
        formdata.append('documentVersionId', this.documentVersionId.toString());
        formdata.append('levelId', this.levelId);
        formdata.append('levelKey', this.levelKey);
        formdata.append('LoggedInUser', this.loggedInUser);
        const req = new HttpRequest('POST', this.urlService.CMMService + '/CMMService-service/UploadFileAsAttachment', formdata, {
            reportProgress: true,
            responseType: 'text'
        }
        );
        return this.http.request(req);
    }
    

    To download file with file name and file path:

    call DownloadFile function from html with filename and filepath as parameters.

    component code:

    DownloadFile(filePath: string, filename: string) {
        this.globalService.DownloadFile(filePath).subscribe(res => {
            //console.log('start download:', res);
            var url = window.URL.createObjectURL(res);
            var a = document.createElement('a');
            document.body.appendChild(a);
            a.setAttribute('style', 'display: none');
            a.href = url;
            res.filename = filename;
            a.download = res.filename;
            a.click();
            window.URL.revokeObjectURL(url);
            a.remove(); // remove the element
        }, error => {
            console.log('download error:', JSON.stringify(error));
        }, () => {
            console.log('Completed file download.')
        });
    }
    

    Global service code to download file:

    public DownloadFile(filePath: string): Observable<any> {
       return this.http
            .get(this.urlService.CMMService + '/CMMService-service/DownloadFile?filePath=' + filePath, {
                responseType: 'blob'
            });
    }
    

    on server side please use below code:

    [HttpGet]
            [ODataRoute("DownloadFile")]
            public HttpResponseMessage DownloadFile(string filePath)
            {
                var fileData = CommonDomain.DownloadFileFromS3(filePath);
                var dataStream = new MemoryStream(fileData.ByteArray);
                HttpResponseMessage httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK);
                httpResponseMessage.Content = new StreamContent(dataStream);
                httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                httpResponseMessage.Content.Headers.ContentDisposition.FileName = fileData.FileName;
                httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                httpResponseMessage.Content.Headers.Add("x-filename", fileData.FileName);
                return httpResponseMessage;
            }
    

    Please let me know if you guys still facing any issue.

    0 讨论(0)
  • 2020-12-13 11:20

    to download file with angular try with this, it works`

    download(row) {
        return this.Http
          .get(file_path , {
            responseType: ResponseContentType.Blob,
          })
          .map(res => {
            return {
              filename: row.name,
              data: res.blob()
            };
          })
          .subscribe(res => {
            let url = window.URL.createObjectURL(res.data);
            let a = document.createElement('a');
            document.body.appendChild(a);
            a.setAttribute('style', 'display: none');
            a.href = url;
            a.download = res.filename;
            a.click();
            window.URL.revokeObjectURL(url);
            a.remove();
          });
      }
    

    `

    0 讨论(0)
提交回复
热议问题