Office js 替换文本后文档不同步
我试图替换Word Online文档中的某些文本,但无法使其正常工作 “{test},[[test]],{test}”结果是'13,2,3',而不是'1,2,3' 第一个文本似乎要处理两次 非常感谢任何帮助Office js 替换文本后文档不同步,office-js,Office Js,我试图替换Word Online文档中的某些文本,但无法使其正常工作 “{test},[[test]],{test}”结果是'13,2,3',而不是'1,2,3' 第一个文本似乎要处理两次 非常感谢任何帮助 Office.initialize = function(reason) { function ready() { var myTags = [ { "value": "1", "text": "{{test}}" },
Office.initialize = function(reason) {
function ready() {
var myTags = [
{ "value": "1", "text": "{{test}}" },
{ "value": "2", "text": "[[test]]" },
{ "value": "3", "text": "{test}" }
];
async function FillTag(tag) {
await Word.run(async function(context) {
var options = Word.SearchOptions.newObject(context);
options.matchWildCards = false;
var searchResults = context.document.body.search(tag.text, options);
context.load(searchResults, 'text');
await context.sync();
searchResults.items.forEach(function(item) {
item.insertText(tag.value, Word.InsertLocation.replace);
});
await context.sync();
})
.catch(function(error) {
console.log('Error: ' + JSON.stringify(error));
if (error instanceof OfficeExtension.Error) {
console.log('Debug info: ' + JSON.stringify(error.debugInfo));
}
});
}
async function ProcessArray(myTags) {
myTags.forEach(async function(tag) {
await FillTag(tag);
});
}
ProcessArray(myTags);
}
if (document.readyState !== 'loading') {
ready();
}
else {
document.addEventListener('DOMContentLoaded', ready);
}
};
这与其说是一个答案,不如说是一个调试建议,但可以在以后编辑。请将该文件安装到Word中。您将在其中找到的一个示例片段称为搜索。代码段中的函数之一是basicSearch。我将搜索文本“Online”替换为“{test}”,并将突出显示黄色搜索文本的行替换为以下行:
results.items[i].insertText("1", Word.InsertLocation.replace);
这很好,因此在足够简单的场景中,它可以准确地找到并替换“{test}”
请你自己尝试一下,然后逐渐改变方法,使之更接近你的方法,看看它在什么时候开始破裂
编辑2018年1月15日: @Kim Brandl的答案可能是最适合你的,假设你真的只有3个搜索字符串。但是,它在循环中有一个
context.sync
。由于每次同步都是到Office主机的一次往返,因此当输入数量较大和/或加载项在Office Online中运行时(这意味着Office主机在同一台计算机的internet上运行),这可能是一个性能问题
对于任何阅读本文的人来说,如果有大量的输入字符串,这里有一个解决方案可以保证整个Word.run中不需要超过3次同步。它还直接攻击您试图解决的问题的根源,即某些已找到范围相对于其他范围的相对位置(特别是,某些范围位于其他范围内)
我在中也使用了这种策略,即首先加载所有范围,然后使用方法和枚举查找所需的相对位置信息。最后,使用每个范围相对于其他范围的相对位置来确定是否/如何处理它
这里是函数。按照Kim的示例,我将整个代码段放在这里,您可以将其导入。(参见Kim Brandl回答中的说明。)
异步函数FindAndReplace(){
让myTags=[
{“值”:“1”,“文本”:“{test}}”,
{“值”:“2”,“文本”:“[[test]]”,
{“值”:“3”,“文本”:“{test}”},
{“value”:“4”,“text”:“bob”},
{“值”:“5”,“文本”:“bobb”},
{“value”:“6”,“text”:“ssally”},
{“value”:“7”,“text”:“sally”}
];
让allSearchResults=[];
等待Word.run(异步(上下文)=>{
对于(myTags的let标记){
让options=Word.SearchOptions.newObject(上下文);
options.matchWildCards=false;
让searchResults=context.document.body.search(tag.text,options);
searchResults.load('text');
//存储找到的每组范围和应替换的文本
//它们在一起,所以我们不必重建相关性
//在context.sync之后。
让correlatedSearchResult={
搜索点击:搜索结果,
replacementString:tag.value
}
allSearchResults.push(correlatedSearchResult);
}
wait context.sync();
//现在,我们已经加载了找到的范围,并将每个范围关联起来
//它的替换字符串,然后查找每个范围的位置关系
//例如,“bob”将位于“xbobx”内。
设correlatedFoundRanges=[];
allSearchResults.forEach(函数(correlatedSearchResult){
correlatedSearchResult.searchHits.items.forEach(函数(foundRange)){
设correlatedFoundRange={
范围:foundRange,
replacementText:correlatedSearchResult.replacementString,
地点关系:[]
}
correlatedFoundRanges.push(correlatedFoundRange);
});
});
//在找到的范围内进行二维循环,以找到每个范围的
//与其他范围的位置关系。
for(设i=0;iasync function FindAndReplace() {
let myTags = [
{ "value": "1", "text": "{{test}}" },
{ "value": "2", "text": "[[test]]" },
{ "value": "3", "text": "{test}" },
{ "value": "4", "text": "bob" },
{ "value": "5", "text": "bobb" },
{ "value": "6", "text": "ssally" },
{ "value": "7", "text": "sally" }
];
let allSearchResults = [];
await Word.run(async (context) => {
for (let tag of myTags) {
let options = Word.SearchOptions.newObject(context);
options.matchWildCards = false;
let searchResults = context.document.body.search(tag.text, options);
searchResults.load('text');
// Store each set of found ranges and the text that should replace
// them together, so we don't have to reconstruct the correlation
// after the context.sync.
let correlatedSearchResult = {
searchHits: searchResults,
replacementString: tag.value
}
allSearchResults.push(correlatedSearchResult);
}
await context.sync();
// Now that we've loaded the found ranges we correlate each to
// its replacement string, and then find each range's location relation
// to every other. For example, 'bob' would be Inside 'xbobx'.
let correlatedFoundRanges = [];
allSearchResults.forEach(function (correlatedSearchResult) {
correlatedSearchResult.searchHits.items.forEach(function (foundRange) {
let correlatedFoundRange = {
range: foundRange,
replacementText: correlatedSearchResult.replacementString,
locationRelations: []
}
correlatedFoundRanges.push(correlatedFoundRange);
});
});
// Two-dimensional loop over the found ranges to find each one's
// location relation with every other range.
for (let i = 0; i < correlatedFoundRanges.length; i++) {
for (let j = 0; j < correlatedFoundRanges.length; j++) {
if (i !== j) // Don't need the range's location relation with itself.
{
let locationRelation = correlatedFoundRanges[i].range.compareLocationWith(correlatedFoundRanges[j].range);
correlatedFoundRanges[i].locationRelations.push(locationRelation);
}
}
}
// It is not necesary to *explicitly* call load() for the
// LocationRelation objects, but a sync is required to load them.
await context.sync();
let nonReplaceableRanges = [];
correlatedFoundRanges.forEach(function (correlatedFoundRange) {
correlatedFoundRange.locationRelations.forEach(function (locationRelation) {
switch (locationRelation.value) {
case "Inside":
case "InsideStart":
case "InsideEnd":
// If the range is contained inside another range,
// blacklist it.
nonReplaceableRanges.push(correlatedFoundRange);
break;
default:
// Leave it off the blacklist, so it will get its
// replacement string.
break;
}
});
});
// Do the replacement, but skip the blacklisted ranges.
correlatedFoundRanges.forEach(function (correlatedFoundRange) {
if (nonReplaceableRanges.indexOf(correlatedFoundRange) === -1) {
correlatedFoundRange.range.insertText(correlatedFoundRange.replacementText, Word.InsertLocation.replace);
}
})
await context.sync();
});
}
async function ProcessArray(myTags) {
for (var tag of myTags) {
await FillTag(tag);
}
}
Office.initialize = function () {
$(document).ready(function () {
FindAndReplace();
});
};
async function FindAndReplace() {
var myTags = [
{ "value": "1", "text": "{{test}}" },
{ "value": "2", "text": "[[test]]" },
{ "value": "3", "text": "{test}" }
];
await Word.run(async (context) => {
for (var tag of myTags) {
var options = Word.SearchOptions.newObject(context);
options.matchWildCards = false;
var searchResults = context.document.body.search(tag.text, options);
context.load(searchResults, 'text');
await context.sync();
searchResults.items.forEach(function (item) {
item.insertText(tag.value, Word.InsertLocation.replace);
});
await context.sync();
}
}).catch(errorHandler);
}