Office Word JS - 来自 Table 个选择的内容控制
Office Word JS - Content Control from Table Selection
我正在使用 Office JS API 开发 Word 加载项,试图在文档中的 Table 绑定周围添加内容控件。
我遇到的问题是在选择 table 周围的绑定后,使用 goToByIdAsync()
,仅在 table 的最后一行周围创建内容控件,而不是选择。返回 ctx.document.getSelection()
的值我可以看到所选范围只是所选 Table 中的最后一行。我需要使用 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);
});
});
}
这是一个很好的问题!谢谢你的提问。我会建议你改变一下如何实现你想要的场景的方法。首先,goToById 不应用于获取任何 object 的范围,这仅用于导航目的。如果你可以插入一个 table,用命名的内容控件包装它(为其分配一个标题),创建一个绑定(使用 addFromNamedItem 而不是使用 addFromSelection 因为你没有固体selection :) ) ,然后只需订阅 bindingSelectionChanged 事件,然后对 table 或选定的单元格执行任何需要执行的操作。
以下代码说明了这一点。希望它能让你朝着正确的方向前进。我为上面描述的每个步骤添加了一堆评论。
谢谢,编码愉快!
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);
})
}
我正在使用 Office JS API 开发 Word 加载项,试图在文档中的 Table 绑定周围添加内容控件。
我遇到的问题是在选择 table 周围的绑定后,使用 goToByIdAsync()
,仅在 table 的最后一行周围创建内容控件,而不是选择。返回 ctx.document.getSelection()
的值我可以看到所选范围只是所选 Table 中的最后一行。我需要使用 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);
});
});
}
这是一个很好的问题!谢谢你的提问。我会建议你改变一下如何实现你想要的场景的方法。首先,goToById 不应用于获取任何 object 的范围,这仅用于导航目的。如果你可以插入一个 table,用命名的内容控件包装它(为其分配一个标题),创建一个绑定(使用 addFromNamedItem 而不是使用 addFromSelection 因为你没有固体selection :) ) ,然后只需订阅 bindingSelectionChanged 事件,然后对 table 或选定的单元格执行任何需要执行的操作。
以下代码说明了这一点。希望它能让你朝着正确的方向前进。我为上面描述的每个步骤添加了一堆评论。
谢谢,编码愉快!
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);
})
}