Office-JS API 使用 Fetch 从服务器获取数据,替换 Word 中的字段 - ItemNotFound 错误
Office-JS API with Fetch to get data from server, replace fields in Word - ItemNotFound error
我是 Office-JS 的新手 API,但我正在尝试开发一个 POC 来演示通过单击按钮将 Word 文档中的所有字段替换为从中检索到的相应数据的能力一个 API.
所以我开发了一个 API 作为 Azure 函数,我可以调用它,传递一个值,它将 return 字段名称和值作为 JSON 用于匹配传递值的记录。我已经使用 Postman 对此进行了测试。
现在我正在尝试让 Office-JS 工作。我从 VS-2022 模板开始,我已将其转换为 TypeScript。
我打算采用的方法是,当用户单击按钮时,应用程序将调用 API 并获取记录(数据)字段作为一组 name/value 对。
然后,我想遍历所有的(数据)字段 returned,并且对于每个(数据)字段名称,检查文档中是否有一个(文档)字段姓名;如果是这样,请将(文档)字段替换为(数据)字段的值。
此代码已成功找到搜索条件,并将替换排队,为 context.sync 调用做准备...但是在 context.sync 调用期间,报告错误“ItemNotFound ."
我正在遵循此处 https://docs.microsoft.com/en-us/office/dev/add-ins/concepts/correlated-objects-pattern“使用相关对象模式处理文档中的对象”部分中记录的推荐方法。
我的代码如下:
(function () {
"use strict";
var messageBanner;
// The initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
(window as any).Promise = OfficeExtension.Promise;
$(document).ready(function () {
// Initialize the notification mechanism and hide it
var element = document.querySelector('.MessageBanner');
messageBanner = new components.MessageBanner(element);
messageBanner.hideBanner();
OfficeExtension.config.extendedErrorLogging = true;
// If not using Word 2016, use fallback logic.
if (!Office.context.requirements.isSetSupported('WordApi', '1.1')) {
$("#template-description").text("This sample displays the selected text.");
$('#button-text').text("Display!");
$('#button-desc').text("Display the selected text");
$('#highlight-button').click(loadCaseData("08-CA-123456"));
//$('#highlight-button').click(simpleTest());
//$('#highlight-button').click(dataCompareTest("08-CA-123456"));
return;
}
$("#template-description").text("This POC demonstrates template capabilities for NLRB within WORD.");
$('#button-text').text("Merge Template!");
$('#button-desc').text("Replaces fields with appropriate data.");
// Add a click event handler for the highlight button.
$('#highlight-button').click(loadCaseData("08-CA-123456"));
//$('#highlight-button').click(simpleTest());
//$('#highlight-button').click(dataCompareTest("08-CA-123456"));
});
};
//CaseNum=08-CA-123456&DataType=1
async function loadCaseData(caseNum) {
Word.run(async (context) => {
const
url = `[My API URL]`;
fetch(url)
.then(resp => resp.json())
.then(resp => {
console.log('Server Response : ' + JSON.stringify(resp));
let fieldList = Object.entries(resp).map(([k, v]) => {
let fieldNameString = '«' + k + '»';
return { fieldName: fieldNameString, fieldValue: v };
});
console.log("Dataset in first part: " + JSON.stringify(fieldList));
return fieldList;
})
.then(async fieldList => await searchDocForFields(fieldList, context))
.catch(errorHandler);
return context.sync();
});
}
async function simpleTest() {
Word.run(async (context) => {
let fieldList = [
{ fieldName: "«StartLogSeqNo»", fieldValue: "AAA5fgABbpgACw==" },
{ fieldName: "«EndLogSeqNo»", fieldValue: null },
{ fieldName: "«SeqVal»", fieldValue: "AAA5fgABbpgAAw==" },
{ fieldName: "«DmlOperation»", fieldValue: 4 },
{ fieldName: "«DmlUpdateFields»", fieldValue: "AAAAAAAAAUAgADg=" },
{ fieldName: "«CaseAssgnedDt»", fieldValue: "2011-07-22T17:12:19" },
{ fieldName: "«AsgnUsrExcldFlg»", fieldValue: "N" },
{ fieldName: "«BuId»", fieldValue: "0-R9NH" },
{ fieldName: "«CaseFiledDt»", fieldValue: "2006-03-09T00:00:00" },
{ fieldName: "«InquiryId»", fieldValue: "08-CA-123456" },
{ fieldName: "«ChgofccmReqFlg»", fieldValue: "N" },
{ fieldName: "«DisputeUnitCity»", fieldValue: "Cleveland" },
{ fieldName: "«CaseClasification»", fieldValue: "Unclassified" },
{ fieldName: "«CaseClosedDt»", fieldValue: null },
{ fieldName: "«Created»", fieldValue: "2010-10-07T15:32:29" },
{ fieldName: "«CreatedBy»", fieldValue: "0-1" },
{ fieldName: "«CrimeSubTypeCd»", fieldValue: null },
{ fieldName: "«TypeCd»", fieldValue: null },
{ fieldName: "«DbLastUpd»", fieldValue: "2019-10-20T17:17:14.31" },
{ fieldName: "«DbLastUpdSrc»", fieldValue: "ScriptingService_PreInvokeMethod" },
{ fieldName: "«CaseDescription»", fieldValue: null },
{ fieldName: "«LastUpd»", fieldValue: "2019-10-20T17:17:14" },
{ fieldName: "«LastUpdBy»", fieldValue: "1-CGA" },
{ fieldName: "«LocalSeqNum»", fieldValue: 1 },
{ fieldName: "«ModificationNum»", fieldValue: 11 },
{ fieldName: "«CaseName»", fieldValue: "This is the case name from the data" },
{ fieldName: "«ParCaseId»", fieldValue: null },
{ fieldName: "«PrAgencyId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrAgentId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrPostnId»", fieldValue: "1-5D2V9F " },
{ fieldName: "«PrPrtnrId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrRepDnrmFlg»", fieldValue: "Y" },
{ fieldName: "«PrRepManlFlg»", fieldValue: "Y" },
{ fieldName: "«PrRepSysFlg»", fieldValue: "Y" },
{ fieldName: "«PrSgroupId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrSubjectId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrSuspctId»", fieldValue: "No Match Row Id" },
{ fieldName: "«IaCategory»", fieldValue: "2" },
{ fieldName: "«RewardExchangeDt»", fieldValue: "2010-10-07T11:09:02" },
{ fieldName: "«RowId»", fieldValue: "1-2DCA-1327" },
{ fieldName: "«CaseNumber»", fieldValue: "08-CA-123456" },
{ fieldName: "«CaseSource»", fieldValue: "Visit" },
{ fieldName: "«DisputeUnitState»", fieldValue: "OH" },
{ fieldName: "«CaseStatus»", fieldValue: "Open" },
{ fieldName: "«CaseSubType»", fieldValue: "CA" },
{ fieldName: "«CaseSubTypeCd»", fieldValue: null },
{ fieldName: "«TerritoryTypeCd»", fieldValue: "08" },
{ fieldName: "«ThreatLvlCd»", fieldValue: "Batch" },
{ fieldName: "«CaseType»", fieldValue: "C" },
{ fieldName: "«BlockedFlag»", fieldValue: null },
{ fieldName: "«CaseLongName»", fieldValue: "This is the case name from the data" },
{ fieldName: "«XCaseNumCi»", fieldValue: null },
{ fieldName: "«DojCaseType»", fieldValue: null },
{ fieldName: "«ElectionTargetDt»", fieldValue: null },
{ fieldName: "«HearingTargetDt»", fieldValue: null },
{ fieldName: "«MethodType»", fieldValue: null },
{ fieldName: "«XNameCi»", fieldValue: null },
{ fieldName: "«Num8a3Discriminatees»", fieldValue: null },
{ fieldName: "«Num8b2Discriminatees»", fieldValue: null },
{ fieldName: "«NumOfEmployees»", fieldValue: 146 },
{ fieldName: "«PostElectionSelfCertification»", fieldValue: null },
{ fieldName: "«Potential10j»", fieldValue: "N" },
{ fieldName: "«XPrPostnBrdId»", fieldValue: "1-4P8HN1" },
{ fieldName: "«XPrPostnSpvId»", fieldValue: "1-1RAQT2" },
{ fieldName: "«ElectionSelfCertification»", fieldValue: null },
{ fieldName: "«XTypeCdCi»", fieldValue: null },
{ fieldName: "«Moved2dh»", fieldValue: 1 },
{ fieldName: "«IdentityVal»", fieldValue: 5792070 },
{ fieldName: "«CdcRecordedFields»", fieldValue: null },
{ fieldName: "«NxgenTestCase»", fieldValue: "N" },
{ fieldName: "«InquiryChargePetition»", fieldValue: null },
{ fieldName: "«ChangeCaptureDatetime»", fieldValue: "2019-10-20T13:17:15.83" },
{ fieldName: "«RegionRecommendsPursuing10j»", fieldValue: "N" },
{ fieldName: "«SurrogateKey»", fieldValue: 1731295 }
]
await searchDocForFields(fieldList, context);
})
}
async function searchDocForFields(fieldList, context) {
console.log("Dataset: " + JSON.stringify(fieldList));
const allSearchResults = [];
console.log('fieldList.Length = ' + fieldList.length);
// console.log("Dataset in second part: " + JSON.stringify(fieldList));
for (let fieldCount = 0; fieldCount < fieldList.length; fieldCount++) {
let options = Word.SearchOptions.newObject(context);
options.matchWildCards = false;
options.matchCase = true;
options.matchWholeWord = true;
// Check the document to see if this field from the database is found
// console.log("Checking for " + fieldList[fieldCount].fieldName + " to be replaced with " + fieldList[fieldCount].fieldValue);
let searchResults = context.document.body.search(fieldList[fieldCount].fieldName, options);
//Load all of the items that meet the search criteria
searchResults.load('items');
let correlatedSearchResult = {
rangesMatchingFieldName: searchResults,
fieldValue: fieldList[fieldCount].fieldValue
}
allSearchResults.push(correlatedSearchResult);
}
await context.sync();
// Now we have all of the search results in the correlatedSearchResult array.
for (let searchResultCount = 0; searchResultCount < allSearchResults.length; searchResultCount++) {
let correlatedObject = allSearchResults[searchResultCount];
console.log("Checking for search result " + searchResultCount + " of " + allSearchResults.length);
for (let rangeCount = 0; rangeCount < correlatedObject.rangesMatchingFieldName.items.length; rangeCount++) {
let targetRange = correlatedObject.rangesMatchingFieldName.items[rangeCount];
let replacementValue = correlatedObject.fieldValue;
targetRange.insertText(replacementValue, Word.InsertLocation.replace);
console.log("Replacing found instance " + rangeCount + " of " + correlatedObject.rangesMatchingFieldName.items.length + " (" + JSON.stringify(targetRange) + ") with (" + replacementValue + ")");
}
}
return await context.sync();
}
function dataCompareTest(caseNum) {
Word.run((context) => {
const
url = `[My API URL]`;
const codedFieldList = [
{ fieldName: "«StartLogSeqNo»", fieldValue: "AAA5fgABbpgACw==" },
{ fieldName: "«EndLogSeqNo»", fieldValue: null },
{ fieldName: "«SeqVal»", fieldValue: "AAA5fgABbpgAAw==" },
{ fieldName: "«DmlOperation»", fieldValue: 4 },
{ fieldName: "«DmlUpdateFields»", fieldValue: "AAAAAAAAAUAgADg=" },
{ fieldName: "«CaseAssgnedDt»", fieldValue: "2011-07-22T17:12:19" },
{ fieldName: "«AsgnUsrExcldFlg»", fieldValue: "N" },
{ fieldName: "«BuId»", fieldValue: "0-R9NH" },
{ fieldName: "«CaseFiledDt»", fieldValue: "2006-03-09T00:00:00" },
{ fieldName: "«InquiryId»", fieldValue: "08-CA-123456" },
{ fieldName: "«ChgofccmReqFlg»", fieldValue: "N" },
{ fieldName: "«DisputeUnitCity»", fieldValue: "Cleveland" },
{ fieldName: "«CaseClasification»", fieldValue: "Unclassified" },
{ fieldName: "«CaseClosedDt»", fieldValue: null },
{ fieldName: "«Created»", fieldValue: "2010-10-07T15:32:29" },
{ fieldName: "«CreatedBy»", fieldValue: "0-1" },
{ fieldName: "«CrimeSubTypeCd»", fieldValue: null },
{ fieldName: "«TypeCd»", fieldValue: null },
{ fieldName: "«DbLastUpd»", fieldValue: "2019-10-20T17:17:14.31" },
{ fieldName: "«DbLastUpdSrc»", fieldValue: "ScriptingService_PreInvokeMethod" },
{ fieldName: "«CaseDescription»", fieldValue: null },
{ fieldName: "«LastUpd»", fieldValue: "2019-10-20T17:17:14" },
{ fieldName: "«LastUpdBy»", fieldValue: "1-CGA" },
{ fieldName: "«LocalSeqNum»", fieldValue: 1 },
{ fieldName: "«ModificationNum»", fieldValue: 11 },
{ fieldName: "«CaseName»", fieldValue: "This is the case name from the data" },
{ fieldName: "«ParCaseId»", fieldValue: null },
{ fieldName: "«PrAgencyId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrAgentId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrPostnId»", fieldValue: "1-5D2V9F " },
{ fieldName: "«PrPrtnrId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrRepDnrmFlg»", fieldValue: "Y" },
{ fieldName: "«PrRepManlFlg»", fieldValue: "Y" },
{ fieldName: "«PrRepSysFlg»", fieldValue: "Y" },
{ fieldName: "«PrSgroupId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrSubjectId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrSuspctId»", fieldValue: "No Match Row Id" },
{ fieldName: "«IaCategory»", fieldValue: "2" },
{ fieldName: "«RewardExchangeDt»", fieldValue: "2010-10-07T11:09:02" },
{ fieldName: "«RowId»", fieldValue: "1-2DCA-1327" },
{ fieldName: "«CaseNumber»", fieldValue: "08-CA-123456" },
{ fieldName: "«CaseSource»", fieldValue: "Visit" },
{ fieldName: "«DisputeUnitState»", fieldValue: "OH" },
{ fieldName: "«CaseStatus»", fieldValue: "Open" },
{ fieldName: "«CaseSubType»", fieldValue: "CA" },
{ fieldName: "«CaseSubTypeCd»", fieldValue: null },
{ fieldName: "«TerritoryTypeCd»", fieldValue: "08" },
{ fieldName: "«ThreatLvlCd»", fieldValue: "Batch" },
{ fieldName: "«CaseType»", fieldValue: "C" },
{ fieldName: "«BlockedFlag»", fieldValue: null },
{ fieldName: "«CaseLongName»", fieldValue: "This is the case name from the data" },
{ fieldName: "«XCaseNumCi»", fieldValue: null },
{ fieldName: "«DojCaseType»", fieldValue: null },
{ fieldName: "«ElectionTargetDt»", fieldValue: null },
{ fieldName: "«HearingTargetDt»", fieldValue: null },
{ fieldName: "«MethodType»", fieldValue: null },
{ fieldName: "«XNameCi»", fieldValue: null },
{ fieldName: "«Num8a3Discriminatees»", fieldValue: null },
{ fieldName: "«Num8b2Discriminatees»", fieldValue: null },
{ fieldName: "«NumOfEmployees»", fieldValue: 146 },
{ fieldName: "«PostElectionSelfCertification»", fieldValue: null },
{ fieldName: "«Potential10j»", fieldValue: "N" },
{ fieldName: "«XPrPostnBrdId»", fieldValue: "1-4P8HN1" },
{ fieldName: "«XPrPostnSpvId»", fieldValue: "1-1RAQT2" },
{ fieldName: "«ElectionSelfCertification»", fieldValue: null },
{ fieldName: "«XTypeCdCi»", fieldValue: null },
{ fieldName: "«Moved2dh»", fieldValue: 1 },
{ fieldName: "«IdentityVal»", fieldValue: 5792070 },
{ fieldName: "«CdcRecordedFields»", fieldValue: null },
{ fieldName: "«NxgenTestCase»", fieldValue: "N" },
{ fieldName: "«InquiryChargePetition»", fieldValue: null },
{ fieldName: "«ChangeCaptureDatetime»", fieldValue: "2019-10-20T13:17:15.83" },
{ fieldName: "«RegionRecommendsPursuing10j»", fieldValue: "N" },
{ fieldName: "«SurrogateKey»", fieldValue: 1731295 }
]
fetch(url)
.then(resp => resp.json())
.then(resp => {
console.log('Server Response : ' + JSON.stringify(resp));
let fetchFieldList = Object.entries(resp).map(([k, v]) => {
let fieldNameString = '«' + k + '»';
return { fieldName: fieldNameString, fieldValue: v };
});
console.log("Dataset in first part: " + JSON.stringify(fetchFieldList));
return fetchFieldList;
})
.then(fieldList => {
console.log('Comparing datasets');
const jsonFieldList = JSON.stringify(fieldList);
const jsonCodedFieldList = JSON.stringify(codedFieldList);
const same = jsonFieldList === jsonCodedFieldList;
console.log("Are the arrays the same? " + same);
})
.catch(errorHandler);
return context.sync();
});
}
//$$(Helper function for treating errors, $loc_script_taskpane_home_js_comment34$)$$
function errorHandler(error) {
// $$(Always be sure to catch any accumulated errors that bubble up from the Word.run execution., $loc_script_taskpane_home_js_comment35$)$$
showNotification("Error:", error);
console.log("Error: " + error);
if (error instanceof OfficeExtension.Error) {
console.log("Debug info: " + JSON.stringify(error.debugInfo));
}
}
// Helper function for displaying notifications
function showNotification(header, content) {
$("#notification-header").text(header);
$("#notification-body").text(content);
messageBanner.showBanner();
messageBanner.toggleExpansion();
}
})();
样本 JSON return 来自我的数据 API:
{
"CaseAssgnedDt": "2011-07-22T17:12:19",
"AsgnUsrExcldFlg": "N",
"BuId": "0-R9NH",
"CaseFiledDt": "2006-03-09T00:00:00",
"InquiryId": "08-CA-123456",
"ChgofccmReqFlg": "N",
"DisputeUnitCity": "Cleveland",
"CaseClasification": "Unclassified",
"CaseClosedDt": null,
"Created": "2010-10-07T15:32:29",
"CreatedBy": "0-1",
"CrimeSubTypeCd": null,
"TypeCd": null,
"DbLastUpd": "2019-10-20T17:17:14.31",
"DbLastUpdSrc": "ScriptingService_PreInvokeMethod",
"CaseDescription": null,
"LastUpd": "2019-10-20T17:17:14",
"LastUpdBy": "1-CGA",
"LocalSeqNum": 1,
"ModificationNum": 11,
"CaseName": "This is the case name from the data",
"ParCaseId": null,
"PrAgencyId": "No Match Row Id",
"PrAgentId": "No Match Row Id",
"PrPostnId": "1-5D2V9F ",
"PrPrtnrId": "No Match Row Id",
"PrRepDnrmFlg": "Y",
"PrRepManlFlg": "Y",
"PrRepSysFlg": "Y",
"PrSgroupId": "No Match Row Id",
"PrSubjectId": "No Match Row Id",
"PrSuspctId": "No Match Row Id",
"IaCategory": "2",
"RewardExchangeDt": "2010-10-07T11:09:02",
"RowId": "1-2DCA-1327",
"CaseNumber": "08-CA-123456",
"CaseSource": "Visit",
"DisputeUnitState": "OH",
"CaseStatus": "Open",
"CaseSubType": "CA",
"CaseSubTypeCd": null,
"TerritoryTypeCd": "08",
"ThreatLvlCd": "Batch",
"CaseType": "C",
"BlockedFlag": null,
"CaseLongName": "This is the case name from the data",
"XCaseNumCi": null,
"DojCaseType": null,
"ElectionTargetDt": null,
"HearingTargetDt": null,
"MethodType": null,
"XNameCi": null,
"Num8a3Discriminatees": null,
"Num8b2Discriminatees": null,
"NumOfEmployees": 146,
"PostElectionSelfCertification": null,
"Potential10j": "N",
"XPrPostnBrdId": "1-4P8HN1",
"XPrPostnSpvId": "1-1RAQT2",
"ElectionSelfCertification": null,
"XTypeCdCi": null,
"Moved2dh": 1,
"IdentityVal": 5792070,
"CdcRecordedFields": null,
"NxgenTestCase": "N",
"InquiryChargePetition": null,
"ChangeCaptureDatetime": "2019-10-20T13:17:15.83",
"RegionRecommendsPursuing10j": "N",
"SurrogateKey": 1731295
}
非常感谢您提供的一切帮助,谢谢。
谢谢。
-- 更新:
根据 Rick Kirkham 的建议,我创建了一个新函数(“simpleTest”,现在包含在上面的代码中)来简化和验证该方法,并且惊讶地发现它有效(尽管我敢打赌 Rick 并不感到惊讶,哈哈).
我还添加了一个函数“dataCompare”,也在上面的代码中),它手动加载一个数据集,另一个使用 Fetch 调用,然后比较两者,它响应两个数组是一样。
鉴于数据是相同的,而且 loadCaseData 和 simpleTest 函数都使用相同的 searchDocForFields 函数来执行搜索和替换,所以我很茫然,为什么 simpleTest 函数会工作,以及loadCaseData 函数因 ItemNotFound 错误而失败?
谢谢。
马克.
最终,这一切都是由于缺少单个等待引起的...请注意下面带有 FETCH 语句的行,该语句之前没有 AWAIT。
async function loadCaseData(caseNum) {
Word.run(async (context) => {
const ul = document.getElementById('caseData'),
url = `[URL to my API]`;
const createNode = element => { return document.createElement(element); };
const append = (parent, el) => { return parent.appendChild(el); };
/*----->*/ await fetch(url)
.then(resp => resp.json())
.then(resp => {
console.log('Server Response : ' + JSON.stringify(resp));
let fieldList = Object.entries(resp).map(([k, v]) => {
let fieldNameString = '«' + k + '»';
return { fieldName: fieldNameString, fieldValue: v };
});
//console.log("Dataset in first part: " + JSON.stringify(fieldList));
return fieldList;
})
.then(async fieldList => await searchDocForFields(fieldList, context))
.catch(errorHandler);
return context.sync();
});
}
async function newLoadCaseData(caseNum) {
Word.run(async (context) => {
const
url = `[URL to my API]`;
let resp = await (await fetch(url)).json();
//let data = resp.json();
console.log('Server Response : ' + JSON.stringify(resp));
let fieldList = Object.entries(resp).map(([k, v]) => {
let fieldNameString = '«' + k + '»';
return { fieldName: fieldNameString, fieldValue: v };
});
console.log("Dataset in first part: " + JSON.stringify(fieldList));
await searchDocForFields(fieldList, context);
});
}
我通过尝试进一步简化我的代码发现了这一点,因此创建了同样显示的“newLoadCaseData”函数。这个版本写FETCH语句的时候,VS2022给我插了个await,让我大开眼界。
现在可以使用了,我希望我的研究和 mistakes/fixes 也能帮助到其他人。
尽情享受吧!
马克.
我是 Office-JS 的新手 API,但我正在尝试开发一个 POC 来演示通过单击按钮将 Word 文档中的所有字段替换为从中检索到的相应数据的能力一个 API.
所以我开发了一个 API 作为 Azure 函数,我可以调用它,传递一个值,它将 return 字段名称和值作为 JSON 用于匹配传递值的记录。我已经使用 Postman 对此进行了测试。
现在我正在尝试让 Office-JS 工作。我从 VS-2022 模板开始,我已将其转换为 TypeScript。
我打算采用的方法是,当用户单击按钮时,应用程序将调用 API 并获取记录(数据)字段作为一组 name/value 对。
然后,我想遍历所有的(数据)字段 returned,并且对于每个(数据)字段名称,检查文档中是否有一个(文档)字段姓名;如果是这样,请将(文档)字段替换为(数据)字段的值。
此代码已成功找到搜索条件,并将替换排队,为 context.sync 调用做准备...但是在 context.sync 调用期间,报告错误“ItemNotFound ."
我正在遵循此处 https://docs.microsoft.com/en-us/office/dev/add-ins/concepts/correlated-objects-pattern“使用相关对象模式处理文档中的对象”部分中记录的推荐方法。
我的代码如下:
(function () {
"use strict";
var messageBanner;
// The initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
(window as any).Promise = OfficeExtension.Promise;
$(document).ready(function () {
// Initialize the notification mechanism and hide it
var element = document.querySelector('.MessageBanner');
messageBanner = new components.MessageBanner(element);
messageBanner.hideBanner();
OfficeExtension.config.extendedErrorLogging = true;
// If not using Word 2016, use fallback logic.
if (!Office.context.requirements.isSetSupported('WordApi', '1.1')) {
$("#template-description").text("This sample displays the selected text.");
$('#button-text').text("Display!");
$('#button-desc').text("Display the selected text");
$('#highlight-button').click(loadCaseData("08-CA-123456"));
//$('#highlight-button').click(simpleTest());
//$('#highlight-button').click(dataCompareTest("08-CA-123456"));
return;
}
$("#template-description").text("This POC demonstrates template capabilities for NLRB within WORD.");
$('#button-text').text("Merge Template!");
$('#button-desc').text("Replaces fields with appropriate data.");
// Add a click event handler for the highlight button.
$('#highlight-button').click(loadCaseData("08-CA-123456"));
//$('#highlight-button').click(simpleTest());
//$('#highlight-button').click(dataCompareTest("08-CA-123456"));
});
};
//CaseNum=08-CA-123456&DataType=1
async function loadCaseData(caseNum) {
Word.run(async (context) => {
const
url = `[My API URL]`;
fetch(url)
.then(resp => resp.json())
.then(resp => {
console.log('Server Response : ' + JSON.stringify(resp));
let fieldList = Object.entries(resp).map(([k, v]) => {
let fieldNameString = '«' + k + '»';
return { fieldName: fieldNameString, fieldValue: v };
});
console.log("Dataset in first part: " + JSON.stringify(fieldList));
return fieldList;
})
.then(async fieldList => await searchDocForFields(fieldList, context))
.catch(errorHandler);
return context.sync();
});
}
async function simpleTest() {
Word.run(async (context) => {
let fieldList = [
{ fieldName: "«StartLogSeqNo»", fieldValue: "AAA5fgABbpgACw==" },
{ fieldName: "«EndLogSeqNo»", fieldValue: null },
{ fieldName: "«SeqVal»", fieldValue: "AAA5fgABbpgAAw==" },
{ fieldName: "«DmlOperation»", fieldValue: 4 },
{ fieldName: "«DmlUpdateFields»", fieldValue: "AAAAAAAAAUAgADg=" },
{ fieldName: "«CaseAssgnedDt»", fieldValue: "2011-07-22T17:12:19" },
{ fieldName: "«AsgnUsrExcldFlg»", fieldValue: "N" },
{ fieldName: "«BuId»", fieldValue: "0-R9NH" },
{ fieldName: "«CaseFiledDt»", fieldValue: "2006-03-09T00:00:00" },
{ fieldName: "«InquiryId»", fieldValue: "08-CA-123456" },
{ fieldName: "«ChgofccmReqFlg»", fieldValue: "N" },
{ fieldName: "«DisputeUnitCity»", fieldValue: "Cleveland" },
{ fieldName: "«CaseClasification»", fieldValue: "Unclassified" },
{ fieldName: "«CaseClosedDt»", fieldValue: null },
{ fieldName: "«Created»", fieldValue: "2010-10-07T15:32:29" },
{ fieldName: "«CreatedBy»", fieldValue: "0-1" },
{ fieldName: "«CrimeSubTypeCd»", fieldValue: null },
{ fieldName: "«TypeCd»", fieldValue: null },
{ fieldName: "«DbLastUpd»", fieldValue: "2019-10-20T17:17:14.31" },
{ fieldName: "«DbLastUpdSrc»", fieldValue: "ScriptingService_PreInvokeMethod" },
{ fieldName: "«CaseDescription»", fieldValue: null },
{ fieldName: "«LastUpd»", fieldValue: "2019-10-20T17:17:14" },
{ fieldName: "«LastUpdBy»", fieldValue: "1-CGA" },
{ fieldName: "«LocalSeqNum»", fieldValue: 1 },
{ fieldName: "«ModificationNum»", fieldValue: 11 },
{ fieldName: "«CaseName»", fieldValue: "This is the case name from the data" },
{ fieldName: "«ParCaseId»", fieldValue: null },
{ fieldName: "«PrAgencyId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrAgentId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrPostnId»", fieldValue: "1-5D2V9F " },
{ fieldName: "«PrPrtnrId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrRepDnrmFlg»", fieldValue: "Y" },
{ fieldName: "«PrRepManlFlg»", fieldValue: "Y" },
{ fieldName: "«PrRepSysFlg»", fieldValue: "Y" },
{ fieldName: "«PrSgroupId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrSubjectId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrSuspctId»", fieldValue: "No Match Row Id" },
{ fieldName: "«IaCategory»", fieldValue: "2" },
{ fieldName: "«RewardExchangeDt»", fieldValue: "2010-10-07T11:09:02" },
{ fieldName: "«RowId»", fieldValue: "1-2DCA-1327" },
{ fieldName: "«CaseNumber»", fieldValue: "08-CA-123456" },
{ fieldName: "«CaseSource»", fieldValue: "Visit" },
{ fieldName: "«DisputeUnitState»", fieldValue: "OH" },
{ fieldName: "«CaseStatus»", fieldValue: "Open" },
{ fieldName: "«CaseSubType»", fieldValue: "CA" },
{ fieldName: "«CaseSubTypeCd»", fieldValue: null },
{ fieldName: "«TerritoryTypeCd»", fieldValue: "08" },
{ fieldName: "«ThreatLvlCd»", fieldValue: "Batch" },
{ fieldName: "«CaseType»", fieldValue: "C" },
{ fieldName: "«BlockedFlag»", fieldValue: null },
{ fieldName: "«CaseLongName»", fieldValue: "This is the case name from the data" },
{ fieldName: "«XCaseNumCi»", fieldValue: null },
{ fieldName: "«DojCaseType»", fieldValue: null },
{ fieldName: "«ElectionTargetDt»", fieldValue: null },
{ fieldName: "«HearingTargetDt»", fieldValue: null },
{ fieldName: "«MethodType»", fieldValue: null },
{ fieldName: "«XNameCi»", fieldValue: null },
{ fieldName: "«Num8a3Discriminatees»", fieldValue: null },
{ fieldName: "«Num8b2Discriminatees»", fieldValue: null },
{ fieldName: "«NumOfEmployees»", fieldValue: 146 },
{ fieldName: "«PostElectionSelfCertification»", fieldValue: null },
{ fieldName: "«Potential10j»", fieldValue: "N" },
{ fieldName: "«XPrPostnBrdId»", fieldValue: "1-4P8HN1" },
{ fieldName: "«XPrPostnSpvId»", fieldValue: "1-1RAQT2" },
{ fieldName: "«ElectionSelfCertification»", fieldValue: null },
{ fieldName: "«XTypeCdCi»", fieldValue: null },
{ fieldName: "«Moved2dh»", fieldValue: 1 },
{ fieldName: "«IdentityVal»", fieldValue: 5792070 },
{ fieldName: "«CdcRecordedFields»", fieldValue: null },
{ fieldName: "«NxgenTestCase»", fieldValue: "N" },
{ fieldName: "«InquiryChargePetition»", fieldValue: null },
{ fieldName: "«ChangeCaptureDatetime»", fieldValue: "2019-10-20T13:17:15.83" },
{ fieldName: "«RegionRecommendsPursuing10j»", fieldValue: "N" },
{ fieldName: "«SurrogateKey»", fieldValue: 1731295 }
]
await searchDocForFields(fieldList, context);
})
}
async function searchDocForFields(fieldList, context) {
console.log("Dataset: " + JSON.stringify(fieldList));
const allSearchResults = [];
console.log('fieldList.Length = ' + fieldList.length);
// console.log("Dataset in second part: " + JSON.stringify(fieldList));
for (let fieldCount = 0; fieldCount < fieldList.length; fieldCount++) {
let options = Word.SearchOptions.newObject(context);
options.matchWildCards = false;
options.matchCase = true;
options.matchWholeWord = true;
// Check the document to see if this field from the database is found
// console.log("Checking for " + fieldList[fieldCount].fieldName + " to be replaced with " + fieldList[fieldCount].fieldValue);
let searchResults = context.document.body.search(fieldList[fieldCount].fieldName, options);
//Load all of the items that meet the search criteria
searchResults.load('items');
let correlatedSearchResult = {
rangesMatchingFieldName: searchResults,
fieldValue: fieldList[fieldCount].fieldValue
}
allSearchResults.push(correlatedSearchResult);
}
await context.sync();
// Now we have all of the search results in the correlatedSearchResult array.
for (let searchResultCount = 0; searchResultCount < allSearchResults.length; searchResultCount++) {
let correlatedObject = allSearchResults[searchResultCount];
console.log("Checking for search result " + searchResultCount + " of " + allSearchResults.length);
for (let rangeCount = 0; rangeCount < correlatedObject.rangesMatchingFieldName.items.length; rangeCount++) {
let targetRange = correlatedObject.rangesMatchingFieldName.items[rangeCount];
let replacementValue = correlatedObject.fieldValue;
targetRange.insertText(replacementValue, Word.InsertLocation.replace);
console.log("Replacing found instance " + rangeCount + " of " + correlatedObject.rangesMatchingFieldName.items.length + " (" + JSON.stringify(targetRange) + ") with (" + replacementValue + ")");
}
}
return await context.sync();
}
function dataCompareTest(caseNum) {
Word.run((context) => {
const
url = `[My API URL]`;
const codedFieldList = [
{ fieldName: "«StartLogSeqNo»", fieldValue: "AAA5fgABbpgACw==" },
{ fieldName: "«EndLogSeqNo»", fieldValue: null },
{ fieldName: "«SeqVal»", fieldValue: "AAA5fgABbpgAAw==" },
{ fieldName: "«DmlOperation»", fieldValue: 4 },
{ fieldName: "«DmlUpdateFields»", fieldValue: "AAAAAAAAAUAgADg=" },
{ fieldName: "«CaseAssgnedDt»", fieldValue: "2011-07-22T17:12:19" },
{ fieldName: "«AsgnUsrExcldFlg»", fieldValue: "N" },
{ fieldName: "«BuId»", fieldValue: "0-R9NH" },
{ fieldName: "«CaseFiledDt»", fieldValue: "2006-03-09T00:00:00" },
{ fieldName: "«InquiryId»", fieldValue: "08-CA-123456" },
{ fieldName: "«ChgofccmReqFlg»", fieldValue: "N" },
{ fieldName: "«DisputeUnitCity»", fieldValue: "Cleveland" },
{ fieldName: "«CaseClasification»", fieldValue: "Unclassified" },
{ fieldName: "«CaseClosedDt»", fieldValue: null },
{ fieldName: "«Created»", fieldValue: "2010-10-07T15:32:29" },
{ fieldName: "«CreatedBy»", fieldValue: "0-1" },
{ fieldName: "«CrimeSubTypeCd»", fieldValue: null },
{ fieldName: "«TypeCd»", fieldValue: null },
{ fieldName: "«DbLastUpd»", fieldValue: "2019-10-20T17:17:14.31" },
{ fieldName: "«DbLastUpdSrc»", fieldValue: "ScriptingService_PreInvokeMethod" },
{ fieldName: "«CaseDescription»", fieldValue: null },
{ fieldName: "«LastUpd»", fieldValue: "2019-10-20T17:17:14" },
{ fieldName: "«LastUpdBy»", fieldValue: "1-CGA" },
{ fieldName: "«LocalSeqNum»", fieldValue: 1 },
{ fieldName: "«ModificationNum»", fieldValue: 11 },
{ fieldName: "«CaseName»", fieldValue: "This is the case name from the data" },
{ fieldName: "«ParCaseId»", fieldValue: null },
{ fieldName: "«PrAgencyId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrAgentId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrPostnId»", fieldValue: "1-5D2V9F " },
{ fieldName: "«PrPrtnrId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrRepDnrmFlg»", fieldValue: "Y" },
{ fieldName: "«PrRepManlFlg»", fieldValue: "Y" },
{ fieldName: "«PrRepSysFlg»", fieldValue: "Y" },
{ fieldName: "«PrSgroupId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrSubjectId»", fieldValue: "No Match Row Id" },
{ fieldName: "«PrSuspctId»", fieldValue: "No Match Row Id" },
{ fieldName: "«IaCategory»", fieldValue: "2" },
{ fieldName: "«RewardExchangeDt»", fieldValue: "2010-10-07T11:09:02" },
{ fieldName: "«RowId»", fieldValue: "1-2DCA-1327" },
{ fieldName: "«CaseNumber»", fieldValue: "08-CA-123456" },
{ fieldName: "«CaseSource»", fieldValue: "Visit" },
{ fieldName: "«DisputeUnitState»", fieldValue: "OH" },
{ fieldName: "«CaseStatus»", fieldValue: "Open" },
{ fieldName: "«CaseSubType»", fieldValue: "CA" },
{ fieldName: "«CaseSubTypeCd»", fieldValue: null },
{ fieldName: "«TerritoryTypeCd»", fieldValue: "08" },
{ fieldName: "«ThreatLvlCd»", fieldValue: "Batch" },
{ fieldName: "«CaseType»", fieldValue: "C" },
{ fieldName: "«BlockedFlag»", fieldValue: null },
{ fieldName: "«CaseLongName»", fieldValue: "This is the case name from the data" },
{ fieldName: "«XCaseNumCi»", fieldValue: null },
{ fieldName: "«DojCaseType»", fieldValue: null },
{ fieldName: "«ElectionTargetDt»", fieldValue: null },
{ fieldName: "«HearingTargetDt»", fieldValue: null },
{ fieldName: "«MethodType»", fieldValue: null },
{ fieldName: "«XNameCi»", fieldValue: null },
{ fieldName: "«Num8a3Discriminatees»", fieldValue: null },
{ fieldName: "«Num8b2Discriminatees»", fieldValue: null },
{ fieldName: "«NumOfEmployees»", fieldValue: 146 },
{ fieldName: "«PostElectionSelfCertification»", fieldValue: null },
{ fieldName: "«Potential10j»", fieldValue: "N" },
{ fieldName: "«XPrPostnBrdId»", fieldValue: "1-4P8HN1" },
{ fieldName: "«XPrPostnSpvId»", fieldValue: "1-1RAQT2" },
{ fieldName: "«ElectionSelfCertification»", fieldValue: null },
{ fieldName: "«XTypeCdCi»", fieldValue: null },
{ fieldName: "«Moved2dh»", fieldValue: 1 },
{ fieldName: "«IdentityVal»", fieldValue: 5792070 },
{ fieldName: "«CdcRecordedFields»", fieldValue: null },
{ fieldName: "«NxgenTestCase»", fieldValue: "N" },
{ fieldName: "«InquiryChargePetition»", fieldValue: null },
{ fieldName: "«ChangeCaptureDatetime»", fieldValue: "2019-10-20T13:17:15.83" },
{ fieldName: "«RegionRecommendsPursuing10j»", fieldValue: "N" },
{ fieldName: "«SurrogateKey»", fieldValue: 1731295 }
]
fetch(url)
.then(resp => resp.json())
.then(resp => {
console.log('Server Response : ' + JSON.stringify(resp));
let fetchFieldList = Object.entries(resp).map(([k, v]) => {
let fieldNameString = '«' + k + '»';
return { fieldName: fieldNameString, fieldValue: v };
});
console.log("Dataset in first part: " + JSON.stringify(fetchFieldList));
return fetchFieldList;
})
.then(fieldList => {
console.log('Comparing datasets');
const jsonFieldList = JSON.stringify(fieldList);
const jsonCodedFieldList = JSON.stringify(codedFieldList);
const same = jsonFieldList === jsonCodedFieldList;
console.log("Are the arrays the same? " + same);
})
.catch(errorHandler);
return context.sync();
});
}
//$$(Helper function for treating errors, $loc_script_taskpane_home_js_comment34$)$$
function errorHandler(error) {
// $$(Always be sure to catch any accumulated errors that bubble up from the Word.run execution., $loc_script_taskpane_home_js_comment35$)$$
showNotification("Error:", error);
console.log("Error: " + error);
if (error instanceof OfficeExtension.Error) {
console.log("Debug info: " + JSON.stringify(error.debugInfo));
}
}
// Helper function for displaying notifications
function showNotification(header, content) {
$("#notification-header").text(header);
$("#notification-body").text(content);
messageBanner.showBanner();
messageBanner.toggleExpansion();
}
})();
样本 JSON return 来自我的数据 API:
{
"CaseAssgnedDt": "2011-07-22T17:12:19",
"AsgnUsrExcldFlg": "N",
"BuId": "0-R9NH",
"CaseFiledDt": "2006-03-09T00:00:00",
"InquiryId": "08-CA-123456",
"ChgofccmReqFlg": "N",
"DisputeUnitCity": "Cleveland",
"CaseClasification": "Unclassified",
"CaseClosedDt": null,
"Created": "2010-10-07T15:32:29",
"CreatedBy": "0-1",
"CrimeSubTypeCd": null,
"TypeCd": null,
"DbLastUpd": "2019-10-20T17:17:14.31",
"DbLastUpdSrc": "ScriptingService_PreInvokeMethod",
"CaseDescription": null,
"LastUpd": "2019-10-20T17:17:14",
"LastUpdBy": "1-CGA",
"LocalSeqNum": 1,
"ModificationNum": 11,
"CaseName": "This is the case name from the data",
"ParCaseId": null,
"PrAgencyId": "No Match Row Id",
"PrAgentId": "No Match Row Id",
"PrPostnId": "1-5D2V9F ",
"PrPrtnrId": "No Match Row Id",
"PrRepDnrmFlg": "Y",
"PrRepManlFlg": "Y",
"PrRepSysFlg": "Y",
"PrSgroupId": "No Match Row Id",
"PrSubjectId": "No Match Row Id",
"PrSuspctId": "No Match Row Id",
"IaCategory": "2",
"RewardExchangeDt": "2010-10-07T11:09:02",
"RowId": "1-2DCA-1327",
"CaseNumber": "08-CA-123456",
"CaseSource": "Visit",
"DisputeUnitState": "OH",
"CaseStatus": "Open",
"CaseSubType": "CA",
"CaseSubTypeCd": null,
"TerritoryTypeCd": "08",
"ThreatLvlCd": "Batch",
"CaseType": "C",
"BlockedFlag": null,
"CaseLongName": "This is the case name from the data",
"XCaseNumCi": null,
"DojCaseType": null,
"ElectionTargetDt": null,
"HearingTargetDt": null,
"MethodType": null,
"XNameCi": null,
"Num8a3Discriminatees": null,
"Num8b2Discriminatees": null,
"NumOfEmployees": 146,
"PostElectionSelfCertification": null,
"Potential10j": "N",
"XPrPostnBrdId": "1-4P8HN1",
"XPrPostnSpvId": "1-1RAQT2",
"ElectionSelfCertification": null,
"XTypeCdCi": null,
"Moved2dh": 1,
"IdentityVal": 5792070,
"CdcRecordedFields": null,
"NxgenTestCase": "N",
"InquiryChargePetition": null,
"ChangeCaptureDatetime": "2019-10-20T13:17:15.83",
"RegionRecommendsPursuing10j": "N",
"SurrogateKey": 1731295
}
非常感谢您提供的一切帮助,谢谢。
谢谢。
-- 更新: 根据 Rick Kirkham 的建议,我创建了一个新函数(“simpleTest”,现在包含在上面的代码中)来简化和验证该方法,并且惊讶地发现它有效(尽管我敢打赌 Rick 并不感到惊讶,哈哈).
我还添加了一个函数“dataCompare”,也在上面的代码中),它手动加载一个数据集,另一个使用 Fetch 调用,然后比较两者,它响应两个数组是一样。
鉴于数据是相同的,而且 loadCaseData 和 simpleTest 函数都使用相同的 searchDocForFields 函数来执行搜索和替换,所以我很茫然,为什么 simpleTest 函数会工作,以及loadCaseData 函数因 ItemNotFound 错误而失败?
谢谢。 马克.
最终,这一切都是由于缺少单个等待引起的...请注意下面带有 FETCH 语句的行,该语句之前没有 AWAIT。
async function loadCaseData(caseNum) {
Word.run(async (context) => {
const ul = document.getElementById('caseData'),
url = `[URL to my API]`;
const createNode = element => { return document.createElement(element); };
const append = (parent, el) => { return parent.appendChild(el); };
/*----->*/ await fetch(url)
.then(resp => resp.json())
.then(resp => {
console.log('Server Response : ' + JSON.stringify(resp));
let fieldList = Object.entries(resp).map(([k, v]) => {
let fieldNameString = '«' + k + '»';
return { fieldName: fieldNameString, fieldValue: v };
});
//console.log("Dataset in first part: " + JSON.stringify(fieldList));
return fieldList;
})
.then(async fieldList => await searchDocForFields(fieldList, context))
.catch(errorHandler);
return context.sync();
});
}
async function newLoadCaseData(caseNum) {
Word.run(async (context) => {
const
url = `[URL to my API]`;
let resp = await (await fetch(url)).json();
//let data = resp.json();
console.log('Server Response : ' + JSON.stringify(resp));
let fieldList = Object.entries(resp).map(([k, v]) => {
let fieldNameString = '«' + k + '»';
return { fieldName: fieldNameString, fieldValue: v };
});
console.log("Dataset in first part: " + JSON.stringify(fieldList));
await searchDocForFields(fieldList, context);
});
}
我通过尝试进一步简化我的代码发现了这一点,因此创建了同样显示的“newLoadCaseData”函数。这个版本写FETCH语句的时候,VS2022给我插了个await,让我大开眼界。
现在可以使用了,我希望我的研究和 mistakes/fixes 也能帮助到其他人。
尽情享受吧!
马克.