Office Word JS - управление содержимым из выделенной таблицы

Я работаю над надстройкой Word, используя Office JS API, пытаясь добавить элемент управления содержимым вокруг привязки таблицы в документе.

Проблема, с которой я столкнулся, заключается в том, что после выбора привязки вокруг таблицы с использованием goToByIdAsync() элемент управления содержимым создается только вокруг последней строки таблицы, а не для выделения. Возвращая значение ctx.document.getSelection(), я вижу, что выбранный диапазон - это только последняя строка в выбранной таблице. Мне нужно использовать объект Binding, чтобы узнать выбранные диапазоны ячеек таблицы. Что-то я делаю не так?

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

person hyperdrive    schedule 10.04.2017    source источник


Ответы (1)


Это большой вопрос! Спасибо за вопрос. Я предлагаю вам немного изменить подход к реализации желаемого сценария. Прежде всего, 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);
        })



 }

person Juan Balmori    schedule 10.04.2017
comment
Большое спасибо за ответ, Хуан! Имеет смысл, это работает. Но есть ли способ использовать другое свойство CC вместо заголовка (т. Е. Тега)? В моем приложении есть вероятность, что названия не будут уникальными. - person hyperdrive; 11.04.2017
comment
к сожалению нет. это должно быть название. И вы не можете создать bindingByName, если существует много копий с одним и тем же заголовком, поэтому убедитесь, что вы назначаете разные заголовки. - person Juan Balmori; 11.04.2017