2017-04-10 83 views
2

我正在使用Office JS API嘗試在文檔中的表格綁定周圍添加內容控件。Office Word JS - 從表格選擇內容控件

我遇到的問題是在選擇表格的綁定後,使用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); 
          }); 
        }); 
    } 

回答

2

這是一個很好的問題!謝謝你的提問。我會建議你稍微改變一下如何實現你想要的場景。首先goToById不應該被用來獲取任何對象的範圍,這只是爲了導航的目的。如果你可以插入一個表格,用一個命名的內容控件(爲它指定一個標題),創建一個綁定(使用addFromNamedItem而不使用addFromSelection,因爲你沒有一個可靠的選擇:)) ,然後只需訂閱bindingSelectionChanged事件並執行您需要對錶或選定單元格執行的任何操作。

下面的代碼顯示了這一點。希望它能讓你朝着正確的方向前進。我在上面描述的每個步驟中添加了一堆評論。

感謝和快樂編碼!

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); 
 
     }) 
 

 

 

 
}

+0

非常感謝您的答覆胡安!有道理,這是有效的。但是,無論如何要使用CC的不同屬性而不是標題(即標籤)?在我的應用程序中有可能標題不會是唯一的。 – user35202

+0

不幸的不是。它必須是標題。如果許多ccs共享相同的標題,則無法創建bindingByName,因此請確保分配不同的標題。 –