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状态。
修复步骤
- 完善
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); }
- 额外优化建议
- 防止提前提交:添加
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
相关产品推荐
相关产品推荐

