You are viewing limited content. For full access, please sign in.

Question

Question

How to convert PDF Byte Array into PDF document?

asked on May 12, 2014

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?

3 0

Answer

SELECTED ANSWER
replied on May 23, 2014

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();

 

2 0

Replies

replied on May 12, 2014

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. 

 

3 0
replied on May 12, 2014

We are using the HTTP Request activity. We will give it a try. Thank you!

1 0
replied on May 22, 2014

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?

1 0
replied on May 23, 2014

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. 

 

 

0 0
replied on May 23, 2014

Has anyone created a script like what Ed is referring to that would be willing to share their work?

1 0
SELECTED ANSWER
replied on May 23, 2014

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();

 

2 0
replied on August 1, 2014

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?

1 0
replied on August 1, 2014

You shouldn't need the attach pdf form activity in this sample since the script is doing that work already.

0 0
replied on October 22, 2014

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:

1 0
replied on October 22, 2014

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.

0 0
replied on October 23, 2014

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".

1 0
replied on October 23, 2014

Add a reference to System.IO to your script. Then at the top in the using statements, add

    using System.IO;
    using System.Xml;

 

0 0
replied on October 23, 2014

That got rid of most of the errors. I now have 3 left.

1 0
replied on October 24, 2014

The script above assumes WF 9.1.1. Are you running 9.0.2 or lower?

0 0
replied on October 27, 2014

No, we are running the latest version of 9.2.

1 0
replied on October 27, 2014

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?

1 0
replied on October 27, 2014

Lines 27-33 save the PDF to the Laserfiche doc.

1 0
replied on October 27, 2014

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;

 

0 0
replied on October 27, 2014

Thanks Bert!

1 0
replied on February 11, 2022

The code from @ed heaney didn't work out of the box but was very helpful in helping to create the pdf.  Here is his modified code that works for me.

The scenario is you are submitting a base64 string using the Rest web api RestWorkflowAPI.svc by calling a workflow.  The workflow in its simplest form just has the 1. Create entry and 2. SDK Script.  The SDK Script is bound to the output of the Create entry which creates the blank pdf file.  The script then will write to that file.

I am not sure why he was reading the base64 string with the xml reader.  If I am missing something, let me know.  In any case, this was tested and works.

protected override void Execute()
        {
            //pdffile is a param written from the webserver with the pdf string 
            string token = this.WorkflowApi.GetTokenValueFromNameAsString("pdffile", 1);
            //converts back to bytes
            byte[] pdfBytes = Convert.FromBase64String(token);
            //grab the create entry 
            DocumentInfo doc = this.BoundEntryInfo as DocumentInfo;
            if (doc == null)
            {
                this.WorkflowApi.TrackWarning("Entry was not a document.");
                return;
            }

            //write to the output entry of the created entry
            using (Stream edocStream = doc.WriteEdoc("application/pdf", pdfBytes.Length))
            {
                edocStream.Write(pdfBytes, 0, pdfBytes.Length); //changed 0 to pdfBytes.Length
            }

            doc.Extension = ".pdf";
            doc.Save();
        }

 

0 0
replied on June 24, 2022 Show version history

Anyway to write the bytes of an image to a native page? There seems to be no reference in Workflow for this kind of stuff. Just a list of functions.

0 0
replied on July 19, 2022 Show version history

Have you just tried changing the "applicant/pdf" to something like "applicant/tiff" or "applicant/jpg", whatever the convention is?

Then also change the extension from ".pdf" to the corresponding file extension.

So long as the image was converted from string to byte array after it gets passed through, it should work.  I think...but have not tested.

0 0
replied on July 19, 2022

First I tried changing doc.WriteEdoc to doc.WriteNdoc and the function did not exist. I can't write to an electronic document when I am trying to create a native document.

This is where I get confused, how did anyone figure all this out? Is there a guide somewhere I should be checking out?

0 0
replied on July 19, 2022

Chad,

You can't use document-level methods like doc.WriteEdoc because each page is a separate object and has to be updated directly.

First, create the page where you want the image to go, then use the PageInfo.WritePagePart() method to add your image.

This method accepts a byte array.

For example, something like this:

PageInfo newPage = doc.AppendPage();

using (Stream writer = newPage.WritePagePart(PagePart.Image, bytes.Length){
    writer.Write(bytes, 0, bytes.Length);
}

newPage.Save();

 

2 0
replied on July 19, 2022

Thank you! I thought it might be a whole different method but I can't seem to find any examples in the SDK Script activity. This is what I was looking for though!

0 0
replied on October 22, 2014

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!

1 0
replied on February 2, 2015 Show version history

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.

1 0
replied on September 2, 2022
Dear Blake,
Could you give me support with this suggested solution for importing documents in Laserfiche, I've been having problems for several days without finding a solution to this requirement.
I appreciate your support, I don't know if we can get in touch, my phone number is +51947285904 
A lot of thanks.
1 0
replied on July 7, 2022 Show version history

Hey Ed pleaseeee,

 

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!

I have for import a document (format: jpg, pdf) and i dont know step by step how Do this process.

Thanks a lot!

1 0
replied on July 26, 2022
Good Morning,
In my case I have an external url in which the document will be received within the parameters (blob format files), could you explain to me a guide on how I could do to achieve the objective of registering this information in the laserfiche database please, in Laserfiche API Cloud?
1 0
replied on October 23, 2014 Show version history

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.

0 0
replied on September 7, 2016

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();
        }
    }
}
0 0
replied on September 14, 2016

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.

0 0
You are not allowed to follow up in this post.

Sign in to reply to this post.