Office-JS API with Fetch 从服务器获取数据,替换 Word 中的字段
Office-JS API with Fetch to get data from server, replace fields in Word
我是 Office-JS 的新手 API,但我正在尝试开发一个 POC 来演示通过单击按钮将 Word 文档中的所有字段替换为从中检索到的相应数据的能力一个 API.
所以我开发了一个 API 作为 Azure 函数,我可以调用它,传递一个值,它将 return 字段名称和值作为 JSON 用于匹配传递值的记录。我已经使用 Postman 对此进行了测试。
现在我正在尝试让 Office-JS 工作。我从 VS-2022 模板开始。
我打算采用的方法是,当用户单击按钮时,应用程序将调用 API 并获取记录(数据)字段作为一组 name/value 对。
然后,我想遍历所有的(数据)字段returned,并且对于每个(数据)字段名称,检查文档中是否有(文档)字段姓名;如果是,请将(文档)字段替换为(数据)字段的值。
最后,我意识到以其他方式循环可能更有效(循环遍历文档字段,然后获取(数据)字段的值等),但我认为我可以调整它一旦我开始工作。
我也意识到在一个循环中执行 context.sync() 是不好的做法,但是再次 - 我可以在它工作后清理它。
现在,我的代码报告“错误:InvalidRequestContext:无法在不同的请求上下文中使用该对象。”
我的代码如下:
(function () {
"use strict";
var messageBanner;
// The initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
$(document).ready(function () {
// Initialize the notification mechanism and hide it
var element = document.querySelector('.MessageBanner');
messageBanner = new components.MessageBanner(element);
messageBanner.hideBanner();
// 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(displaySelectedText);
return;
}
$("#template-description").text("This POC demonstrates template capabilities for NLRB within WORD.");
$('#button-text').text("Merge Template!");
$('#button-desc').text("Replaces fields with approprate data.");
// Add a click event handler for the highlight button.
$('#highlight-button').click(loadCaseData("08-CA-036441"));
});
};
//CaseNum=08-CA-036441&DataType=1
function loadCaseData(caseNum) {
Word.run((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); };
fetch(url)
.then(response => { return response.json(); })
.then(json => {
let caseDataResult = json;
// Identify fields in the document
// Loop through case data for field substitution
var range = context.document.body;
context.load(range, 'text');
var searchResults;
for (let fieldName in caseDataResult) {
var searchFieldName = "«" + fieldName + "»";
let fieldValue = caseDataResult[fieldName];
return context.sync()
.then(function () {
// Queue a search command.
searchResults = range.search(searchFieldName, { matchCase: true, matchWholeWord: true });
// Queue a commmand to load the font property of the results.
context.load(searchResults, 'text');
})
.then(context.sync)
.then(function () {
var replaceCount = searchResults.items.length;
if (replaceCount && replaceCount >= 1) {
for (var replaceItem = 0; replaceItem < replaceCount; replaceItem++) {
searchResults[replaceItem].insertText(fieldValue,
Word.InsertLocation.replace);
}
}
})
.then(context.sync);
}
return context.sync();
})
.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-036441",
"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": "Sample test case name",
"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-036441",
"CaseSource": "Visit",
"DisputeUnitState": "OH",
"CaseStatus": "Open",
"CaseSubType": "CA",
"CaseSubTypeCd": null,
"TerritoryTypeCd": "08",
"ThreatLvlCd": "Batch",
"CaseType": "C",
"BlockedFlag": null,
"CaseLongName": "Long sample test case name",
"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
}
非常感谢您提供的所有帮助,让这项工作顺利进行。
谢谢。
这是 context.sync 嵌套调用的另一个常见症状。首先修复嵌套。此外,当您将过滤逻辑尽可能靠近数据源时,性能会更好。考虑将 Azure 函数设计为接收字段列表并仅发回匹配名称的数据。然后您的客户端代码会大大简化,因为您可以假设返回的每个数据记录都有一个匹配字段。
我是 Office-JS 的新手 API,但我正在尝试开发一个 POC 来演示通过单击按钮将 Word 文档中的所有字段替换为从中检索到的相应数据的能力一个 API.
所以我开发了一个 API 作为 Azure 函数,我可以调用它,传递一个值,它将 return 字段名称和值作为 JSON 用于匹配传递值的记录。我已经使用 Postman 对此进行了测试。
现在我正在尝试让 Office-JS 工作。我从 VS-2022 模板开始。
我打算采用的方法是,当用户单击按钮时,应用程序将调用 API 并获取记录(数据)字段作为一组 name/value 对。
然后,我想遍历所有的(数据)字段returned,并且对于每个(数据)字段名称,检查文档中是否有(文档)字段姓名;如果是,请将(文档)字段替换为(数据)字段的值。
最后,我意识到以其他方式循环可能更有效(循环遍历文档字段,然后获取(数据)字段的值等),但我认为我可以调整它一旦我开始工作。
我也意识到在一个循环中执行 context.sync() 是不好的做法,但是再次 - 我可以在它工作后清理它。
现在,我的代码报告“错误:InvalidRequestContext:无法在不同的请求上下文中使用该对象。”
我的代码如下:
(function () {
"use strict";
var messageBanner;
// The initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
$(document).ready(function () {
// Initialize the notification mechanism and hide it
var element = document.querySelector('.MessageBanner');
messageBanner = new components.MessageBanner(element);
messageBanner.hideBanner();
// 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(displaySelectedText);
return;
}
$("#template-description").text("This POC demonstrates template capabilities for NLRB within WORD.");
$('#button-text').text("Merge Template!");
$('#button-desc').text("Replaces fields with approprate data.");
// Add a click event handler for the highlight button.
$('#highlight-button').click(loadCaseData("08-CA-036441"));
});
};
//CaseNum=08-CA-036441&DataType=1
function loadCaseData(caseNum) {
Word.run((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); };
fetch(url)
.then(response => { return response.json(); })
.then(json => {
let caseDataResult = json;
// Identify fields in the document
// Loop through case data for field substitution
var range = context.document.body;
context.load(range, 'text');
var searchResults;
for (let fieldName in caseDataResult) {
var searchFieldName = "«" + fieldName + "»";
let fieldValue = caseDataResult[fieldName];
return context.sync()
.then(function () {
// Queue a search command.
searchResults = range.search(searchFieldName, { matchCase: true, matchWholeWord: true });
// Queue a commmand to load the font property of the results.
context.load(searchResults, 'text');
})
.then(context.sync)
.then(function () {
var replaceCount = searchResults.items.length;
if (replaceCount && replaceCount >= 1) {
for (var replaceItem = 0; replaceItem < replaceCount; replaceItem++) {
searchResults[replaceItem].insertText(fieldValue,
Word.InsertLocation.replace);
}
}
})
.then(context.sync);
}
return context.sync();
})
.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-036441",
"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": "Sample test case name",
"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-036441",
"CaseSource": "Visit",
"DisputeUnitState": "OH",
"CaseStatus": "Open",
"CaseSubType": "CA",
"CaseSubTypeCd": null,
"TerritoryTypeCd": "08",
"ThreatLvlCd": "Batch",
"CaseType": "C",
"BlockedFlag": null,
"CaseLongName": "Long sample test case name",
"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
}
非常感谢您提供的所有帮助,让这项工作顺利进行。
谢谢。
这是 context.sync 嵌套调用的另一个常见症状。首先修复嵌套。此外,当您将过滤逻辑尽可能靠近数据源时,性能会更好。考虑将 Azure 函数设计为接收字段列表并仅发回匹配名称的数据。然后您的客户端代码会大大简化,因为您可以假设返回的每个数据记录都有一个匹配字段。