嗨,您好,我尝试使用以下打字稿来抓取一个Excel文件,然后将其转换为json以用作我正在使用的图表的数据源。它在onload函数中出错,因为我认为.response = null-readystate = 1(OPENED)和status = 0(Open或Unsent)。不太确定为什么它为空。.我读过readstate必须为= 4并且status = 200(完成将其打开),然后它才能起作用。但我不知道该怎么办?

import { Injectable } from '@angular/core';
import { read, IWorkBook, IWorkSheet, utils } from 'ts-xlsx';

@Injectable()
export class OperationDataService {
    oUrl: string;
    xhr: any;
    wb: IWorkBook;
    wbSheet: IWorkSheet;
    arraybuffer: any;
    data: any;
    arr: any;
    bstr: any;

    getData() {
        this.oUrl = './assets/operations.xlsx';
        this.xhr = new XMLHttpRequest();
        this.xhr.open('GET', this.oUrl, true);
        this.xhr.responseType = 'arraybuffer';

        console.log('Service Constructor ' + this.xhr.open + ' - ' + this.xhr.readyState + ' - ' + this.xhr.response + ' - ' + this.xhr.status);

        if (this.xhr.readyState === 4) {

            if (this.xhr.status === 200) {

                this.xhr.onload = function (e) {
                    console.log('in side function');

                    this.arraybuffer = this.xhr.response;

                    console.log('ArrayBuffer ' + this.arraybuffer);

                    /* convert data to binary string */
                    this.data = new Uint8Array(this.arraybuffer);
                    this.arr = new Array();

                    for (let item of this.data) {
                        this.arr[item] = String.fromCharCode(this.data[item]);
                    }

                    this.bstr = this.arr.join('');
                    console.log(this.xhr.responseText);

                    this.wb = read(this.bstr, { type: 'binary' });
                    this.wbSheet = this.wb.Sheets[0];

                    this.objAr = utils.sheet_to_json(this.wbSheet, { header: 1 });
                    console.log(utils.sheet_to_json(this.wbSheet, { header: 1 }));
                    console.log('get data set');

                    return this.objAr;
                };
            }
        }

        this.xhr.send();
    }

}




更新

谢谢下面的帮助,让我进入了将Excel转换为json的javescript库-似乎是ts-xlsx依赖项中的JSzip版本的问题,但XMLHtpRequest GET起作用了,我可以在浏览器中显示二进制数据。

import { Injectable } from '@angular/core';
import { read, IWorkBook, IWorkSheet, utils } from 'ts-xlsx';

@Injectable()
export class OperationDataService {
    oUrl: string;
    xhr: any;
    wb: IWorkBook;
    wbSheet: IWorkSheet;
    arraybuffer: any;
    data: any;
    arr: any;
    bstr: any;

    getData() {
        this.oUrl = './assets/operations.xlsx';
        this.xhr = new XMLHttpRequest();
        this.xhr.open('GET', this.oUrl, true);
        this.xhr.responseType = 'arraybuffer';

        this.xhr.addEventListener('load', function() {

                    this.arraybuffer = this.xhr.response;

                    // /* convert data to binary string */
                    this.data = new Uint8Array(this.arraybuffer);
                    this.arr = new Array();

                    for (let i = 0; i !== this.data.length; ++i) {
                    this.arr[i] = String.fromCharCode(this.data[i]);
                    }
                    this.bstr = this.arr.join('');

                    this.wb = read(this.bstr, { type: 'binary' });

                    this.wbSheet = this.wb.Sheets[0];
                    this.objAr = utils.sheet_to_json(this.wbSheet, { header: 1 });

                    return this.objAr;

            }.bind(this));

            this.xhr.send(null);
        }

    }

最佳答案

使用XMLHttpRequest can be simpler加载文件比:

this.oUrl = './assets/operations.xlsx';
this.xhr = new XMLHttpRequest();
this.xhr.addEventListener("load", function() {
    var arraybuffer = this.response;
    ...
});
this.xhr.open('GET', this.oUrl, true);
this.xhr.responseType = 'arraybuffer';


您也可以按照自己的方式做,但是应该像这样:

this.xhr.onreadystatechange =() => {
    if (this.xhr.readyState === 4 && this.xhr.status === 200) {
        this.arraybuffer = this.xhr.response;

    }
}


如果使用的是onload事件,则无需检查readyState
无论如何,您从未真正添加过事件侦听器,因为仅当readyState === 4status === 200在真正发送请求之前就不会发生时,才添加它。

至于响应,看起来是因为xlsx文件已压缩。



编辑

如果您将事件监听器函数分配为匿名函数,则该函数主体中的this不是您的对象,而是XMLHttpRequest对象,因此它应该是:

this.xhr.addEventListener("load", function() {
    var arraybuffer = this.response;
    ...
});


除非您绑定它:

this.xhr.addEventListener("load", function() {
    var arraybuffer = this.xhr.response;
    ...
}.bind(this));


如果您使用箭头功能,那么this将是您的对象:

this.xhr.addEventListener("load",() => {
    var arraybuffer = this.xhr.response;
    ...
});

10-01 01:14
查看更多