如何使用添加按钮在 Angular 6 中上传多个文件?
Posted
技术标签:
【中文标题】如何使用添加按钮在 Angular 6 中上传多个文件?【英文标题】:How to Upload multiple files in Angular 6 with ADDMORE button? 【发布时间】:2019-01-06 07:22:17 【问题描述】:你好,Everone。我一直在尝试上传上面(图片)用例。我知道当我们只有一个文件时这很容易。但现在情况不同了,它由带有文件的对象数组组成。 现在我的问题是如何使用对象数组呈现 formdata 对象,其中每个对象都由一个文件组成。对于动态形式,我使用了角度反应形式。任何人都可以请建议我如何通过单击保存按钮将整个数据发送到支持。 对于后端,我使用了 Springmvc。 提前致谢。
我的 Github 上有完整的源代码:Source
多文件上传.component.html
<div class="container-fluid">
<section class="content">
<div id="main-form-content">
<form [formGroup]="documentGrp" (ngSubmit)="OnSubmit(documentGrp.value)" #uploadDocumentsForm="ngForm" ngNativeValidate>
<div class="box box-solid box-primary">
<div class="box-body" formArrayName="items">
<h2 class="page-header text-blue ">
<i class="fa fa-files-o"></i> Upload Documents
</h2>
<div class="row">
<div class="col-sm-12">
<div *ngFor="let item of items.controls; let i = index;">
<div [formGroupName]="i">
<table id="tbl-upload" class="table table-bordered">
<tbody>
<tr *ngIf="i==0" class="active">
<th>Document Name</th>
<th>Document Description</th>
<th>Document File</th>
<th> </th>
</tr>
<tr>
<td>
<div class="form-group required">
<input type="text" class="form-control" name="doc_name" formControlName="doc_name" placeholder="Enter document Category"
required="">
<div class="help-block"></div>
</div>
</td>
<td>
<div class="form-group ">
<input type="text" class="form-control" name="doc_description" formControlName="doc_description" maxlength="100" placeholder="Enter document related descriptions"
required="">
<div class="help-block"></div>
</div>
</td>
<td>
<div class="form-group required">
<input type="file" name="admission_docs_path" title="Browse Document" (change)="fileSelectionEvent($event)" required="">
<div class="help-block"></div>
</div>
</td>
<td class="remove" *ngIf=" i!=0 ">
<a title="Remove" (click)="removeItem(i)" class="fa fa-minus-square fa-lg text-red"></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="pull-right">
<a class="btn btn-sm btn-success" title="Add More" style="" (click)="addItem()">
<i class="fa fa-plus-square"></i> Add More</a>
</div>
</div>
<!--./col-->
</div>
<!--./row-->
</div>
<!--./box-body-->
<div class="box-footer" style="align-content: center">
<button type="submit" class="btn btn-primary pull-right">Save</button>
</div>
</div>
</form>
</div>
</section>
</div>
多文件上传.component.ts
import Component, OnInit, Renderer from '@angular/core';
import FormBuilder, FormGroup, Validators, FormArray, FormControl, NgForm from '@angular/forms';
import MultifilesService from './multifiles.service'
@Component(
selector: 'app-multi-files-upload',
templateUrl: './multi-files-upload.component.html',
styleUrls: ['./multi-files-upload.component.css']
)
export class MultiFilesUploadComponent implements OnInit
constructor(private renderer: Renderer,
private formBuilder: FormBuilder,
private multifilesService: MultifilesService
)
public documentGrp: FormGroup;
ngOnInit()
this.documentGrp = this.formBuilder.group(
doc_name: '',
doc_description: '',
documentFile: File,
items: this.formBuilder.array([this.createUploadDocuments()])
);
public doc_name = "";
public doc_description = "";
public documentFile: File;
createUploadDocuments(): FormGroup
return this.formBuilder.group(
doc_name: '',
doc_description: '',
documentFile: File,
);
get items(): FormArray
return this.documentGrp.get('items') as FormArray;
;
addItem(): void
this.items.insert(0, this.createUploadDocuments())
removeItem(index: number)
this.items.removeAt(index);
public fileSelectionEvent(fileInput: any)
if (fileInput.target.files && fileInput.target.files[0])
var reader = new FileReader();
reader.onload = (event: any) =>
this.documentFile = (fileInput.target.files[0]);
console.log("the document is" + JSON.stringify(fileInput.target.files[0].name));
reader.readAsDataURL(fileInput.target.files[0]);
public OnSubmit(formValue: any)
let total_form: FormData[] = [];
console.log(formValue.items)
formValue.items.forEach(element =>
let upl_fom: FormData = new FormData();
console.log("each element is", element);
upl_fom.append('document_category', element.doc_name);
upl_fom.append('document_details', element.doc_description);
upl_fom.append('document_file', element.documentFile);
total_form.push(upl_fom);
);
this.multifilesService.saveFiles(total_form).subscribe(data =>
console.log("result is ", data)
)
Multifiles.service.ts
import Injectable from '@angular/core';
import HttpClient,HttpHeaders from '@angular/common/http';
@Injectable(
providedIn: 'root'
)
export class MultifilesService
constructor( private http: HttpClient)
saveFiles(total_form)
return this.http.post("http://localhost:8181/uploadFiles",total_form);
上传控制器.java
@PostMapping("uploadFiles")
public String uploadMultiFiles(HttpServletRequest request)
System.out.println("hitting uploadFiles");
Enumeration e =request.getParameterNames();
while(e.hasMoreElements())
System.out.println(e.nextElement());
MultipartHttpServletRequest multiPartRequest = new DefaultMultipartHttpServletRequest(request);
try
multiPartRequest = (MultipartHttpServletRequest) request;
multiPartRequest.getParameterMap();
//multipartRequest.
Iterator < String > it = multiPartRequest.getFileNames();
int i = 1;
while (it.hasNext())
MultipartFile multipart = multiPartRequest.getFile(it.next());
System.out.println("File name is "+multipart.getOriginalFilename());
catch(Exception ex)
return "uploaded ";
【问题讨论】:
现在有什么问题? @Chellappan 我没有将任何文件发送到我的后端,所以我假设我的 component.ts 中的 formdata 的呈现可能是一个问题。所以我想知道如何在何时呈现 formdata 对象这种场景。 不要在标题中加上“SOLVED”,只要接受你的答案,就意味着它正在被解决。 【参考方案1】:在尝试了不同的场景来渲染 formdata 对象后,我在一个场景中成功了。
GitHub 链接:Source
更新文件
多文件上传.component.html
<div class="container-fluid">
<section class="content">
<div id="main-form-content">
<form [formGroup]="documentGrp" (ngSubmit)="OnSubmit(documentGrp.value)" #uploadDocumentsForm="ngForm" ngNativeValidate>
<div class="box box-solid box-primary">
<div class="box-body" formArrayName="items">
<h2 class="page-header text-blue ">
<i class="fa fa-files-o"></i> Upload Documents
</h2>
<div class="row">
<div class="col-sm-12">
<div *ngFor="let item of items.controls; let i = index;">
<div [formGroupName]="i">
<table id="tbl-upload" class="table table-bordered">
<tbody>
<tr *ngIf="i==0" class="active">
<th>Document Name</th>
<th>Document Description</th>
<th>Document File</th>
<th> </th>
</tr>
<tr>
<td>
<div class="form-group required">
<input type="text" class="form-control" name="doc_name" formControlName="doc_name" placeholder="Enter document Category"
required="">
<div class="help-block"></div>
</div>
</td>
<td>
<div class="form-group ">
<input type="text" class="form-control" name="doc_description" formControlName="doc_description" maxlength="100" placeholder="Enter document related descriptions"
required="">
<div class="help-block"></div>
</div>
</td>
<td>
<div class="form-group required">
<input type="file" title="Browse Document" (change)="fileSelectionEvent($event,i)" required="">
<div class="help-block"></div>
</div>
</td>
<td class="remove" *ngIf=" i!=0 ">
<a title="Remove" (click)="removeItem(i)" class="fa fa-minus-square fa-lg text-red"></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="pull-right">
<button type="submit" class="btn btn-sm btn-success" title="Add More" style="" (click)="addItem()">Add More</button>
</div>
</div>
<!--./col-->
</div>
<!--./row-->
</div>
<!--./box-body-->
<div class="box-footer" style="align-content: center">
<button type="submit" class="btn btn-primary pull-right">Save</button>
</div>
</div>
</form>
</div>
</section>
</div>
多文件上传.component.ts
import Component, OnInit, Renderer, ViewChild from '@angular/core';
import FormBuilder, FormGroup, Validators, FormArray, FormControl, NgForm from '@angular/forms';
import MultifilesService from './multifiles.service'
@Component(
selector: 'app-multi-files-upload',
templateUrl: './multi-files-upload.component.html',
styleUrls: ['./multi-files-upload.component.css']
)
export class MultiFilesUploadComponent implements OnInit
constructor(private renderer: Renderer,
private formBuilder: FormBuilder,
private multifilesService: MultifilesService
)
public documentGrp: FormGroup;
public totalfiles: Array<File> =[];
public totalFileName = [];
public lengthCheckToaddMore =0;
ngOnInit()
this.documentGrp = this.formBuilder.group(
doc_name: '',
doc_description: '',
documentFile:new FormControl(File),
items: this.formBuilder.array([this.createUploadDocuments()])
);
createUploadDocuments(): FormGroup
return this.formBuilder.group(
doc_name: '',
doc_description: '',
documentFile : File
);
get items(): FormArray
return this.documentGrp.get('items') as FormArray;
;
addItem(): void
//console.log("length is ",this.totalfiles.length);
//console.log("lengthCheckToaddMore ", this.lengthCheckToaddMore);
if(this.totalfiles.length!=0)
if( this.items.value[0].doc_name != "" && this.items.value[0].doc_description != "" && ((this.lengthCheckToaddMore) === (this.totalfiles.length)) )
this.items.insert(0, this.createUploadDocuments())
this.lengthCheckToaddMore=this.lengthCheckToaddMore+1;
removeItem(index: number)
this.totalfiles.splice(index);
this.totalFileName.splice(index);
this.items.removeAt(index);
this.lengthCheckToaddMore=this.lengthCheckToaddMore-1;
// console.log("name are ",this.totalFileName);
public fileSelectionEvent(fileInput: any,oldIndex)
//console.log("oldIndex is ", oldIndex);
if (fileInput.target.files && fileInput.target.files[0])
var reader = new FileReader();
reader.onload = (event: any) =>
if(oldIndex==0)
this.totalfiles.unshift((fileInput.target.files[0]))
this.totalFileName.unshift(fileInput.target.files[0].name)
else
this.totalfiles[oldIndex]=(fileInput.target.files[0]);
this.totalFileName[oldIndex]=fileInput.target.files[0].name
reader.readAsDataURL(fileInput.target.files[0]);
if(this.totalfiles.length == 1)
this.lengthCheckToaddMore=1;
public OnSubmit(formValue: any)
let main_form: FormData = new FormData();
for(let j=0;j<this.totalfiles.length; j++)
console.log("the values is ",<File>this.totalfiles[j]);
console.log("the name is ",this.totalFileName[j]);
main_form.append(this.totalFileName[j],<File>this.totalfiles[j])
console.log(formValue.items)
//reverseFileNames=this.totalFileName.reverse();
let AllFilesObj= []
formValue.items.forEach((element, index) =>
console.log("index is ",index);
console.log("element is ", element);
let eachObj=
'doc_name' : element.doc_name,
'doc_description' : element.doc_description,
'file_name' : this.totalFileName[index]
AllFilesObj.push(eachObj);
);
//console.log("the Array data is ",AllFilesObj);
main_form.append("fileInfo",JSON.stringify(AllFilesObj))
this.multifilesService.saveFiles(main_form).subscribe(data =>
//console.log("result is ", data)
)
Multifiles.service.ts
same code already in the question section.
MultiFileController.java
@PostMapping("uploadFiles")
public String uploadMultiFiles(HttpServletRequest request)
System.out.println("hitting uploadFiles");
//System.out.println("data is "+ upladeedFiles);
List documentList= new ArrayList<>();
//System.out.println(request.getParameter("fileInfo"));
JSONArray jsonArray = new JSONArray(request.getParameter("fileInfo"));
for (int i = 0; i < jsonArray.length(); i++)
JSONObject jsonObj = jsonArray.getJSONObject(i);
documentList.add(jsonObj);
System.out.println("index "+ i +" -- "+jsonObj);
MultipartHttpServletRequest multiPartRequest = new DefaultMultipartHttpServletRequest(request);
try
multiPartRequest = (MultipartHttpServletRequest) request;
multiPartRequest.getParameterMap();
Iterator<String> itr = multiPartRequest.getFileNames();
while (itr.hasNext())
MultipartFile mFile = multiPartRequest.getFile(itr.next());
System.out.println("FileName is "+mFile.getOriginalFilename());
// Do something with the mfile based on your requirement
catch (Exception e)
e.printStackTrace();
return "uploaded ";
如果您不理解代码,请将其 fork 到您的存储库,然后使用控制台日志进行克隆和调试,这样您就可以清楚地理解代码。谢谢
【讨论】:
以上是关于如何使用添加按钮在 Angular 6 中上传多个文件?的主要内容,如果未能解决你的问题,请参考以下文章