7

嗨,我是 Angular 的新手,目前我正在使用 Angular 11 项目,我必须上传一个 CSV 文件并在客户端提取文件的记录,然后通过 ASP.NET Web API 将它们保存在数据库中。

在这里,我按照教程并尝试获取角度侧的 CSV 文件的数据并将它们显示在同一页面中。

然后我得到了这个错误,

键入“文件 | null' 不可分配给类型“文件”。类型“null”不可分配给类型“文件”.ts(2322)

我尝试了很多东西,但仍然无法解决这个问题。请你帮助我好吗?

这是我的 .ts 文件,

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-file-upload',
  templateUrl: './file-upload.component.html',
  styles: [
  ]
})
export class FileUploadComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

  lines: any = [];
  linesR: any = [];

  changeListener(files: FileList) {
    console.log(files);
    if (files && files.length > 0) {
      let file: File = files.item(0);
      console.log(file.name);
      console.log(file.size);
      console.log(file.type);

      let reader: FileReader = new FileReader();
      reader.readAsText(file);
      reader.onload = (e) => {
        let csv: any = reader.result;
        let allTextLines = [];
        allTextLines = csv.split(/\r|\n|\r/);

        let headers = allTextLines[0].split(';');
        let data = headers;
        let tarr = [];
        for (let j = 0; j < headers.length; j++) {
          tarr.push(data[j]);
        }
        this.lines.push(tarr);
        let tarrR = [];
        let arrl = allTextLines.length;
        let rows = [];
        for (let i = 1; i < arrl; i++) {
          rows.push(allTextLines[i].split(';'));
        }
        for (let j = 0; j < arrl; j++) {
          tarrR.push(rows[j]);
        }
        this.linesR.push(tarrR);
      }
    }
  }
}

这是我的 .html 文件

    <div class="container">
    <h1 style="text-align: center"> File Upload </h1>
    <br><br>

    <input class="form-control" type="file" class="upload" (change)="changeListener($event.target.files)">

    <table class="table table-bordered table-dark">
        <thead>
            <tr>
                <th *ngFor="let item of lines[0]; let i = index">
                    {{item}}
                </th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let item of linesR[0]; let i = index">
                <td *ngFor="let itemm of lines[0]; let j = index">
                    {{item[j]}}
                </td>
            </tr>
        </tbody>
    </table>
</div>

这是我得到的错误

谢谢!

4

6 回答 6

2

尝试使用:

文件上传.component.ts

import { Component, OnInit, VERSION } from "@angular/core";
    
@Component({
  selector: 'app-file-upload',
  templateUrl: './file-upload.component.html',
  styles: []
})
export class FileUploadComponent implements OnInit {
      name = "Angular " + VERSION.major;
    
      lines: any = [];
      linesR: any = [];
    
      ngOnInit() {}
    
      changeListener(files) {
        let fileList = (<HTMLInputElement>files.target).files;
        if (fileList && fileList.length > 0) {
          let file: File = fileList[0];
          console.log(file.name);
          console.log(file.size);
          console.log(file.type);
    
          let reader: FileReader = new FileReader();
          reader.readAsText(file);
          reader.onload = e => {
            let csv: any = reader.result;
            let allTextLines = [];
            allTextLines = csv.split(/\r|\n|\r/);
    
            let headers = allTextLines[0].split(";");
            let data = headers;
            let tarr = [];
            for (let j = 0; j < headers.length; j++) {
              tarr.push(data[j]);
            }
            this.lines.push(tarr);
            let tarrR = [];
            let arrl = allTextLines.length;
            let rows = [];
            for (let i = 1; i < arrl; i++) {
              rows.push(allTextLines[i].split(";"));
            }
            for (let j = 0; j < arrl; j++) {
              tarrR.push(rows[j]);
            }
            this.linesR.push(tarrR);
          };
        }
      }
    }

文件上传.component.html

<div class="container">
  <h1 style="text-align: center">File Upload</h1>
  <br /><br />

  <input
    class="form-control"
    type="file"
    class="upload"
    (change)="changeListener($event)"
  />

  <table class="table table-bordered table-dark">
    <thead>
      <tr>
        <th *ngFor="let item of lines[0]; let i = index">
          {{item}}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let item of linesR[0]; let i = index">
        <td *ngFor="let itemm of lines[0]; let j = index">
          {{item[j]}}
        </td>
      </tr>
    </tbody>
  </table>
</div>
于 2021-02-01T07:55:22.797 回答
1

如果您确定您将在文件项中包含值,那么您可以说:

let file: File = files.item(0) as File;
于 2021-02-01T09:08:25.150 回答
0

我对此没有任何问题:

const file = files.item(0);
if (file && file !== null) {
  ...

和这个:

const file: any = files.item(0);
if (file && file !== null) {
  ...

即使我使用files[0]而不是files.item(0). 而这一切都在strict模式中。

于 2021-02-01T09:15:21.773 回答
0

您正在使用strict: true打字稿。那挺好的!你面临的问题是这件作品:

let file: File = files.item(0);

可以返回未定义,即使您之前检查了长度。这将使类型File | null ,但你说它应该只是File

最好将其更改为以下内容:

changeListener(files: FileList) {
 const file: File | null = files?.item(0);

 if (file) {
   // here `file` will have type `File` because it has been asserted with the `if`
      console.log(file.size);
      console.log(file.type);

      let reader: FileReader = new FileReader();
      reader.readAsText(file);
      reader.onload = (e) => {
  //...
 
于 2021-02-01T08:00:52.043 回答
0

如果你想让一个文件 Null 这样做 file= new File([],''); 它会将文件对象重新初始化为一个空文件对象

于 2022-03-04T16:49:15.927 回答
0

另一个解决方案是 -

let file: File | any = null;

或者

let file: File | null = null;
于 2022-02-02T10:37:35.523 回答