【问题标题】:Office Word JS - Content Control from Table SelectionOffice Word JS - 表格选择的内容控制
【发布时间】:2017-09-06 00:22:43
【问题描述】:

我正在使用 Office JS API 开发 Word 加载项,尝试在文档中的表格绑定周围添加内容控件。

我遇到的问题是在选择了表格周围的绑定后,使用goToByIdAsync(),仅围绕表格的最后一行创建了内容控件,而不是选择。返回ctx.document.getSelection() 的值我可以看到选定的范围只是选定表中的最后一行。我需要使用 Binding 对象来了解 Table 的选定单元格范围。是不是我做错了什么?

var bindingId  = '123';
var doc        = Office.context.document;

    // Create table in document.
    doc.setSelectedDataAsync(tableValue, { coercionType: Office.CoercionType.Table }, function (asyncResult) {

            // Add Binding to table
            doc.bindings.addFromSelectionAsync(Office.BindingType.Table, { id: bindingId }, function (asyncResult) {

                    // Select the table object                        
                    doc.goToByIdAsync(bindingId, Office.GoToType.Binding, { selectionMode: 'selected' }, function (asyncResult) {

                         // Create Content Control
                         createCC();
                    });

            });
    });


    function createCC(){
         Word.run(function (ctx) {
             var range = ctx.document.getSelection();
             var html  = range.getHtml();

                 return ctx.sync().then(function () {
                     console.log('Selected Range', html.value); // Only displays last row in the table.

                     var myContentControl = range.insertContentControl();
                         myContentControl.tag = bindingId;
                         myContentControl.title = 'My Content Control';

                         return ctx.sync().then(function () {
                                    //Content control for table created
                                });
                           }).catch(function (err) {
                               errorHandler(err);
                           });
                    });
    }

【问题讨论】:

    标签: javascript office365 office-js word-addins


    【解决方案1】:

    这是一个很好的问题!谢谢你的提问。我会建议你改变一点关于如何实现你想要的场景的方法。首先 goToById 不应该用于获取任何对象的范围,这仅用于导航目的。如果您可以插入一个表格,用命名的内容控件包装它(为其分配一个标题),创建一个绑定(使用 addFromNamedItem 而不是使用 addFromSelection,因为您没有可靠的选择:),这将更具确定性,然后只需订阅 bindingSelectionChanged 事件并对表格或选定的单元格执行任何您需要执行的操作。

    以下代码显示了这一点。希望它能让你朝着正确的方向前进。我为上面描述的每个步骤添加了一堆 cmets。

    感谢并祝您编码愉快!

    function insertTableCreateABindingAndSubscribeToEvents() {
        Word.run(function (context) { 
            //ok first we insert a table... 2 rows, 3 columns 
            var myTableData = [["Banana", "Mango", "Cherry"],["10","20","30"]];
            var myTable = context.document.body.insertTable(2, 3, "end", myTableData); //insert at the end of the body of the document.
            context.load(myTable);
            return context.sync()
                .then(function () { 
                //then we wrap the isnerted table with a content control
            var myCC = myTable.insertContentControl();
            myCC.title = "myTableTitle"; //important: assing a title so then i can use it to bind by namedItem!
            return context.sync()
            .then(function () { 
                    //Now we create the binding and subscribe to the events...
                    //since  we know the content control title, we can use addFromNamedItem!
        
                Office.context.document.bindings.addFromNamedItemAsync("myTableTitle", "table", {}, function (result) {
                 //boom now lets subscribe to the event...
                    if (result.status == "succeeded") {
                        //now lets subscribe to the selectionChanged event.\
                        result.value.addHandlerAsync(Office.EventType.BindingSelectionChanged, handler);
                    }
                    else { 
                        console.log("error");
                    }
    
                 } )
            })
    
                })
    
        })
            .catch(function (e) { 
                console.log(e.message);
            })
    
    
     }
    
    function handler(args) {
    //check out all the values you can get, see below how we use it to display the selected cell value...
      //  console.log("selection changed!" + args.startRow + " " + args.startColumn + " " + args.rowCount + " " + args.columnCount);
        var row;
        if (args.startRow == undefined) {
            //menas the selection is in the header!
            row = 0;
        }
        else {
             //selection not in the header...
            row = args.startRow + 1
        }
    
    // the other thing you can try here is to get the table, and print the selected cell value..
        Word.run(function (context) {
            //this instruction selected  cell of the  table within the content control named "myTableTite"
            var mySelectedCellBody = context.document.contentControls.getByTitle("myTableTitle").getFirst().tables.getFirst().getCell(row,args.startColumn).body;
            context.load(mySelectedCellBody);
            return context.sync()
                .then(function () {
                    //lets write the value of the cell (assumes single cell selected.)
                    console.log(mySelectedCellBody.text);
    
                 })
        })
            .catch(function (e) { 
                console.log("handler:" + e.message);
            })
    
    
    
     }

    【讨论】:

    • 非常感谢胡安的回复!有道理,这行得通。但是无论如何使用CC的不同属性而不是标题(即标签)?我的应用程序中的标题可能不是唯一的。
    • 很遗憾没有。它必须是标题。如果有很多 ccs 共享相同的标题,则无法创建 bindingByName,因此请确保分配不同的标题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 2015-01-08
    • 1970-01-01
    相关资源
    最近更新 更多