Dynamics CRM 365:通过功能区上的按钮下载 Word 文档模板
Dynamics CRM 365 : Downloading a Word Document Template via a Button on the Ribbon
目前用户必须点击省略号、word模板、最后引用才能下载word模板。
为了方便我们的用户,我们希望在按下功能区上的“打印报价”按钮时下载文档。
这可能吗?如果是这样,我将如何去做呢?我了解如何使用功能区 workbench 编辑功能区。我需要知道如何使用功能区下载 Word 模板。
如果解决方案是使用功能区 workbench,我可以输入什么命令来下载要下载的 word 模板?
当您单击模板弹出窗口时,它会通过调用 /AppWebServices/DocumentTemplate.asmx
动态填充,其中 returns 菜单的 XML。
事件主页网格中 Word 模板的弹出窗口如下所示:
<Menu Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu">
<MenuSection Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.CreateTemplates" Title="Create Word Template" Sequence="10" DisplayMode="Menu16">
<Controls Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.CreateTemplates.Controls">
<Button Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.CreateTemplates.Controls.00000000-0000-0000-0000-000000000000" Command="incident|NoRelationship|HomePageGrid|Mscrm.WordTemplate.CreateWordTemplate.Grid" Sequence="10" ToolTipDescription="Create Word Template" Alt="Create Word Template" LabelText="Create Word Template" />
</Controls>
</MenuSection>
<MenuSection Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.WordTemplates" Title="Word Templates" Sequence="20" DisplayMode="Menu16">
<Controls Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.WordTemplates.Controls">
<Button Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.WordTemplates.Controls.9b77c5b0-1033-4741-a01c-afdbdb1c3f22" Command="incident|NoRelationship|HomePageGrid|Mscrm.WordTemplate.TemplatesMenu.Grid" Sequence="10" ToolTipDescription="Case Summary" Alt="Case Summary" LabelText="Case Summary" />
</Controls>
</MenuSection>
</Menu>
我目前没有办法尝试,但我会尝试 "copy" 最后一个 <Button>
:
<Button Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.WordTemplates.Controls.9b77c5b0-1033-4741-a01c-afdbdb1c3f22" Command="incident|NoRelationship|HomePageGrid|Mscrm.WordTemplate.TemplatesMenu.Grid" Sequence="10" ToolTipDescription="Case Summary" Alt="Case Summary" LabelText="Case Summary" />
可以仅使用 CRM 支持的功能来执行此操作(当然,我确信使用不受支持的 javascript 也可以执行此操作,但我目前没有时间对此进行调查)。实现所需功能应采取的步骤:
- 创建类型为 Action 的新流程,绑定到您想要的实体
创建一个模板(我在这里建议采取行动的原因是
它可以使用 JavaScript 和 CRM WebAPI)
轻松调用
- 在此操作中添加单个步骤 - 调用一个操作并选择
内置操作 "SetWordTemplate"
- 设置此操作的属性 - 选择您需要的模板
并将目标动态设置为当前实体(使用 Dynamic
值助手)如果您从未使用过此操作 - 它只是创建
给定的单词模板并将其作为注释添加到您的实体中
- 现在您需要在按钮中编写逻辑(我假设您
知道如何使用功能区 Workbench 或其他方式添加按钮)
- 使用 WebAPI 调用您的操作
- 查找刚刚为您的实体创建的注释
附加文件
- 下载附件(可以给用户显示一些提示或者
只需强制下载文件,用户必须保存它)
- 删除注释
也许不是单线,但会让您处于受支持的区域...
ExecuteWordMerge = function (wordtemplateid, entitytypecodeint, ids, templatetype, fieldforfilename, filenameoverride) {
try {
Xrm.Page.ui.clearFormNotification("worderror");
var funcpath = Xrm.Page.context.getClientUrl() + "/_grid/print/print_data.aspx";
if (typeof ids !== "object") {
var tids = ids;
ids = new Array();
ids.push(tids);
}
var wordTemplateId = wordtemplateid;//"f1f7b994-543b-e711-8106-c4346bac2908" test data;
var currentEntityTypeCode = entitytypecodeint;//"10063" test data;
var templateType = (templatetype || 9940); //9940 is global and 9941 is personal
var fieldForFileName = (fieldforfilename || "");
var formdata = "exportType=MergeWordTemplate&selectedRecords=" + encodeURIComponent(JSON.stringify(ids)) +
"&associatedentitytypecode=" + currentEntityTypeCode + "&TemplateId=" + wordTemplateId + "&TemplateType=" + templateType;
var req = new XMLHttpRequest();
req.open("POST", funcpath, true);
req.responseType = "arraybuffer";
req.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
req.setRequestHeader("Accept-Language", "en-US,en;q=0.8");
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.onreadystatechange = function () {
if (this.readyState == 4) {/* complete */
req.onreadystatechange = null;
if (this.status >= 200 && this.status <= 299) {//200 range okay
var mimetype = (2 === 2) ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
var blob = new Blob([req.response], { type: mimetype });
var fileNameTemplate = req.getResponseHeader('content-disposition').split('filename=')[1].replace(/'/g, "");
var dloadurl = URL.createObjectURL(blob);
var filename = (fieldForFileName !== "" && Xrm.Page.getAttribute(fieldForFileName) !== null && Xrm.Page.getAttribute(fieldForFileName).getValue() !== "") ?
Xrm.Page.getAttribute(fieldForFileName).getValue() : fileNameTemplate;
filename = filenameoverride || filename;
//new code, prevent IE errors
if (navigator.msSaveOrOpenBlob) {
navigator.msSaveOrOpenBlob(blob, filename);
return;
}
else if (window.navigator.msSaveBlob) { // for IE browser
window.navigator.msSaveBlob(blob, filename);
return;
}
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = dloadurl;
a.download = filename;
a.click();
URL.revokeObjectURL(dloadurl);
//window.location = dloadurl;//we can use just this instead of creating an anchor but we don't get to the name the file
}
else {
Xrm.Page.ui.setFormNotification("An Error occurred generating the word document, please contact support if the issue persists,code: " + this.status, "ERROR", "worderror");
}
}
};
req.send(formdata);
}
catch (err) {
Xrm.Page.ui.setFormNotification("An Error occurred generating the word document, please contact support if the issue persists. " + err.message, "ERROR", "worderror");
}
}
只是为了简化@TeamEASI.com 我在这里做了一点回答。
- 使用 XRMToolBox Ribbon Workbench 2016 向功能区添加按钮。
- 创建如下所示的 JS 网络资源。
/*
* Author: Matthew Hunt
* File: vsi_DownloadTemplate.js
* Date: 12/20/2017
* Project: CRM USA
* Description: DownloadTemplate() allows the user to download a document template
* via a button on the ribbon.
*
* @param entitytypecode: the type code of the entity. In the ribbon workbench set a
* CRM parameter with value PrimaryEntityTypeCode. ex: 1063
*
* @param templateid: the id for the template you want to download. I had to go to
* the database to find this and pass it as a string parameter in the ribbon workbench.
* For example:
* SELECT DocumentTemplateId, Name FROM dbo.DocumentTemplateBase WHERE Name Like '%Quote%';
* returns something like 4AB391A4-D247-E711-80D3-005056914EA2
* Unforunatly, anytime the template is updated, you'll probably have to get the new id.
*
* @param templatetype: the code for the template type. Pass this value in the ribbon
* workbench as a int param. ex: 9940 is a documenttemplate
*
* @param filename: the resulting name of the file that will be downloaded to the users
* computer. Pass this value in the ribbon workbench as a string param. ex: Quote.docx
*
*/
function DownloadTemplate(entitytypecode, templateid, templatetype, filename){
// retrieve the entity id from the current page
var entityid = new Array();
entityid.push(Xrm.Page.data.entity.getId());
// try and make a request for the document template
try{
// clear the page of any previous errors
Xrm.Page.ui.clearFormNotification("docerror");
// the path that will be used to retrieve the word template
var funcpath = Xrm.Page.context.getClientUrl() + "/_grid/print/print_data.aspx";
// open the request to create the template
var req = new XMLHttpRequest();
req.open("POST", funcpath, true);
req.responseType = "arraybuffer";
req.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
req.setRequestHeader("Accept-Language", "en-US,en;q=0.8");
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// on completion, run the bellow function
req.onreadystatechange = function () {
// request complete
if (this.readyState == 4) {
req.onreadystatechange = null;
// check if we got back a 200 from the request
if (this.status >= 200 && this.status <= 299) {
// add the download url to an a tag and then click the a tag
// to download the document
var mimetype = (2 === 2) ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
var blob = new Blob([req.response], { type: mimetype });
var dloadurl = URL.createObjectURL(blob);
var a = document.createElement("a");
// if ie, because ie sucks
if (navigator.msSaveOrOpenBlob) {
navigator.msSaveOrOpenBlob(blob, filename);
// else a browser that doesn't suck
} else {
document.body.appendChild(a);
a.style = "display: none";
a.href = dloadurl;
a.download = filename;
a.click();
URL.revokeObjectURL(dloadurl);
}
}
};
// compile the data to send with the request
var formdata = "exportType=MergeWordTemplate&selectedRecords=" + encodeURIComponent(JSON.stringify(entityid)) +
"&associatedentitytypecode=" + entitytypecode + "&TemplateId=" + templateid + "&templatetype=" + templatetype;
// make the request to create the template
req.send(formdata);
}catch (err) {
PrintError(err.message);
}
}
/*
* PrintError() is a helper method to display any errors to the user.
*/
function PrintError(msg){
Xrm.Page.ui.setFormNotification("An Error occurred generating the word document, please contact support if the issue persists. " + msg, "ERROR", "docerror");
}
IE 修复:
- 使用XRMToolBox Ribbon Workbench 2016创建一个命令,参数如下,点击按钮时执行JS。
要获取实体代码,运行下面查询:
SELECT coalesce(OriginalLocalizedName,name) AS DisplayName, Name AS SchemaName, ObjectTypeCode
FROM EntityLogicalView
ORDER BY ObjectTypeCode
和 Template ID
:
SELECT DocumentTemplateId, Name FROM dbo.DocumentTemplateBase
对于新版本的 CRM,此 javascript 代码需要修改以删除不受支持的 API,以及一些其他更改,以便能够与 CHROME 一起使用.
低于我的工作版本,
/*
* Author: Matthew Hunt
* Changes: Philippe Guarino
* File: vsi_DownloadTemplate.js
* Date: 22/09/2021
* Project: CRM USA
* Description: DownloadTemplate() allows the user to download a document template
* via a button on the ribbon.
*
* @param entitytypecode: the type code of the entity. In the ribbon workbench set a
* CRM parameter with value PrimaryEntityTypeCode. ex: 1063
*
* @param templateid: the id for the template you want to download. I had to go to
* the database to find this and pass it as a string parameter in the ribbon workbench.
* For example:
* SELECT DocumentTemplateId, Name FROM dbo.DocumentTemplateBase WHERE Name Like '%Quote%';
* returns something like 4AB391A4-D247-E711-80D3-005056914EA2
* Unforunatly, anytime the template is updated, you'll probably have to get the new id.
*
* @param templatetype: the code for the template type. Pass this value in the ribbon
* workbench as a int param. ex: 9940 is a documenttemplate
*
* @param filename: the resulting name of the file that will be downloaded to the users
* computer. Pass this value in the ribbon workbench as a string param. ex: Quote.docx
*
*/
function DownloadTemplate(entitytypecode, templateid, templatetype, filename, formContext)
{
// var formContext = executionContext.getFormContext(); // get formContext
// retrieve the entity id from the current page
var entityid = new Array();
entityid.push(formContext.data.entity.getId());
// try and make a request for the document template
try
{
// clear the page of any previous errors
formContext.ui.clearFormNotification("docerror");
// the path that will be used to retrieve the word template
var globalContext = Xrm.Utility.getGlobalContext();
var funcpath = globalContext.getClientUrl() + "/_grid/print/print_data.aspx";;
// open the request to create the template
var req = new XMLHttpRequest();
req.open("POST", funcpath, true);
req.responseType = "arraybuffer";
req.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
req.setRequestHeader("Accept-Language", "en-US,en;q=0.8");
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// on completion, run the bellow function
req.onreadystatechange = function ()
{
// request complete
if (this.readyState == 4)
{
req.onreadystatechange = null;
// check if we got back a 200 from the request
if (this.status >= 200 && this.status <= 299)
{
// add the download url to an a tag and then click the a tag
// to download the document
var mimetype = (2 === 2) ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
var blob = new Blob([req.response],
{
type: mimetype
});
var dloadurl = (window.URL ? URL : webkitURL).createObjectURL(blob);
var a = document.createElement("a");
// if ie, because ie sucks
if (navigator.msSaveOrOpenBlob)
{
navigator.msSaveOrOpenBlob(blob, filename);
// else a browser that doesn't suck
}
else
{
document.body.appendChild(a);
a.style = "display: none";
a.href = dloadurl;
a.download = filename;
a.click();
URL.revokeObjectURL(dloadurl);
}
}
}
};
// compile the data to send with the request
var formdata = "exportType=MergeWordTemplate&selectedRecords=" + encodeURIComponent(JSON.stringify(entityid)) +
"&associatedentitytypecode=" + entitytypecode + "&TemplateId=" + templateid + "&templatetype=" + templatetype;
// make the request to create the template
req.send(formdata);
}
catch (err)
{
PrintError(err.message);
}
}
/*
* PrintError() is a helper method to display any errors to the user.
*/
function PrintError(msg)
{
Xrm.Page.ui.setFormNotification("An Error occurred generating the word document, please contact support if the issue persists. " + msg, "ERROR", "docerror");
}
目前用户必须点击省略号、word模板、最后引用才能下载word模板。
为了方便我们的用户,我们希望在按下功能区上的“打印报价”按钮时下载文档。
这可能吗?如果是这样,我将如何去做呢?我了解如何使用功能区 workbench 编辑功能区。我需要知道如何使用功能区下载 Word 模板。
如果解决方案是使用功能区 workbench,我可以输入什么命令来下载要下载的 word 模板?
当您单击模板弹出窗口时,它会通过调用 /AppWebServices/DocumentTemplate.asmx
动态填充,其中 returns 菜单的 XML。
事件主页网格中 Word 模板的弹出窗口如下所示:
<Menu Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu">
<MenuSection Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.CreateTemplates" Title="Create Word Template" Sequence="10" DisplayMode="Menu16">
<Controls Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.CreateTemplates.Controls">
<Button Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.CreateTemplates.Controls.00000000-0000-0000-0000-000000000000" Command="incident|NoRelationship|HomePageGrid|Mscrm.WordTemplate.CreateWordTemplate.Grid" Sequence="10" ToolTipDescription="Create Word Template" Alt="Create Word Template" LabelText="Create Word Template" />
</Controls>
</MenuSection>
<MenuSection Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.WordTemplates" Title="Word Templates" Sequence="20" DisplayMode="Menu16">
<Controls Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.WordTemplates.Controls">
<Button Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.WordTemplates.Controls.9b77c5b0-1033-4741-a01c-afdbdb1c3f22" Command="incident|NoRelationship|HomePageGrid|Mscrm.WordTemplate.TemplatesMenu.Grid" Sequence="10" ToolTipDescription="Case Summary" Alt="Case Summary" LabelText="Case Summary" />
</Controls>
</MenuSection>
</Menu>
我目前没有办法尝试,但我会尝试 "copy" 最后一个 <Button>
:
<Button Id="incident|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.incident.WordTemplates.Menu.WordTemplates.Controls.9b77c5b0-1033-4741-a01c-afdbdb1c3f22" Command="incident|NoRelationship|HomePageGrid|Mscrm.WordTemplate.TemplatesMenu.Grid" Sequence="10" ToolTipDescription="Case Summary" Alt="Case Summary" LabelText="Case Summary" />
可以仅使用 CRM 支持的功能来执行此操作(当然,我确信使用不受支持的 javascript 也可以执行此操作,但我目前没有时间对此进行调查)。实现所需功能应采取的步骤:
- 创建类型为 Action 的新流程,绑定到您想要的实体 创建一个模板(我在这里建议采取行动的原因是 它可以使用 JavaScript 和 CRM WebAPI) 轻松调用
- 在此操作中添加单个步骤 - 调用一个操作并选择 内置操作 "SetWordTemplate"
- 设置此操作的属性 - 选择您需要的模板 并将目标动态设置为当前实体(使用 Dynamic 值助手)如果您从未使用过此操作 - 它只是创建 给定的单词模板并将其作为注释添加到您的实体中
- 现在您需要在按钮中编写逻辑(我假设您 知道如何使用功能区 Workbench 或其他方式添加按钮)
- 使用 WebAPI 调用您的操作
- 查找刚刚为您的实体创建的注释 附加文件
- 下载附件(可以给用户显示一些提示或者 只需强制下载文件,用户必须保存它)
- 删除注释
也许不是单线,但会让您处于受支持的区域...
ExecuteWordMerge = function (wordtemplateid, entitytypecodeint, ids, templatetype, fieldforfilename, filenameoverride) {
try {
Xrm.Page.ui.clearFormNotification("worderror");
var funcpath = Xrm.Page.context.getClientUrl() + "/_grid/print/print_data.aspx";
if (typeof ids !== "object") {
var tids = ids;
ids = new Array();
ids.push(tids);
}
var wordTemplateId = wordtemplateid;//"f1f7b994-543b-e711-8106-c4346bac2908" test data;
var currentEntityTypeCode = entitytypecodeint;//"10063" test data;
var templateType = (templatetype || 9940); //9940 is global and 9941 is personal
var fieldForFileName = (fieldforfilename || "");
var formdata = "exportType=MergeWordTemplate&selectedRecords=" + encodeURIComponent(JSON.stringify(ids)) +
"&associatedentitytypecode=" + currentEntityTypeCode + "&TemplateId=" + wordTemplateId + "&TemplateType=" + templateType;
var req = new XMLHttpRequest();
req.open("POST", funcpath, true);
req.responseType = "arraybuffer";
req.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
req.setRequestHeader("Accept-Language", "en-US,en;q=0.8");
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.onreadystatechange = function () {
if (this.readyState == 4) {/* complete */
req.onreadystatechange = null;
if (this.status >= 200 && this.status <= 299) {//200 range okay
var mimetype = (2 === 2) ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
var blob = new Blob([req.response], { type: mimetype });
var fileNameTemplate = req.getResponseHeader('content-disposition').split('filename=')[1].replace(/'/g, "");
var dloadurl = URL.createObjectURL(blob);
var filename = (fieldForFileName !== "" && Xrm.Page.getAttribute(fieldForFileName) !== null && Xrm.Page.getAttribute(fieldForFileName).getValue() !== "") ?
Xrm.Page.getAttribute(fieldForFileName).getValue() : fileNameTemplate;
filename = filenameoverride || filename;
//new code, prevent IE errors
if (navigator.msSaveOrOpenBlob) {
navigator.msSaveOrOpenBlob(blob, filename);
return;
}
else if (window.navigator.msSaveBlob) { // for IE browser
window.navigator.msSaveBlob(blob, filename);
return;
}
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = dloadurl;
a.download = filename;
a.click();
URL.revokeObjectURL(dloadurl);
//window.location = dloadurl;//we can use just this instead of creating an anchor but we don't get to the name the file
}
else {
Xrm.Page.ui.setFormNotification("An Error occurred generating the word document, please contact support if the issue persists,code: " + this.status, "ERROR", "worderror");
}
}
};
req.send(formdata);
}
catch (err) {
Xrm.Page.ui.setFormNotification("An Error occurred generating the word document, please contact support if the issue persists. " + err.message, "ERROR", "worderror");
}
}
只是为了简化@TeamEASI.com 我在这里做了一点回答。
- 使用 XRMToolBox Ribbon Workbench 2016 向功能区添加按钮。
- 创建如下所示的 JS 网络资源。
/*
* Author: Matthew Hunt
* File: vsi_DownloadTemplate.js
* Date: 12/20/2017
* Project: CRM USA
* Description: DownloadTemplate() allows the user to download a document template
* via a button on the ribbon.
*
* @param entitytypecode: the type code of the entity. In the ribbon workbench set a
* CRM parameter with value PrimaryEntityTypeCode. ex: 1063
*
* @param templateid: the id for the template you want to download. I had to go to
* the database to find this and pass it as a string parameter in the ribbon workbench.
* For example:
* SELECT DocumentTemplateId, Name FROM dbo.DocumentTemplateBase WHERE Name Like '%Quote%';
* returns something like 4AB391A4-D247-E711-80D3-005056914EA2
* Unforunatly, anytime the template is updated, you'll probably have to get the new id.
*
* @param templatetype: the code for the template type. Pass this value in the ribbon
* workbench as a int param. ex: 9940 is a documenttemplate
*
* @param filename: the resulting name of the file that will be downloaded to the users
* computer. Pass this value in the ribbon workbench as a string param. ex: Quote.docx
*
*/
function DownloadTemplate(entitytypecode, templateid, templatetype, filename){
// retrieve the entity id from the current page
var entityid = new Array();
entityid.push(Xrm.Page.data.entity.getId());
// try and make a request for the document template
try{
// clear the page of any previous errors
Xrm.Page.ui.clearFormNotification("docerror");
// the path that will be used to retrieve the word template
var funcpath = Xrm.Page.context.getClientUrl() + "/_grid/print/print_data.aspx";
// open the request to create the template
var req = new XMLHttpRequest();
req.open("POST", funcpath, true);
req.responseType = "arraybuffer";
req.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
req.setRequestHeader("Accept-Language", "en-US,en;q=0.8");
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// on completion, run the bellow function
req.onreadystatechange = function () {
// request complete
if (this.readyState == 4) {
req.onreadystatechange = null;
// check if we got back a 200 from the request
if (this.status >= 200 && this.status <= 299) {
// add the download url to an a tag and then click the a tag
// to download the document
var mimetype = (2 === 2) ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
var blob = new Blob([req.response], { type: mimetype });
var dloadurl = URL.createObjectURL(blob);
var a = document.createElement("a");
// if ie, because ie sucks
if (navigator.msSaveOrOpenBlob) {
navigator.msSaveOrOpenBlob(blob, filename);
// else a browser that doesn't suck
} else {
document.body.appendChild(a);
a.style = "display: none";
a.href = dloadurl;
a.download = filename;
a.click();
URL.revokeObjectURL(dloadurl);
}
}
};
// compile the data to send with the request
var formdata = "exportType=MergeWordTemplate&selectedRecords=" + encodeURIComponent(JSON.stringify(entityid)) +
"&associatedentitytypecode=" + entitytypecode + "&TemplateId=" + templateid + "&templatetype=" + templatetype;
// make the request to create the template
req.send(formdata);
}catch (err) {
PrintError(err.message);
}
}
/*
* PrintError() is a helper method to display any errors to the user.
*/
function PrintError(msg){
Xrm.Page.ui.setFormNotification("An Error occurred generating the word document, please contact support if the issue persists. " + msg, "ERROR", "docerror");
}
IE 修复:
- 使用XRMToolBox Ribbon Workbench 2016创建一个命令,参数如下,点击按钮时执行JS。
要获取实体代码,运行下面查询:
SELECT coalesce(OriginalLocalizedName,name) AS DisplayName, Name AS SchemaName, ObjectTypeCode
FROM EntityLogicalView
ORDER BY ObjectTypeCode
和 Template ID
:
SELECT DocumentTemplateId, Name FROM dbo.DocumentTemplateBase
对于新版本的 CRM,此 javascript 代码需要修改以删除不受支持的 API,以及一些其他更改,以便能够与 CHROME 一起使用.
低于我的工作版本,
/*
* Author: Matthew Hunt
* Changes: Philippe Guarino
* File: vsi_DownloadTemplate.js
* Date: 22/09/2021
* Project: CRM USA
* Description: DownloadTemplate() allows the user to download a document template
* via a button on the ribbon.
*
* @param entitytypecode: the type code of the entity. In the ribbon workbench set a
* CRM parameter with value PrimaryEntityTypeCode. ex: 1063
*
* @param templateid: the id for the template you want to download. I had to go to
* the database to find this and pass it as a string parameter in the ribbon workbench.
* For example:
* SELECT DocumentTemplateId, Name FROM dbo.DocumentTemplateBase WHERE Name Like '%Quote%';
* returns something like 4AB391A4-D247-E711-80D3-005056914EA2
* Unforunatly, anytime the template is updated, you'll probably have to get the new id.
*
* @param templatetype: the code for the template type. Pass this value in the ribbon
* workbench as a int param. ex: 9940 is a documenttemplate
*
* @param filename: the resulting name of the file that will be downloaded to the users
* computer. Pass this value in the ribbon workbench as a string param. ex: Quote.docx
*
*/
function DownloadTemplate(entitytypecode, templateid, templatetype, filename, formContext)
{
// var formContext = executionContext.getFormContext(); // get formContext
// retrieve the entity id from the current page
var entityid = new Array();
entityid.push(formContext.data.entity.getId());
// try and make a request for the document template
try
{
// clear the page of any previous errors
formContext.ui.clearFormNotification("docerror");
// the path that will be used to retrieve the word template
var globalContext = Xrm.Utility.getGlobalContext();
var funcpath = globalContext.getClientUrl() + "/_grid/print/print_data.aspx";;
// open the request to create the template
var req = new XMLHttpRequest();
req.open("POST", funcpath, true);
req.responseType = "arraybuffer";
req.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
req.setRequestHeader("Accept-Language", "en-US,en;q=0.8");
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// on completion, run the bellow function
req.onreadystatechange = function ()
{
// request complete
if (this.readyState == 4)
{
req.onreadystatechange = null;
// check if we got back a 200 from the request
if (this.status >= 200 && this.status <= 299)
{
// add the download url to an a tag and then click the a tag
// to download the document
var mimetype = (2 === 2) ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
var blob = new Blob([req.response],
{
type: mimetype
});
var dloadurl = (window.URL ? URL : webkitURL).createObjectURL(blob);
var a = document.createElement("a");
// if ie, because ie sucks
if (navigator.msSaveOrOpenBlob)
{
navigator.msSaveOrOpenBlob(blob, filename);
// else a browser that doesn't suck
}
else
{
document.body.appendChild(a);
a.style = "display: none";
a.href = dloadurl;
a.download = filename;
a.click();
URL.revokeObjectURL(dloadurl);
}
}
}
};
// compile the data to send with the request
var formdata = "exportType=MergeWordTemplate&selectedRecords=" + encodeURIComponent(JSON.stringify(entityid)) +
"&associatedentitytypecode=" + entitytypecode + "&TemplateId=" + templateid + "&templatetype=" + templatetype;
// make the request to create the template
req.send(formdata);
}
catch (err)
{
PrintError(err.message);
}
}
/*
* PrintError() is a helper method to display any errors to the user.
*/
function PrintError(msg)
{
Xrm.Page.ui.setFormNotification("An Error occurred generating the word document, please contact support if the issue persists. " + msg, "ERROR", "docerror");
}