Saving Generated Documents to SharePoint
– 7 MinutesMicrosoft recently added functionality for one-click document generation to Dynamics 365. Although this is great functionality, it is a bit limited with regard to where it can save the generated document. Out of the box, we can add the SetWordTemplate action to a workflow, but that generates the document and saves it as an attachment to an annotation. What if you want to save it in SharePoint? We can accomplish this with a custom plugin.
Although Microsoft has added them to the online documentation, there are some actions available for us to call.
Action | Input Parameters | Output Parameters | ||
---|---|---|---|---|
Name | Type | Name | Type | |
ExportWordDocument | EntityTypeCode | Int32 | WordFile | Byte[] |
SelectedRecords | String | |||
SelectedTemplate | EntityReference | |||
UploadDocument | Content | Byte[] | *None* | |
OverwriteExisting | Boolean | |||
Entity | Entity | |||
ParentEntityReference | EntityReference |
First, let's create some extension methods that will help us call these undocumented commands to generate either a Word or an Excel document.
if (typeof BGuidinger == "undefined") {
BGuidinger = { __namespace: true };
}
if (typeof BGuidinger.Samples == "undefined") {
BGuidinger.Samples = { __namespace: true };
}
BGuidinger.Samples.Sdk = {
ExportWordDocument: function (templateId, entityType, entityId) {
this.EntityTypeCode = entityType;
this.SelectedRecords = "[ '{" + entityId + "}' ]";
this.SelectedTemplate = {
entityType: "documenttemplate",
id: templateId
};
this.getMetadata = function () {
return {
operationName: "ExportWordDocument",
operationType: 0,
parameterTypes: {
"EntityTypeCode": {
"typeName": "Edm.Int32",
"structuralProperty": 1
},
"SelectedRecords": {
"typeName": "Edm.String",
"structuralProperty": 1
},
"SelectedTemplate": {
"typeName": "mscrm.documenttemplate",
"structuralProperty": 5
}
}
};
};
},
UploadDocument: function (entityType, entityId, filename, content) {
this.Content = content;
this.OverwriteExisting = true;
this.Entity = {
entityType: 'sharepointdocument',
id: '00000000-0000-0000-0000-000000000000',
title: filename
};
this.ParentEntityReference = {
entityType: entityType,
id: entityId
};
this.getMetadata = function () {
return {
operationName: "UploadDocument",
operationType: 0,
parameterTypes: {
"Content": {
"typeName": "Edm.String",
"structuralProperty": 1
},
"OverwriteExisting": {
"typeName": "Edm.Boolean",
"structuralProperty": 1
},
"Entity": {
"typeName": "mscrm.sharepointdocument",
"structuralProperty": 5
},
"ParentEntityReference": {
"typeName": "mscrm.crmbaseentity",
"structuralProperty": 5
}
}
};
};
}
};
What's awesome about the UploadDocument action is we don't have to include a dependency on the SharePoint SDK (and deal with ILMerge...). This is the same action Dynamics 365 uses when you upload a document through the UI (check the network trace when you upload a document).