问题描述
我试图从FileReader
返回结果,但发现了此实现.但是由于它已经过时,所以我想知道如何使用ES6 Promises
或Rx Observables
来实现相同的功能.
I was trying to return result from FileReader
and I found this implementation. But since it is outdated, I'm wondering how to implement the same using ES6 Promises
or Rx Observables
.
下面是我引用上述链接的代码,它可以按预期工作.
Below is my code with reference to the aforementioned link and it works as expected.
import { Injectable } from '@angular/core';
import * as XLSX from 'xlsx';
import * as XLS from 'xlsx';
@Injectable()
export class ExcelReaderService {
constructor() { }
importFromExcel(ev): JQueryPromise<any> {
let deferred = $.Deferred();
let regex = /^([a-zA-Z0-9\s_\\.\-:])+(.xlsx|.xls)$/;
let workbook;
let excelInJSON;
if (regex.test(ev.target.files[0].name.toString().toLowerCase())) {
let xlsxflag = false; /*Flag for checking whether excel is .xls format or .xlsx format*/
if (ev.target.files[0].name.toString().toLowerCase().indexOf(".xlsx") > 0) {
xlsxflag = true;
}
let fileReader = new FileReader();
fileReader.onload = (ev) => {
let binary = "";
let bytes = new Uint8Array((<any>ev.target).result);
let length = bytes.byteLength;
for (let i = 0; i < length; i++) {
binary += String.fromCharCode(bytes[i]);
}
/*Converts the excel data in to json*/
if (xlsxflag) {
workbook = XLSX.read(binary, { type: 'binary', cellDates: true, cellStyles: true });
// only first sheet
excelInJSON = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]);
deferred.resolve(excelInJSON);
}
else {
workbook = XLS.read(binary, { type: 'binary', cellDates: true, cellStyles: true });
excelInJSON = <{}[]>XLS.utils.sheet_to_row_object_array(workbook.Sheets[workbook.SheetNames[0]]);
deferred.resolve(excelInJSON);
}
}
// init read
if (xlsxflag)
fileReader.readAsArrayBuffer((<any>ev.target).files[0]);
else
fileReader.readAsBinaryString((<any>ev.target).files[0]);
} else {
deferred.reject('Invalid file!');
}
return deferred.promise();
}
}
在使用者component
this.excelReaderService.importFromExcel(ev).then((result) => {
this.detailHeadings = Object.keys(result[0]);
this.detailData = result;
})
如果有人对我有所帮助,那将是很棒的,因为我是异步编程的新手.
It'll be great if someone helps me with this as I'm new to asynchronous programming.
推荐答案
这是我的工作方式,以防万一有人想要Angular服务来读取Excel文件并以observable
内容作为JSON
进行响应的情况.
This is how I did it, in case anyone wants an Angular service that reads Excel files and responds with an observable
of the content as JSON
.
我正在使用 SheetJS 来读取文件并输出JSON
.
I'm using SheetJS for reading the file and outputting JSON
.
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import * as XLSX from 'xlsx';
@Injectable()
export class ExcelReaderService {
constructor() { }
importFromExcel(ev): Observable<any> {
let workbook;
let excelInJSON;
const fileReader = new FileReader();
// init read
fileReader.readAsArrayBuffer((<any>ev.target).files[0]);
return Observable.create((observer: Subscriber<any[]>): void => {
// if success
fileReader.onload = ((ev: ProgressEvent): void => {
let binary = "";
let bytes = new Uint8Array((<any>ev.target).result);
let length = bytes.byteLength;
for (let i = 0; i < length; i++) {
binary += String.fromCharCode(bytes[i]);
}
// Converts the excel data in to json
workbook = XLSX.read(binary, { type: 'binary', cellDates: true, cellStyles: true });
// only first sheet
excelInJSON = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]);
observer.next(excelInJSON);
observer.complete();
}
// if failed
fileReader.onerror = (error: FileReaderProgressEvent): void => {
observer.error(error);
}
});
}
}
从component
,只需将事件传递给此服务,如下所示,它将使用JSON进行响应.
From the component
, just pass the event to this service as shown below and it will respond with the JSON.
this.excelReaderService.importFromExcel(ev)
.subscribe((response: any[]): void => {
// do something with the response
});
这篇关于角度:从FileReader返回Observable/ES6承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!