In this article I will explain how to generate a PDF document of a Word Template using the C# CRM API. It is very simple. First create or take an existing Word Template in CRM:
Take the Word Template name and the entity logical name related. Here is the code:
NOTE: To use this, you need to run the following Nuget to use the CRM API:
Install-Package Microsoft.CrmSdk.XrmTooling.CoreAssembly
1. public byte[] GeneratePDFFromWordTemplate(Guid? wordTemplateId, string wordTemplateName, int? entityTypeCode, string entityName, Guid entityId)
2. {
3. // Get the Entity Type code if not known
4. if (entityTypeCode == null)
5. {
6. entityTypeCode = GetObjectTypeCodeOfEntity(entityName);
7. }
8.
9. // Get the Word Template ID if not known
10. if (wordTemplateId == null)
11. {
12. wordTemplateId = GetWordTemplateID(service, entityTypeCode, wordTemplateName);
13. }
14.
15. // Instance the Organization Request with the attributes to generate the PDF
16. OrganizationRequest exportPdfAction = new OrganizationRequest("ExportPdfDocument");
17.
18. exportPdfAction["EntityTypeCode"] = entityTypeCode;
19. exportPdfAction["SelectedTemplate"] = new EntityReference("documenttemplate", (Guid)wordTemplateId);
20. exportPdfAction["SelectedRecords"] = "[\'{" + entityId + "}\']";
21.
22. OrganizationResponse convertPdfResponse = (OrganizationResponse)service.Execute(exportPdfAction);
23.
24. return convertPdfResponse["PdfFile"] as byte[];
25. }
This function will return a byte array of the PDF file generated. Here step by step:
-First, if the entity type code is not specified by parameter, the code will query the entity type code of the entity related, for example “account”. This is because if you are using a custom entity, the type code will change in the different environments where your solution is imported. But if you are using a system entity like “account”, will be the same so is not necessary to call this function.
-Then the code will query the Word Template ID, if this id is not specified by parameter, by the Template Name and Entity Type Code retrieved in the previous step (or taking the parameter if is specified).
-The code will generate the Organization Request to CRM using “ExportPdfDocument” action request type and will fill its attributes with the Entity Type Code, the Word Template ID and the record ID.
-Finally, the code executes the Organization Request returning the byte array of the PDF generated in the “PdfFile” attribute of the response. Then use this byte array to accomplish your objective like save the file in disk or generate a download in your web app.
-If you need the code to retrieve the Word Template ID by name, here it is:
1. private Guid GetWordTemplateID(IOrganizationService service, int? entityTypeCode, string wordTemplateName)
2. {
3. QueryExpression query = new QueryExpression("documenttemplate");
4. query.ColumnSet.AddColumns("name", "associatedentitytypecode");
5. query.Criteria.AddCondition("name", ConditionOperator.Equal, wordTemplateName);
6. query.Criteria.AddCondition("associatedentitytypecode", ConditionOperator.Equal, (int)entityTypeCode);
7.
8. EntityCollection templates = service.RetrieveMultiple(query);
9.
10. if (templates.Entities.Count == 0)
11. {
12. throw new Exception($"No template found with name {wordTemplateName}");
13. }
14. if (templates.Entities.Count > 1)
15. {
16. throw new Exception($"More than one template found with name {wordTemplateName}");
17. }
18. return templates.Entities[0].Id;
19. }
-And if you need the code to retrieve the Entity Type Code by the Entity Logical name, here it is:
1. public int GetObjectTypeCodeOfEntity(string entityName)
2. {
3. RetrieveEntityRequest retrieveEntityRequest = new RetrieveEntityRequest
4. {
5. EntityFilters = EntityFilters.Entity,
6. LogicalName = entityName
7. };
8.
9. RetrieveEntityResponse retrieveAccountEntityResponse = (RetrieveEntityResponse)service.Execute(retrieveEntityRequest);
10. EntityMetadata AccountEntity = retrieveAccountEntityResponse.EntityMetadata;
11.
12. return (int)retrieveAccountEntityResponse.EntityMetadata.ObjectTypeCode;
13. }
Enjoy it!