Angular:从 FileReader 返回 Observable/ES6 Promise [英] Angular: Return Observable / ES6 Promise from FileReader

查看:19
本文介绍了Angular:从 FileReader 返回 Observable/ES6 Promise的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从 FileReader 返回结果,我发现 this 实施.但是因为它已经过时了,我想知道如何使用 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-9s_\.-:])+(.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();
  }

}

在消费者组件

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
  });

这篇关于Angular:从 FileReader 返回 Observable/ES6 Promise的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆