web-dev-qa-db-ja.com

Angular 6で複数のファイルをADDMOREボタンでアップロードする方法は?

こんにちは、エバーワン。上記(画像)のユースケースをアップロードしようとしています。ファイルが1つしかない場合は非常に簡単です。しかし、今はシナリオが異なり、ファイルを含むオブジェクトの配列で構成されています。ここで私の質問は、formdataオブジェクトを、各オブジェクトがファイルで構成されるオブジェクトの配列でどのようにレンダリングできるかです。動的フォームには、angular反応性フォームを使用しました。保存ボタンを1回クリックするだけで、データ全体をバックアップに送信する方法を誰かに提案できますか?バックエンドには、Springmvcを使用しました。よろしくお願いします。

私のGithubで利用可能なFullSourceコード: 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>&nbsp;</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>&nbsp; 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 ";
        }
3
SHIVA

さまざまなシナリオでformdataオブジェクトをレンダリングした後、1つのシナリオで成功しました。

GitHubリンク: ソース

更新されたファイル

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>&nbsp;</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 ";
        }

コードがわからない場合は、リポジトリにフォークしてから、クローンしてコンソールログでデバッグすると、コードを明確に理解できます。ありがとう

2
SHIVA