如何下载(根路径中的.exe
文件)和从Angular 4上传文件?
我是Angular4和打字稿以及.NET Core Web API的新手。我用谷歌搜索但找不到解决方案。
以下是我发现的一些类似问题:
答案 0 :(得分:21)
我想为此添加一个Angular 4.3 / 5/6更新,尤其是与简化的HttpClient相比。由于Angular会自动构建Content-Type(因此存在添加Content-Type = undefined的倾向,因此不存在'Content-Type'特别重要。不要,因为它会在各种情况下产生问题,也许不会好的做法)。一旦没有Content-Type,浏览器将自动添加'multipart / form-data'和相关参数。注意,这里的后端是Spring Boot,虽然它没关系。
这是一些伪代码 - 请原谅phat手指。希望这会有所帮助:
<强> MyFileUploadComponent(html的):强>
...
<input type="file" (change)=fileEvent($event)...>
MyFileUploadComponent(.ts)在fileEvent上调用MyFileUploadService(.ts):
...
public fileEvent($event) {
const fileSelected: File = $event.target.files[0];
this.myFileUploadService.uploadFile(fileSelected)
.subscribe( (response) => {
console.log('set any success actions...');
return response;
}.
(error) => {
console.log('set any error actions...');
});
}
<强> MyFileUploadService.ts:强>
...
public uploadFile(fileToUpload: File) {
const _formData = new FormData();
_formData.append('file', fileToUpload, fileToUpload.name);
return<any>post(UrlFileUpload, _formData); //note: no HttpHeaders passed as 3d param to POST!
//So no Content-Type constructed manually.
//Angular 4.x-6.x does it automatically.
}
答案 1 :(得分:10)
对于上传文件,我们可以以multipart / form-data的形式发布数据。为此,我们必须使用FormData类。这是一个例子。
模板:
<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>
组件:
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);
}
要上传API文件,请参阅:
https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-2
答案 2 :(得分:1)
非常简单 component.html看起来像
<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>
在ts文件中,它看起来像
public fileUploader(event) {
const elem = event.target;
if (elem.files.length > 0) {
console.log(elem.files[0]);
}
// ...
}
答案 3 :(得分:0)
<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() {
}
}
答案 4 :(得分:0)
尝试用角度下载文件,就可以了
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();
});
}
`
答案 5 :(得分:0)
请参考以下代码进行文件上传。 html代码:
<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>
组件代码:
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;
}
全球服务代码:
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);
}
要下载具有文件名和文件路径的文件:
使用文件名和文件路径作为参数从html调用DownloadFile函数。
组件代码:
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.')
});
}
下载文件的全球服务代码:
public DownloadFile(filePath: string): Observable<any> {
return this.http
.get(this.urlService.CMMService + '/CMMService-service/DownloadFile?filePath=' + filePath, {
responseType: 'blob'
});
}
在服务器端,请使用以下代码:
[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;
}
请让我知道你们是否仍然遇到任何问题。
答案 6 :(得分:0)
使用Angular 8+和ASP.NET CORE 2+版本从服务器下载任何文件。
下载文件的控制器实现:
[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); }
创建角度服务
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' })); } }
创建角度模型
export interface ProgressStatus { status: ProgressStatusEnum; percentage?: number; } export enum ProgressStatusEnum { START, COMPLETE, IN_PROGRESS, ERROR }
创建一个组件以下载文件
<button [disabled]="disabled" class="button download" [ngClass]="{'disabled': disabled}" (click)="download()">download
创建一个子组件以下载文件。打字稿文件中的以下代码:
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}); } ); } }
在父组件中添加以下实现:
<app-download [disabled]="showProgress" [fileName]="file" (downloadStatus)="downloadStatus($event)"> <p *ngIf="showProgress"> progress {{percentage}}%
在父打字稿组件中添加以下实现:
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; } } }
完成!