Javascript Office.js加载项不使用动态列

Javascript Office.js加载项不使用动态列,javascript,excel,knockout.js,office-js,Javascript,Excel,Knockout.js,Office Js,我正在尝试使用Office.js将数据绑定到excel电子表格,但是列是一个日期范围的跨度,每个项目可能会有所不同。下面是我用来处理静态列的代码,它在这方面非常有用。但是,随着列范围的更改,我会遇到以下错误:提供的数据对象与当前选择的大小不匹配。包含动态列的属性是self.VisibleBudgetDownloadColumns()。我尝试过几种不同的方法,但是关于如何处理这个问题的例子有限。我本质上是在寻找一种更新列和数据的方法。提前谢谢 Excel.run(function (ctx) {

我正在尝试使用Office.js将数据绑定到excel电子表格,但是列是一个日期范围的跨度,每个项目可能会有所不同。下面是我用来处理静态列的代码,它在这方面非常有用。但是,随着列范围的更改,我会遇到以下错误:提供的数据对象与当前选择的大小不匹配。包含动态列的属性是self.VisibleBudgetDownloadColumns()。我尝试过几种不同的方法,但是关于如何处理这个问题的例子有限。我本质上是在寻找一种更新列和数据的方法。提前谢谢

Excel.run(function (ctx) {
        var activeWorksheet = ctx.workbook.worksheets.getActiveWorksheet();
        var currentRows = GetRows(self.BudgetDownload(), self.BudgetDownload().length, self.VisibleBudgetDownloadColumns(), self.VisibleBudgetDownloadColumns().length);

        return ctx.sync()
            .then(function () {
                Office.context.document.bindings.getByIdAsync(bindingID,
                    function (asyncResult) {
                        // if binding exists, delete and update rows
                        if (asyncResult.status == Office.AsyncResultStatus.Succeeded) {
                            asyncResult.value.deleteAllDataValuesAsync();
                            asyncResult.value.addRowsAsync(currentRows,
                                function (asyncResult) {
                                    if (asyncResult.status === Office.AsyncResultStatus.Failed) {
                                        self.showErrorMessageBar(asyncResult.error.message);
                                    }
                                }
                            );
                        }
                        else { // create new binding
                            var td = new Office.TableData();
                            td.rows = currentRows;
                            td.headers = ko.utils.arrayMap(self.VisibleBudgetDownloadColumns(),
                                function (item) {
                                    return item.DisplayName;
                                });

                            Office.context.document.setSelectedDataAsync(td,
                                function (result) {
                                    if (result.status === Office.AsyncResultStatus.Failed) {
                                        self.showErrorMessageBar(result.error.message);
                                    }
                                    else {
                                        Office.context.document.bindings.addFromSelectionAsync(Office.BindingType.Table, { id: bindingID },
                                            function (asyncResult) {
                                                if (asyncResult.status === Office.AsyncResultStatus.Failed) {
                                                    self.showErrorMessageBar(asyncResult.error.message);
                                                }
                                                else {
                                                    asyncResult.value.setDataAsync(td, { coercionType: Office.CoercionType.Table },
                                                        function (result) {
                                                            if (result.status === Office.AsyncResultStatus.Failed) {
                                                                self.showErrorMessageBar(result.error.message);
                                                            }
                                                        }
                                                    );
                                                }
                                            }
                                        );
                                    }
                                }
                            );
                        }
                    }
                );
            });
    }).catch(function (error) {
        overlay.hide();
        self.showErrorMessageBar(error);
    });
}

在您等待更好的答案时,有几件事:

  • 您的外部结构是一个
    Excel.run
    ,它来自特定于主机的Excel.js API,但它内部的大部分逻辑来自共享(也称为公共)API。当您需要使用这两组API时,对共享API的调用应该封装在一个承诺返回函数中。例如,请参阅此文件中的
    getDocumentFilePath
    函数:并在同一文件中向上滚动以查看如何调用它

  • 也就是说,您应该尽可能多地使用特定于主机的API。一位同事建议Range.getCell()和Range.getResizedRange()方法可能适合您的场景。特别是,如果将它们链接起来:
    getCell(0,0).getResizedRange(…)

  • 最后一行中的4
    ctx.sync
    调用让我感到困惑


  • 谢谢你,瑞克。我对上面的代码做了一些编辑,并将共享API包装在promise中。现在还从底部删除了额外的ctx.sync调用。