我是Angular的初学者,我想知道如何创建Angular 5文件上传部分,我试图找到任何教程或文档,但我在任何地方都看不到任何东西。对此有什么想法吗?我尝试了ng4-files,但它不适用于Angular 5


当前回答

使用Angular和nodejs上传文件的完整示例(express)

HTML代码

            <div class="form-group">
                <label for="file">Choose File</label><br/>
                <input type="file" id="file" (change)="uploadFile($event.target.files)" multiple>
            </div>

TS组件代码

uploadFile(files) {
    console.log('files', files)
        var formData = new FormData();

    for(let i =0; i < files.length; i++){
      formData.append("files", files[i], files[i]['name']);
        }

    this.httpService.httpPost('/fileUpload', formData)
      .subscribe((response) => {
        console.log('response', response)
      },
        (error) => {
      console.log('error in fileupload', error)
       })
  }

Node Js代码

上传火灾控制器

function start(req, res) {
fileUploadService.fileUpload(req, res)
    .then(fileUploadServiceResponse => {
        res.status(200).send(fileUploadServiceResponse)
    })
    .catch(error => {
        res.status(400).send(error)
    })
}

module.exports.start = start

使用multer上传服务

const multer = require('multer') // import library
const moment = require('moment')
const q = require('q')
const _ = require('underscore')
const fs = require('fs')
const dir = './public'

/** Store file on local folder */
let storage = multer.diskStorage({
destination: function (req, file, cb) {
    cb(null, 'public')
},
filename: function (req, file, cb) {
    let date = moment(moment.now()).format('YYYYMMDDHHMMSS')
    cb(null, date + '_' + file.originalname.replace(/-/g, '_').replace(/ /g,     '_'))
}
})

/** Upload files  */
let upload = multer({ storage: storage }).array('files')

/** Exports fileUpload function */
module.exports = {
fileUpload: function (req, res) {
    let deferred = q.defer()

    /** Create dir if not exist */
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir)
        console.log(`\n\n ${dir} dose not exist, hence created \n\n`)
    }

    upload(req, res, function (err) {
        if (req && (_.isEmpty(req.files))) {
            deferred.resolve({ status: 200, message: 'File not attached', data: [] })
        } else {
            if (err) {
                deferred.reject({ status: 400, message: 'error', data: err })
            } else {
                deferred.resolve({
                    status: 200,
                    message: 'File attached',
                    filename: _.pluck(req.files,
                        'filename'),
                    data: req.files
                })
            }
        }
    })
    return deferred.promise
}
}

其他回答

就我个人而言,我使用ngx-material-file-input作为前端,Firebase作为后端。更准确地说,后端是与Cloud Firestore结合的Cloud Storage for Firebase。下面是一个示例,它限制文件不大于20 MB,并且只接受某些文件扩展名。我还使用Cloud Firestore来存储上传文件的链接,但你可以跳过这个。

contact.component.html

<mat-form-field>
  <!--
    Accept only files in the following format: .doc, .docx, .jpg, .jpeg, .pdf, .png, .xls, .xlsx. However, this is easy to bypass, Cloud Storage rules has been set up on the back-end side.
  -->
  <ngx-mat-file-input
    [accept]="[
      '.doc',
      '.docx',
      '.jpg',
      '.jpeg',
      '.pdf',
      '.png',
      '.xls',
      '.xlsx'
    ]"
    (change)="uploadFile($event)"
    formControlName="fileUploader"
    multiple
    aria-label="Here you can add additional files about your project, which can be helpeful for us."
    placeholder="Additional files"
    title="Additional files"
    type="file"
  >
  </ngx-mat-file-input>
  <mat-icon matSuffix>folder</mat-icon>
  <mat-hint
    >Accepted formats: DOC, DOCX, JPG, JPEG, PDF, PNG, XLS and XLSX,
    maximum files upload size: 20 MB.
  </mat-hint>
  <!--
    Non-null assertion operators are required to let know the compiler that this value is not empty and exists.
  -->
  <mat-error
    *ngIf="contactForm.get('fileUploader')!.hasError('maxContentSize')"
  >
    This size is too large,
    <strong
      >maximum acceptable upload size is
      {{
        contactForm.get('fileUploader')?.getError('maxContentSize')
          .maxSize | byteFormat
      }}</strong
    >
    (uploaded size:
    {{
      contactForm.get('fileUploader')?.getError('maxContentSize')
        .actualSize | byteFormat
    }}).
  </mat-error>
</mat-form-field>

ts(大小验证器部分)

import { FileValidator } from 'ngx-material-file-input';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

/**
 * @constructor
 * @description Creates a new instance of this component.
 * @param  {formBuilder} - an abstraction class object to create a form group control for the contact form.
 */
constructor(
  private angularFirestore: AngularFirestore,
  private angularFireStorage: AngularFireStorage,
  private formBuilder: FormBuilder
) {}

public maxFileSize = 20971520;
public contactForm: FormGroup = this.formBuilder.group({
    fileUploader: [
      '',
      Validators.compose([
        FileValidator.maxContentSize(this.maxFileSize),
        Validators.maxLength(512),
        Validators.minLength(2)
      ])
    ]
})

ts(文件上传器部分)

import { AngularFirestore } from '@angular/fire/firestore';
import {
  AngularFireStorage,
  AngularFireStorageReference,
  AngularFireUploadTask
} from '@angular/fire/storage';
import { catchError, finalize } from 'rxjs/operators';
import { throwError } from 'rxjs';

public downloadURL: string[] = [];
/**
* @description Upload additional files to Cloud Firestore and get URL to the files.
   * @param {event} - object of sent files.
   * @returns {void}
   */
  public uploadFile(event: any): void {
    // Iterate through all uploaded files.
    for (let i = 0; i < event.target.files.length; i++) {
      const randomId = Math.random()
        .toString(36)
        .substring(2); // Create random ID, so the same file names can be uploaded to Cloud Firestore.

      const file = event.target.files[i]; // Get each uploaded file.

      // Get file reference.
      const fileRef: AngularFireStorageReference = this.angularFireStorage.ref(
        randomId
      );

      // Create upload task.
      const task: AngularFireUploadTask = this.angularFireStorage.upload(
        randomId,
        file
      );

      // Upload file to Cloud Firestore.
      task
        .snapshotChanges()
        .pipe(
          finalize(() => {
            fileRef.getDownloadURL().subscribe((downloadURL: string) => {
              this.angularFirestore
                .collection(process.env.FIRESTORE_COLLECTION_FILES!) // Non-null assertion operator is required to let know the compiler that this value is not empty and exists.
                .add({ downloadURL: downloadURL });
              this.downloadURL.push(downloadURL);
            });
          }),
          catchError((error: any) => {
            return throwError(error);
          })
        )
        .subscribe();
    }
  }

storage.rules

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
        allow read; // Required in order to send this as attachment.
      // Allow write files Firebase Storage, only if:
      // 1) File is no more than 20MB
      // 2) Content type is in one of the following formats: .doc, .docx, .jpg, .jpeg, .pdf, .png, .xls, .xlsx.
      allow write: if request.resource.size <= 20 * 1024 * 1024
        && (request.resource.contentType.matches('application/msword')
        || request.resource.contentType.matches('application/vnd.openxmlformats-officedocument.wordprocessingml.document')
        || request.resource.contentType.matches('image/jpg')
        || request.resource.contentType.matches('image/jpeg')
        || request.resource.contentType.matches('application/pdf')
                || request.resource.contentType.matches('image/png')
        || request.resource.contentType.matches('application/vnd.ms-excel')
        || request.resource.contentType.matches('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'))
    }
  }
}

我使用的是Angular 5.2.11, 我喜欢Gregor Doroschenko提供的解决方案,但是我注意到上传的文件是零字节的,我必须做一个小小的改变才能让它为我工作。

postFile(fileToUpload: File): Observable<boolean> {
  const endpoint = 'your-destination-url';
  return this.httpClient
    .post(endpoint, fileToUpload, { headers: yourHeadersConfig })
    .map(() => { return true; })
    .catch((e) => this.handleError(e));
}

下面几行(formData)对我不起作用。

const formData: FormData = new FormData();
formData.append('fileKey', fileToUpload, fileToUpload.name);

https://github.com/amitrke/ngrke/blob/master/src/app/services/fileupload.service.ts

试试这个

安装

npm install primeng --save

进口

import {FileUploadModule} from 'primeng/primeng';

Html

<p-fileUpload name="myfile[]" url="./upload.php" multiple="multiple"
    accept="image/*" auto="auto"></p-fileUpload>

超文本标记语言


    <div class="form-group">
      <label for="file">Choose File</label><br /> <input type="file" id="file" (change)="uploadFiles($event.target.files)">
    </div>

    <button type="button" (click)="RequestUpload()">Ok</button>

ts文件

public formData = new FormData();
ReqJson: any = {};

uploadFiles( file ) {
        console.log( 'file', file )
        for ( let i = 0; i < file.length; i++ ) {
            this.formData.append( "file", file[i], file[i]['name'] );
        }
    }

RequestUpload() {
        this.ReqJson["patientId"] = "12"
        this.ReqJson["requesterName"] = "test1"
        this.ReqJson["requestDate"] = "1/1/2019"
        this.ReqJson["location"] = "INDIA"
        this.formData.append( 'Info', JSON.stringify( this.ReqJson ) )
            this.http.post( '/Request', this.formData )
                .subscribe(( ) => {                 
                });     
    }

后端Spring(java文件)


import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class Request {
    private static String UPLOADED_FOLDER = "c://temp//";

    @PostMapping("/Request")
    @ResponseBody
    public String uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("Info") String Info) {
        System.out.println("Json is" + Info);
        if (file.isEmpty()) {
            return "No file attached";
        }
        try {
            // Get the file and save it somewhere
            byte[] bytes = file.getBytes();
            Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
            Files.write(path, bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "Succuss";
    }
}

我们必须在C驱动器中创建一个文件夹“temp”,然后这段代码将在控制台中打印Json并将上传的文件保存在创建的文件夹中

下面是一个上传文件到api的例子:

步骤1:HTML模板

定义文件类型的简单输入标记。为(change)-event添加一个处理选择文件的函数。

<div class="form-group">
    <label for="file">Choose File</label>
    <input type="file"
           id="file"
           (change)="handleFileInput($event.target.files)">
</div>

步骤2:在TypeScript中处理上传

为所选文件定义一个默认变量。

fileToUpload: File | null = null;

创建你在(change)-event中使用的函数:

handleFileInput(files: FileList) {
    this.fileToUpload = files.item(0);
}

如果你想处理多文件选择,那么你可以遍历这个文件数组。

现在通过调用file-upload.service创建文件上传函数:

uploadFileToActivity() {
    this.fileUploadService.postFile(this.fileToUpload).subscribe(data => {
      // do something, if upload success
      }, error => {
        console.log(error);
      });
  }

第三步:文件上传服务

通过post方法上传文件,你应该使用FormData,因为这样你可以添加文件到http请求。

postFile(fileToUpload: File): Observable<boolean> {
    const endpoint = 'your-destination-url';
    const formData: FormData = new FormData();
    formData.append('fileKey', fileToUpload, fileToUpload.name);
    return this.httpClient
      .post(endpoint, formData, { headers: yourHeadersConfig })
      .map(() => { return true; })
      .catch((e) => this.handleError(e));
}

所以,这是一个非常简单的工作例子,我每天都在工作中使用。