You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 5中UploadFile函数内this.data始终为undefined求助

问题:Angular文件上传时this.data始终为undefined

我是Angular初学者,自学后实现了以下文件上传功能:一个Angular页面,支持上传含5个表头的.csv或.xlsx文件,点击上传后通过.NET WebAPI将文件保存至服务器,传递文件名和JSON格式的文件内容。但UploadFile函数内的this.data始终显示为undefined,请帮我指出代码中的问题。

组件代码

import { Component, ElementRef, Input, ViewChild } from '@angular/core';
import { Response } from '@angular/http';
import { LoggerService } from '../../core/logger.service'
import { Router } from '@angular/router';
import * as Util from '../../shared/Utility';
import { HttpClient } from '@angular/common/http';
import { DataService } from '../../services/data.service';
import * as XLSX from 'xlsx';

@Component({
  templateUrl: './system.component.html',
  styleUrls: ['./system.component.css']
})

export class SystemComponent {
  constructor(private router: Router, private http: HttpClient, private dataService: DataService) { }

  /*fileName = '';*/
  fileSelected = false;
  invalidFileType = false;
  file: File = null; // Variable to store file
  data: any;
  jsonData: any;
  displayError: boolean;
  errorText: string;
  responseData: any;

  @ViewChild('fileUpload') fileUpload: ElementRef;

  Reset(form) {
    console.log("Reset is clicked");
    this.fileSelected = false;
    this.file = null;
    this.invalidFileType = false;
    this.data = null;
    this.jsonData = null;
    this.responseData = null;
    this.displayError = false;
    this.errorText = null;
    this.fileUpload.nativeElement.value = "";
    console.log("Reset completed");
  }

  UploadFile(filevalue) {

    console.log("UploadFile");

    const reqbody = {
      filename: this.file.name,
      lines: JSON.stringify(this.data)
    };

    var route = "FileSave";
    this.dataService.post(reqbody, route).subscribe(
      (data: any[]) => {
        console.log("Response data: " + data);
        LoggerService.success(`File successfully uploaded to server`, true, false);
        this.responseData = data;
      },
      (error: Response) => {
        this.displayError = true;
        this.errorText = `Error saving API service ${error.status}`;
      });
  }

  onFileChange(event: any): void {
    this.file = event.target.files[0];

    if (this.file) {
      console.log("this.file.type: " + this.file.type);

      const fileName = this.file.name;
      const fileExtension = fileName.split('.').pop().toLowerCase();

      // Define allowed file extensions
      const allowedExtensions = ['xlsx', 'csv'];

      if (allowedExtensions.indexOf(fileExtension) === -1) {
        LoggerService.error(`Invalid file type. Allowed: .xlsx,.csv`, true, true);
        this.fileSelected = false;
        this.file = null;
        this.invalidFileType = true;
        this.data = null;
        this.jsonData = null;
        this.responseData = null;
        this.displayError = false;
        this.errorText = null;
        this.fileUpload.nativeElement.value = "";
      }
      else {
        this.fileSelected = true;
        this.invalidFileType = false;
        this.readFile();
      }
    }
  }

  readFile(): void {
    const fileReader = new FileReader();

    fileReader.onload = (e: any) => {
      const binaryString = e.target.result;
      console.log(binaryString);
      const workBook = XLSX.read(binaryString, { type: 'binary' });

      const workSheetName = workBook.SheetNames[0];
      const workSheet = workBook.Sheets[workSheetName];

      // Parse the Excel data into JSON format
      this.data = XLSX.utils.sheet_to_json(workSheet);
      console.log(this.data);
    }
  }
}

HTML代码

<div class="search-form">
  <mat-card>
    <div class="row">
      <div class="col-lg-1">
      </div>
      <div class="col-lg-11">
        <h2 class="font--bold">system</h2>
        <form name="#systemform" #systemform="ngForm" role="search" (ngSubmit)="UploadFile(systemform.value)" novalidate>
          <!--Start-->
          <div class="row">
            <div class="col-md-4">
              <input #fileUpload type="file" class="file-upload" name="fileUpload" id="fileUpload" accept=".xlsx,.xls,.csv" required (change)="onFileChange($event)">
              <div class="invalidFileTypeAlert" *ngIf="invalidFileType">Invalid file type. Allowed: .xlsx, .xls, .csv</div>
            </div>
            <div class="col-md-4">
              <button (click)="UploadFile(systemform.value)" type="button" mat-raised-button color="primary" [disabled]="!fileSelected">Upload</button>
              <button (click)="Reset(systemform.value)" mat-raised-button [disabled]="!fileSelected">Reset</button>
              <h5>Please upload excel file </h5>
            </div>
          </div>
        </form>
      </div>
    </div>
  </mat-card>
</div>
问题原因及修复方案

核心问题

readFile方法中缺少触发文件读取的关键代码:创建FileReader实例后,没有调用readAsBinaryString方法启动文件读取流程,导致onload回调从未执行,this.data始终处于初始的undefined状态。

修复步骤

  1. 完善readFile方法,添加文件读取触发代码:
readFile(): void {
  const fileReader = new FileReader();

  fileReader.onload = (e: any) => {
    const binaryString = e.target.result;
    console.log(binaryString);
    const workBook = XLSX.read(binaryString, { type: 'binary' });

    const workSheetName = workBook.SheetNames[0];
    const workSheet = workBook.Sheets[workSheetName];

    // Parse the Excel data into JSON format
    this.data = XLSX.utils.sheet_to_json(workSheet);
    console.log(this.data);
  };

  // 关键:启动文件读取操作
  fileReader.readAsBinaryString(this.file);
}
  1. 额外优化建议
  • 防止提前提交:添加isReading状态变量,避免用户在文件未读取完成时点击上传按钮。修改组件类:
    isReading = false; // 添加状态变量
    
    然后修改上传按钮的禁用条件:
    <button (click)="UploadFile(systemform.value)" type="button" mat-raised-button color="primary" [disabled]="!fileSelected || isReading">Upload</button>
    
    并在readFile中更新状态:
    readFile(): void {
      const fileReader = new FileReader();
      this.isReading = true;
    
      fileReader.onload = (e: any) => {
        // ...原有解析逻辑...
        this.isReading = false;
      };
    
      // 添加错误处理
      fileReader.onerror = () => {
        LoggerService.error('文件读取失败,请检查文件是否损坏', true, true);
        this.isReading = false;
        this.fileSelected = false;
      };
    
      fileReader.readAsBinaryString(this.file);
    }
    

内容的提问来源于stack exchange,提问作者user17824023

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:45:01