在我的插件中,我正在发出HTTP请求并接收输出。我想将该输出放入绑定中并在必要时扩展绑定,因为用户不一定知道输出将有多少行x列。我该怎么做呢?目前我绑定到一个范围,但如果该范围与我提供的[[]]的大小不匹配,则数据不会显示在工作表中。因此,这最终要求用户知道输出的大小。
我目前正在使用Angular进行的操作如下(问题是输出的大小与用户在电子表格中选择的Office.BindingType.Matrix的大小不同):
我创建了输出应该放置的位置,如下所示:
inputBindFromPrompt(parameterId: number): Promise<IOfficeResult> {
let bindType: Office.BindingType;
if(this.inputBindings[parameterId].type != 'data.frame' && this.inputBindings[parameterId].type != 'vector') {
bindType = Office.BindingType.Text;
} else {
bindType = Office.BindingType.Matrix;
}
return new Promise((resolve, reject) => {
this.workbook.bindings.addFromPromptAsync(bindType, { id: this.inputBindings[parameterId].name },
(addBindingResult: Office.AsyncResult) => {
if(addBindingResult.status === Office.AsyncResultStatus.Failed) {
reject({
error: 'Unable to bind to workbook. Error: ' + addBindingResult.error.message
});
} else {
this.inputBindings[parameterId].binding = addBindingResult.value;
resolve({
success: 'Created binding ' + addBindingResult.value.type + ' on ' + addBindingResult.value.id
});
}
})
})
}
然后当用户通过按钮提交时,输入被传递给HTTP请求服务,然后接收我处理成数组的输出,以便它可以进入Office.BindingType.Matrix:
this.isBusy = true;
this.feedback = 'submitted';
// Grab the values from the form
// Send as a POST and receive an output
// Put the output in the Excel sheet
this.webServicesService.postWebServices(this.service, this.inputParameters)
.subscribe(
(data: any) => {
// Correctly received data
// Access the data by name while looping through output parameters
this.error = false;
this.feedback = 'received data';
let i = 0;
this.outputParameters.forEach(element => {
// temporary name to identify the parameter
let name = element.name;
// Set the data value in the parameter
if(element.type == 'data.frame') {
let parameter = data[name];
this.feedback = parameter;
let excelData = [];
for(var key in parameter) {
if(parameter.hasOwnProperty(key)) {
var val = parameter[key];
excelData.push(val);
}
}
element.value = excelData;
}
else {
element.value = data[name];
}
// Set value in the form
let param = (<FormArray>this.serviceForm.controls['outputParameters']).at(i);
param.patchValue({
value: element.value
});
// Set value in the spreadsheet
this.excelService.outputSetText(i, element.value)
.then((result: IOfficeResult) => {
this.onResult(result);
i++;
});
}, (result: IOfficeResult) => {
this.onResult(result);
});
},
(error) => {
if(error.status == 400 || error.status == 401) {
// Return user to authentication page
this.authService.logout();
this.router.navigate(['/']);
} else {
// Tell user to try again
this.error = true;
}
}
);
上面的行是将值设置为Office.Matrix.Binding的是this.excelService.outputSetText(i,element.value),它在Excel服务中调用此方法:
outputSetText(parameterId: number, data: any): Promise<IOfficeResult> {
return new Promise((resolve, reject) => {
if(this.outputBindings[parameterId].binding) {
this.outputBindings[parameterId].binding.setDataAsync(data, function (result: Office.AsyncResult) {
if(result.status == Office.AsyncResultStatus.Failed) {
reject({ error: 'Failed to set value. Error: ' + result.error.message });
} else {
let test: Office.Binding;
resolve({
success: 'successfully set value'
});
}
})
} else {
reject({
error: 'binding has not been created. bindFromPrompt must be called'
});
}
})
}
它实质上是使用addFromPromptAsync()来设置HTTP请求的输出点。然后,用户提交发送请求的数据,接收数据并将其处理为数组[[]]数组,以便它可以是Office.BindingType.Matrix的正确数据格式。但是,除非此行数和列数与最初选择的绑定数相同,否则它将不会显示在工作表中。那么,是否有一种绑定类型会根据我提供的数据动态增长?或者我只需要释放当前绑定并根据HTTP响应数据的大小创建一个新绑定?