嗨,您好,我尝试使用以下打字稿来抓取一个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 === 4
和status === 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;
...
});