如何使用添加按钮在 Angular 6 中上传多个文件? [英] How to Upload multiple files in Angular 6 with ADDMORE button?
问题描述
你好,Everone.我一直在尝试上传上面(图片)用例.我知道当我们只有一个文件时这很容易.但现在情况不同了,它由带有文件的对象数组组成.现在我的问题是如何使用对象数组呈现 formdata 对象,其中每个对象由一个文件组成.对于动态形式,我使用了角度反应形式.任何人都可以建议我如何通过单击保存按钮将整个数据发送到支持.对于后端,我使用了 Springmvc.提前致谢.
我的 Github 上的完整源代码:源
multi-files-upload.component.html
<section class="内容"><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>上传文件<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"><tr *ngIf="i==0" class="active"><th>文档名称</th><第>文档描述<th>文档文件</th><th> </th></tr><tr><td><div class="form-group required"><input type="text" class="form-control" name="doc_name" formControlName="doc_name" placeholder="输入文档类别"必需=""><div class="help-block"></div></td><td><div class="form-group"><input type="text" class="form-control" name="doc_description" formControlName="doc_description" maxlength="100" placeholder="输入文档相关描述"必需=""><div class="help-block"></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>
</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>
<div class="pull-right"><a class="btn btn-sm btn-success" title="添加更多" style="" (click)="addItem()"><i class="fa fa-plus-square"></i> 添加更多
<!--./col-->
<!--./row-->
<!--./box-body--><div class="box-footer" style="align-content: center"><button type="submit" class="btn btn-primary pull-right">保存</button>
</表单>
</节>
multi-files-upload.component.ts
import { Component, OnInit, Renderer } from '@angular/core';import { FormBuilder, FormGroup, Validators, FormArray, FormControl, NgForm } from '@angular/forms';从 './multifiles.service' 导入 { MultifilesService }@成分({选择器:'app-multi-files-upload',templateUrl: './multi-files-upload.component.html',styleUrls: ['./multi-files-upload.component.css']})导出类 MultiFilesUploadComponent 实现 OnInit {构造函数(私有渲染器:渲染器,私有表单构建器:FormBuilder,私有多文件服务:多文件服务) { }公共文档组:FormGroup;ngOnInit() {this.documentGrp = this.formBuilder.group({文档名称:'',doc_description: '',文件文件:文件,项目:this.formBuilder.array([this.createUploadDocuments()])});}公共文档名称 = "";公共 doc_description = "";公共文档文件:文件;createUploadDocuments(): FormGroup {返回 this.formBuilder.group({文档名称:'',doc_description: '',文件文件:文件,});}获取项目():FormArray {返回 this.documentGrp.get('items') 作为 FormArray;};添加项目():无效{this.items.insert(0, this.createUploadDocuments())}删除项目(索引:数字){this.items.removeAt(index);}公共文件选择事件(文件输入:任何){if (fileInput.target.files && fileInput.target.files[0]) {var reader = new FileReader();reader.onload = (event: any) =>{}this.documentFile = (fileInput.target.files[0]);console.log("文档是" + JSON.stringify(fileInput.target.files[0].name));reader.readAsDataURL(fileInput.target.files[0]);}}公共 OnSubmit(formValue: any) {让 total_form: FormData[] = [];控制台日志(formValue.items)formValue.items.forEach(元素 => {让 upl_fom: FormData = new FormData();console.log("每个元素都是", 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("结果为", 数据)})}}
Multifiles.service.ts
import { Injectable } from '@angular/core';从 '@angular/common/http' 导入 { HttpClient,HttpHeaders };@Injectable({提供在:'根'})导出类 MultifilesService {构造函数(私有http:HttpClient){}保存文件(total_form){return this.http.post("http://localhost:8181/uploadFiles",total_form);}}
上传控制器.java
@PostMapping("uploadFiles")public String uploadMultiFiles(HttpServletRequest 请求){System.out.println("点击上传文件");枚举 e =request.getParameterNames();while(e.hasMoreElements()){System.out.println(e.nextElement());}MultipartHttpServletRequest multiPartRequest = new DefaultMultipartHttpServletRequest(request);尝试 {multiPartRequest = (MultipartHttpServletRequest) 请求;multiPartRequest.getParameterMap();//多部分请求.迭代器字符串 >it = multiPartRequest.getFileNames();int i = 1;而 (it.hasNext()) {MultipartFile multipart = multiPartRequest.getFile(it.next());System.out.println("文件名是"+multipart.getOriginalFilename());}}catch(异常前){}返回已上传";}
解决方案 在尝试使用不同的场景渲染 formdata 对象后,我在一个场景中成功了.
GitHub 链接:来源
更新的文件
multi-files-upload.component.html
<section class="内容"><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>上传文件<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"><tr *ngIf="i==0" class="active"><th>文档名称</th><第>文档描述<th>文档文件</th><th> </th></tr><tr><td><div class="form-group required"><input type="text" class="form-control" name="doc_name" formControlName="doc_name" placeholder="输入文档类别"必需=""><div class="help-block"></div></td><td><div class="form-group"><input type="text" class="form-control" name="doc_description" formControlName="doc_description" maxlength="100" placeholder="输入文档相关描述"必需=""><div class="help-block"></div>
</td><td><div class="form-group required"><input type="file" title="Browse Document" (change)="fileSelectionEvent($event,i)" required=""><div class="help-block"></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>
<div class="pull-right"><button type="submit" class="btn btn-sm btn-success" title="添加更多" style="" (click)="addItem()">添加更多</button>
<!--./col-->
<!--./row-->
<!--./box-body--><div class="box-footer" style="align-content: center"><button type="submit" class="btn btn-primary pull-right">保存</button>
</表单>
</节>
multi-files-upload.component.ts
import { Component, OnInit, Renderer, ViewChild } from '@angular/core';import { FormBuilder, FormGroup, Validators, FormArray, FormControl, NgForm } from '@angular/forms';从 './multifiles.service' 导入 { MultifilesService }@成分({选择器:'app-multi-files-upload',templateUrl: './multi-files-upload.component.html',styleUrls: ['./multi-files-upload.component.css']})导出类 MultiFilesUploadComponent 实现 OnInit {构造函数(私有渲染器:渲染器,私有表单构建器:FormBuilder,私有多文件服务:多文件服务) { }公共文档组:FormGroup;公共总文件:数组<文件>=[];公共总文件名 = [];public lengthCheckToaddMore =0;ngOnInit() {this.documentGrp = this.formBuilder.group({文档名称:'',doc_description: '',文档文件:新的表单控件(文件),项目:this.formBuilder.array([this.createUploadDocuments()])});}createUploadDocuments(): FormGroup {返回 this.formBuilder.group({文档名称:'',doc_description: '',文档文件:文件});}获取项目():FormArray {返回 this.documentGrp.get('items') 作为 FormArray;};添加项目():无效{//console.log("长度为",this.totalfiles.length);//console.log("lengthCheckToaddMore ", this.lengthCheckToaddMore);如果(this.totalfiles.length!=0)if( this.items.value[0].doc_name != "" &&&& this.items.value[0].doc_description != "" && ((this.lengthCheckToaddMore) === (this.总文件数.长度))){this.items.insert(0, this.createUploadDocuments())this.lengthCheckToaddMore=this.lengthCheckToaddMore+1;}}删除项目(索引:数字){this.totalfiles.splice(index);this.totalFileName.splice(index);this.items.removeAt(index);this.lengthCheckToaddMore=this.lengthCheckToaddMore-1;//console.log("name are ",this.totalFileName);}公共文件选择事件(文件输入:任何,旧索引){//console.log("oldIndex is ", oldIndex);if (fileInput.target.files && fileInput.target.files[0]) {var reader = new FileReader();reader.onload = (event: any) =>{}如果(旧索引== 0){this.totalfiles.unshift((fileInput.target.files[0]))this.totalFileName.unshift(fileInput.target.files[0].name)}别的{this.totalfiles[oldIndex]=(fileInput.target.files[0]);this.totalFileName[oldIndex]=fileInput.target.files[0].name}reader.readAsDataURL(fileInput.target.files[0]);}如果(this.totalfiles.length == 1){this.lengthCheckToaddMore=1;}}公共 OnSubmit(formValue: any) {让 main_form: FormData = new FormData();for(let j=0;jthis.totalfiles[j]);console.log("名称是",this.totalFileName[j]);main_form.append(this.totalFileName[j],<File>this.totalfiles[j])}控制台日志(formValue.items)//reverseFileNames=this.totalFileName.reverse();让 AllFilesObj= []formValue.items.forEach((element, index) => {console.log("索引为",index);console.log("元素是", element);让 eachObj={'doc_name' : element.doc_name,'doc_description' : element.doc_description,'file_name' : this.totalFileName[index]}AllFilesObj.push(eachObj);});//console.log("数组数据为",AllFilesObj);main_form.append("fileInfo",JSON.stringify(AllFilesObj))this.multifilesService.saveFiles(main_form).subscribe(data => {//console.log("result is ", data)})}}
Multifiles.service.ts
问题部分中已有相同的代码.
MultiFileController.java
@PostMapping("uploadFiles")public String uploadMultiFiles(HttpServletRequest 请求){System.out.println("点击上传文件");//System.out.println("数据为"+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);尝试 {multiPartRequest = (MultipartHttpServletRequest) 请求;multiPartRequest.getParameterMap();迭代器<字符串>itr = multiPartRequest.getFileNames();而 (itr.hasNext()) {MultipartFile mFile = multiPartRequest.getFile(itr.next());System.out.println("文件名是"+mFile.getOriginalFilename());//根据您的要求对 mfile 做一些事情}} 捕获(异常 e){e.printStackTrace();}返回已上传";}
如果您不理解代码,请将其分叉到您的存储库,然后使用控制台日志进行克隆和调试,然后您就可以清楚地理解代码.谢谢
Hello, Everone. I've been trying to Upload above(image) use case. I know it is very easy when we have a single file. but now the scenario is different it consists of an array of objects with the file.
Now my question is how can I render the formdata object with the array of objects where each object consists of a file. For dynamic form, I used angular reactive forms. Can anyone please suggest me how can send whole data to the backed with the single click on save button.
For backend I used Springmvc.
Thanks in advance.
FullSource code availabe on my Github : Source
multi-files-upload.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>
multi-files-upload.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);
}
}
UploadController.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 ";
}
解决方案 After trying with different scenarios to rendering the formdata object, I succeed in one scenario.
GitHub Link: Source
Updated files
multi-files-upload.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>
multi-files-upload.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 ";
}
If you don't understand the code please fork it to your repository then clone and debug with console logs then you can clearly understand the code. Thanks
这篇关于如何使用添加按钮在 Angular 6 中上传多个文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文
登录
关闭
扫码关注1秒登录
发送“验证码”获取
|
15天全站免登陆