We have a workflow where we are receiving employee documents back from a 3rd party service in a PDF byte array. How would we go about converting this byte array to a PDF to store into Laserfiche?
Question
Question
Answer
Something like this should work but I didn't have much time to test it:
string token = this.WorkflowApi.GetTokenValueFromNameAsString("HTTPWebRequest_Content File", 1); string base64PDF = null; using(StringReader stringReader = new StringReader(token)) { using(XmlReader reader = XmlReader.Create(stringReader)) { if(!reader.ReadToFollowing("GetFormAsPDF")) { this.WorkflowApi.TrackWarning("HTTP Response was not valid."); return; } base64PDF = reader.Value; } } this.SetTokenValue("Base64PDF", base64PDF); byte[] pdfBytes = Convert.FromBase64String(base64PDF); DocumentInfo doc = this.BoundEntryInfo as DocumentInfo; if (doc == null) { this.WorkflowApi.TrackWarning("Entry was not a document."); return; } using (Stream edocStream = doc.WriteEdoc("application/pdf", pdfBytes.Length)) { edocStream.Write(pdfBytes, 0, 0); } doc.Extension = ".pdf"; doc.Save();
Replies
Are you using the Http Request Activity? If so you can use the Attach E-doc activity if the web service is returning the PDF document as the response.
We are using the HTTP Request activity. We will give it a try. Thank you!
So if my Web Request reply looks like this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <GetFormAsPDF p1:type="Edm.Binary" xmlns:p1="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">JVBERi0xLjANCjEgMCBvYmoNCjw8DQovVHlwZSAvQ2F0YWxvZw0KL1BhZ2VzIDMgMCBSDQovT3V0bGluZXMgMiAwIFINCi9QYWdlTW9kZSAvVXNlT3V0bGluZXMNCi9QYWdlTGF5b3V0IC9PbmVDb2x1bW4NCj4+DQplbmRvYmoNCiUlIEZvckFwcE5vJSUgVGl0bGVTdHJpbmc6IEhlYWx0aCBJbnN1cmFuY2UgTWFya2V0IFBsYWNlIENvdmVyYWdlIC==</GetFormAsPDF>
Do I need to extract just the data in between the GetFormAsPDF tags?
You have to extract the string and decode it from Base 64.
Unfortunately that is outside what Attach e-doc can support at this time.
You'll want to use a script and the Convert.FromBase64String function to get a byte[] that you put into your e-doc stream.
Has anyone created a script like what Ed is referring to that would be willing to share their work?
Something like this should work but I didn't have much time to test it:
string token = this.WorkflowApi.GetTokenValueFromNameAsString("HTTPWebRequest_Content File", 1); string base64PDF = null; using(StringReader stringReader = new StringReader(token)) { using(XmlReader reader = XmlReader.Create(stringReader)) { if(!reader.ReadToFollowing("GetFormAsPDF")) { this.WorkflowApi.TrackWarning("HTTP Response was not valid."); return; } base64PDF = reader.Value; } } this.SetTokenValue("Base64PDF", base64PDF); byte[] pdfBytes = Convert.FromBase64String(base64PDF); DocumentInfo doc = this.BoundEntryInfo as DocumentInfo; if (doc == null) { this.WorkflowApi.TrackWarning("Entry was not a document."); return; } using (Stream edocStream = doc.WriteEdoc("application/pdf", pdfBytes.Length)) { edocStream.Write(pdfBytes, 0, 0); } doc.Extension = ".pdf"; doc.Save();
Ed, so would I do something like the following:
When I try to tell the Attach PDF Form activity to Attach a file from the "EForm to PDF Request from Applitrack" activity, the script is not available to select from. How would I accomplish that?
You shouldn't need the attach pdf form activity in this sample since the script is doing that work already.
Ed, when I try add the Script activity and then add what you posted into the Script Editor where it says 'Write your code here, it gives me a bunch of errors when I hover over the exclamation point. Am I supposed to be entering what you posted a different way into the script activity?
Also, how to I do I tell the script to process the byte array that is returned from the "EForm to PDF Request from Applitrack" activity? Here is a screenshot of what I have currently:
What do the errors say? Stuff like "'String' is a class type and cannot be used as an expression."?
Ed's code was in C#, your activity seems to be using VB.NET.
I switched it to C# and that seems to have gotten rid of some of the error messages, but now I am seeing things like "namespace stringready could not be found" or "namespace xmlreader could not be found".
Add a reference to System.IO to your script. Then at the top in the using statements, add
using System.IO; using System.Xml;
That got rid of most of the errors. I now have 3 left.
The script above assumes WF 9.1.1. Are you running 9.0.2 or lower?
No, we are running the latest version of 9.2.
We got the errors figured out. We were not using the SDK script activity. A couple of other questions on this though. Does the script attach the PDF to the entry created in the "Create Entry" step of the workflow or do I need to change something for that to happen?
Lines 27-33 save the PDF to the Laserfiche doc.
The code that Ed provided will import the PDF into the Document Entry you set the Script activity to run against. You can see that on line 20:
DocumentInfo doc = this.BoundEntryInfo as DocumentInfo;
Thanks Bert!
Hey Ed,
Could you give some more insight on how this script should be written? We have limited knowledge in this process and any help would be appreciated!
Thanks!
You should make the script a C# script, it looks like in the workflow you have it set to a visual basic script.That's assuming you copied ed's code which is C#.
Edit - didn't see the reply that pointed this out, disregard.
Thank you everyone for the help. Below is the completed Workflow we came up with for our needs based on the feedback here:
And below are the contents of the SDK Script:
namespace WorkflowActivity.Scripting.SDKScript { using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.SqlClient; using System.Text; using System.IO; using System.Xml; using Laserfiche.RepositoryAccess; /// <summary> /// Provides one or more methods that can be run when the workflow scripting activity is performed. /// </summary> public class Script1 : RAScriptClass92 { /// <summary> /// This method is run when the activity is performed. /// </summary> protected override void Execute() { string token = this.WorkflowApi.GetTokenValueFromNameAsString("EFormtoPDFRequestfromApplitrack_Content", 0); //var token2 = GetTokenValue("EFormtoPDFRequestfromApplitrack_Content File"); // string token = this.WorkflowApi.GetTokenValueFromNameAsString("HTTPWebRequest_Content File", 1); string base64PDF = null; using(StringReader stringReader = new StringReader(token)) { using(XmlReader reader = XmlReader.Create(stringReader)) { if(!reader.ReadToFollowing("GetFormAsPDF")) { this.WorkflowApi.TrackWarning("HTTP Response was not valid."); return; } base64PDF = reader.ReadElementContentAsString("GetFormAsPDF", "http://schemas.microsoft.com/ado/2007/08/dataservices"); } } this.SetTokenValue("Base64PDF", base64PDF); byte[] pdfBytes = Convert.FromBase64String(base64PDF); DocumentInfo doc = this.BoundEntryInfo as DocumentInfo; if (doc == null) { this.WorkflowApi.TrackWarning("Entry was not a document."); return; } using (Stream edocStream = doc.WriteEdoc("application/pdf", pdfBytes.Length)) { edocStream.Write(pdfBytes, 0, pdfBytes.Length); } doc.Extension = ".pdf"; doc.Save(); } } }
I hope it helps someone.
Hii all ,
we are reading a PDF File in byte array format through HTTP Web Service in our Workflow.
Aspx .
We need to retrieve the PDF Contents now through our SDK Script.
How can we do the same?? Thanks for your help.
namespace WorkflowActivity.Scripting.SDKScript { using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.SqlClient; using System.Text; using System.IO; using System.Xml; using Laserfiche.RepositoryAccess; /// <summary> /// Provides one or more methods that can be run when the workflow scripting activity is performed. /// </summary> public class Script1 : RAScriptClass92 { /// <summary> /// This method is run when the activity is performed. /// </summary> protected override void Execute() { string token = this.WorkflowApi.GetTokenValueFromNameAsString("EFormtoPDFRequestfromApplitrack_Content", 0); //var token2 = GetTokenValue("EFormtoPDFRequestfromApplitrack_Content File"); // string token = this.WorkflowApi.GetTokenValueFromNameAsString("HTTPWebRequest_Content File", 1); string base64PDF = null; using(StringReader stringReader = new StringReader(token)) { using(XmlReader reader = XmlReader.Create(stringReader)) { if(!reader.ReadToFollowing("GetFormAsPDF")) { this.WorkflowApi.TrackWarning("HTTP Response was not valid."); return; } base64PDF = reader.ReadElementContentAsString("GetFormAsPDF", "http://schemas.microsoft.com/ado/2007/08/dataservices"); } } this.SetTokenValue("Base64PDF", base64PDF); byte[] pdfBytes = Convert.FromBase64String(base64PDF); DocumentInfo doc = this.BoundEntryInfo as DocumentInfo; if (doc == null) { this.WorkflowApi.TrackWarning("Entry was not a document."); return; } using (Stream edocStream = doc.WriteEdoc("application/pdf", pdfBytes.Length)) { edocStream.Write(pdfBytes, 0, pdfBytes.Length); } doc.Extension = ".pdf"; doc.Save(); } } }
To send data across the web, it needs to be converted to a string. You will notice in the code sample provided by Ed that he is loading the received data into a string object and then generating a byte array using Convert.FromBase64String:
string base64PDF = null; ... byte[] pdfBytes = Convert.FromBase64String(base64PDF);
So in your code to send the PDF, you must convert your byte array into a Base64String and then send the string to the requester.