2017-06-21 28 views
1

在我的加载项中,我正在发出HTTP请求并接收输出。我希望将该输出放入绑定中,并在必要时扩展绑定,因为用户不一定知道输出将有多少行x列。我会如何去做这件事?目前我绑定到一个范围,但是如果该范围与我提供的[[]]的大小不匹配,那么数据不会显示在表单中。所以,这最终要求用户知道输出的大小。动态创建单元格范围输出

我做目前使用的角如下(本处在于输出并不总是大小相同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响应数据的大小进行新绑定?

+0

请问您可以粘贴一些代码(最好是[Script Lab](https://aka.ms/scriptlab)代码片段)到目前为止?随意“伪造”请求/响应部分,并使用JSON对象或数组。 –

+0

@ MichaelZlatkovsky-Microsoft我已经发布了代码,以上是我在Angular中做的事情。 – codex

回答

1

只要您使用“共享”(Office 2013)API,就会遇到此问题。

但是,在特定于主机(2016+)的API中,可以通过调整范围来适应您的需求,从而轻松解决问题。或者更准确地说,获取绑定,则要求其范围,然后让只是第一个(左上)单元格,然后调整其大小:

await Excel.run(async (context) => { 
     let values = [ 
      ["", "Price"], 
      ["Apple", 0.99], 
      ["Orange", 1.59], 
     ]; 

     let firstCell = context.workbook.bindings.getItem("TestBinding").getRange().getCell(0, 0); 
     let fullRange = firstCell.getResizedRange(
      values.length - 1, values[0].length - 1); 
     fullRange.values = values; 

     await context.sync(); 
    }); 

您可以尝试在字面上5次点击这个片段直播新的脚本实验室(https://aka.ms/getscriptlab)。只需安装Script Lab加载项(免费),然后在导航菜单中选择“导入”,然后使用以下GIST URL:https://gist.github.com/Zlatkovsky/5a2fc743bc9c8556d3eb3234e287d7f3。见more info about importing snippets to Script Lab

+0

谢谢,这正是我正在寻找的。我应该仍然可以从提示中进行绑定,然后使用新的apis抓取绑定并调整大小。 – codex