尝试读取excel文件时,XMLHTTPRequest.response为null

时间:2016-11-02 21:22:43

标签: javascript angular typescript xmlhttprequest

嗨新手很多我试图使用下面的打字稿来获取excel文件,然后将其转换为json用作我正在使用的图表的数据源。它在onload函数中出现问题,因为我认为.response = null - readystate = 1(OPENED)和status = 0(Open或Unsent)。不太确定wjy它是null ..我已经读过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();
    }

}

更新

谢谢以下让我使用javescript lib将excel转换为json - 在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);
        }

    }

1 个答案:

答案 0 :(得分:1)

使用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;
    ...
});