Convert Word to PDF in Dynamics 365 CE Online with Flow (Part 3)

Today I will show you how we can put the Flow we created in the previous part into action.

You should complete the workflow to Generate a Word document from a template in this post before we can proceed. Our goal is to convert the Word document to a PDF document and attach it to a Note.

First, in your custom workflow activity project, create a new custom workflow with following code snippet. I’m not going to explain it as you can understand easily when you have a closer look. You just need to pay attention to the “ConvertWordToPdf” method where we send request to our Flow. I put some comments there also.


public class MyCustomWorkflowActivity : CodeActivity
 {
 protected override void Execute(CodeActivityContext executionContext)
 {
 ITracingService tracer = executionContext.GetExtension();
 IWorkflowContext context = executionContext.GetExtension();
 IOrganizationServiceFactory serviceFactory = executionContext.GetExtension();
 IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

try
 {
 Entity entity = (Entity)context.InputParameters["Target"];

// Get the last note with word attachment generated from the previous step
 var wordNote = GetLastWordNote(service, context.PrimaryEntityId);

// send it to our Flow, convert it to pdf and attach to a note
 if (wordNote != null)
 {
 ConverToPdfNote(service, wordNote, context.PrimaryEntityId);
 }
 }
 catch (Exception e)
 {
 throw new InvalidPluginExecutionException(e.Message);
 }
 }

private Entity GetLastWordNote(IOrganizationService service, Guid targetId)
 {
 QueryExpression query= new QueryExpression("annotation")
 {
 ColumnSet = new ColumnSet(true),
 Criteria = new FilterExpression()
 {
 Conditions =
 {
 new ConditionExpression()
 {
 AttributeName="isdocument",
 Operator = ConditionOperator.Equal,
 Values = { true }
 },
 new ConditionExpression()
 {
 AttributeName = "objectid",
 Operator = ConditionOperator.Equal,
 Values = { targetId }
 }
 }
 },
 Orders = {
 new OrderExpression()
 {
 AttributeName = "createdon",
 OrderType = OrderType.Descending
 }
 }
 };

 // optional: filter for mimetype to make sure it is a word attachment
 var docFilter = query.Criteria.AddFilter(LogicalOperator.Or);
 docFilter.AddCondition("mimetype", ConditionOperator.Equal, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
 docFilter.AddCondition("mimetype", ConditionOperator.Equal, "application/octet-stream");

 var response = service.RetrieveMultiple(query);
 if (response.Entities.Count > 0)
 {
 return response.Entities.First();
 }

 return null;
 }

private void ConverToPdfNote(IOrganizationService service, Entity note, EntityReference targetRef)
 {
 var mime = note.Contains("mimetype") ? (string)note["mimetype"] : string.Empty;
 if (mime != "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
 && mime != "application/octet-stream")
 {
 throw new InvalidPluginExecutionException("Source file is an invalid Word format");
 }
 var fileName = note.Contains("filename") ? (string)note["filename"] : string.Empty;
 var noteData = note.Contains("documentbody") ? (string)note["documentbody"] : string.Empty;
 if (string.IsNullOrWhiteSpace(fileName) || string.IsNullOrWhiteSpace(noteData))
 {
 throw new InvalidPluginExecutionException("Source file is invalid");
 }

 try
 {
 // Send request to Flow
 var pdfData = ConvertWordToPdf(fileName, noteData);
 Entity pdfnote = new Entity("annotation");
 pdfnote["filename"] = fileName + ".pdf";
 pdfnote["documentbody"] = pdfData;
 pdfnote["mimetype"] = "application/pdf";
 pdfnote["objectid"] = targetRef;
 service.Create(pdfnote);
 }
 catch (Exception ex)
 {
 throw;
 }
 }

private static string ConvertWordToPdf(string filename, string base64word)
 {
 var result = string.Empty;
 var json = string.Format("{{'filename': '{0}', 'base64data': '{1}'}}", filename, base64word);

// TODO: store api url somewhere else
 var apiurl = "https://prod-02.southeastasia.logic.azure.com:443/workflows/";

try
 {
 using (WebClientEx client = new WebClientEx())
 {
 client.Timeout = 60000;
 client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
 client.Encoding = System.Text.Encoding.UTF8;
 result = client.UploadString(apiurl, json);
 }
 }
 catch (WebException exception)
 {
 string str = string.Empty;
 if (exception.Response != null)
 {
 using (StreamReader reader =
 new StreamReader(exception.Response.GetResponseStream()))
 {
 str = reader.ReadToEnd();
 }

exception.Response.Close();
 }

if (exception.Status == WebExceptionStatus.Timeout)
 {
 throw new InvalidPluginExecutionException("The timeout elapsed while attempting to issue the the PDF conversion request.", exception);
 }

throw new InvalidPluginExecutionException(string.Format("A Web exception occurred while attempting to issue the PDF conversion request. {0}: {1}", exception.Message, str), exception);
 }
 catch
 {
 throw new InvalidPluginExecutionException("Failed to convert to PDF");
 }

return result;
 }
 }
 public class WebClientEx : WebClient
 {
 public int Timeout { get; set; }

protected override WebRequest GetWebRequest(Uri address)
 {
 var request = (HttpWebRequest)base.GetWebRequest(address);
 request.Timeout = Timeout;
 // Keep-Alive set to true in the HTTP request header can cause delays upwards of 20+ seconds
 request.KeepAlive = false;
 return request;
 }
 }

Next, build and deploy the workflow to CRM.

Then, open CRM workflow to generate word document, and add a step to our custom workflow. I marked my workflow to be on-demand so I can test it easily with existing record.

wordtopdf

And check out the result. A new PDF note is created.

result.PNG

That’s it. hope it helps!

P/S: if you have any suggestion regarding converting Word to PDF online or on-premise, please let me know. Cheers!

 

2 thoughts on “Convert Word to PDF in Dynamics 365 CE Online with Flow (Part 3)

  1. Hi, Thanks for providing this very useful feature. I really apricate you. We tried to use this custom workflow and got an error. ConverToPdfNote(service, wordNote, context.PrimaryEntityId); and private void ConverToPdfNote(IOrganizationService service, Entity note, EntityReference targetRef) , Here 3rd parameter passing guid and receiving as entity reference. It gives error please let me know the detail.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s