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

Discussion

Discussion

Workflow to Export Document to Windows Folder

posted on October 17, 2018 Show version history

There have been a lot of questions about using a workflow to export Document(s) to a Windows folder.  I will show a script that will handle almost any export need.  It has a lot of checks built into functions, so it may look a little complicated, but I find that building in smaller functions and calling into them makes it easier to both develop and trouble shoot.

The Workflow I will show runs a search for documents and then loops through each found Document and exports it.  Here is the Flow:

You can see that in the Assign Token activity, I have a token to specify to export image documents as PDF and another token to specify the windows destination folder.

Use a SDK Script activity and set the Script Language to C# .net and the Script's Default Entry to the For Each Entry - Current Entry.  Then open the script editor and add a reference to the Laserfiche.DocumentServices and the corresponding "using" statement.

Then here is the whole of the script that I am starting with:

        protected override void Execute()
        {
            // Write your code here. The BoundEntryInfo property will access the entry, RASession will get the Repository Access session
            try
            {
                // Get Setting for Exporting Image Documents
                String sImageToPDF = (String)GetTokenValue("ExportImagesAsPDF");
                // Get Path to Windows Folder for Exports
                String exportFolder = (String)GetTokenValue("DestinationPath");
                // Ensure the Destination folder exists
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(exportFolder);
                if (!di.Exists)
                {
                    // Create missing folder(s)
                    di.Create();
                }
                // Only Export Documents
                if (IsEntryDocument(BoundEntryInfo))
                {
                    // Get DocumentInfo object
                    using (DocumentInfo doc = (DocumentInfo)BoundEntryInfo)
                    {
                        if (IsElectronicDocument(doc)) // Check if it is an electronic document
                        {
                            // Export the electronic Portion of the document
                            ExportElectronic(doc, exportFolder);
                        }
                        else if (HasImagePages(doc)) // Check for Image pages
                        {
                            if (sImageToPDF.ToLower() == "true")
                            {
                                // Export images to PDF
                                ExportImageDocumentToPDF(doc, exportFolder);
                            }
                            else
                            {
                                // Export images to TIFF
                                ExportImageDocument(doc, exportFolder);
                            }
                        }
                        else
                        {
                            if (HasText(doc)) // if it has Text
                            {
                                // Export text file
                                ExportTextDocument(doc, exportFolder);
                            }
                            else
                            {
                                ExportEmptyDocument(doc, exportFolder);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }

        }

        private void ExportEmptyDocument(DocumentInfo LFDoc, String sExportFolder)
        {
            try
            {
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sExportFolder);
                if (!di.Exists)
                {
                    di.Create();
                }
                String exportPath= System.IO.Path.Combine(sExportFolder, LFDoc.Name);
                System.IO.File.Create(exportPath).Dispose();
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }
        }

        private void ExportTextDocument(DocumentInfo LFDoc, String sExportFolder)
        {
            try
            {
                String sTxt = null;
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sExportFolder);
                if (!di.Exists)
                {
                    di.Create();
                }
                String exportPath= System.IO.Path.Combine(sExportFolder, LFDoc.Name + ".txt");
                using (PageInfoReader LF_PageInfos = LFDoc.GetPageInfos())
                {
                    foreach (PageInfo PI in LF_PageInfos)
                    {
                        if (PI.HasText)
                        {
                            using (System.IO.StreamReader reader = PI.ReadTextPagePart())
                            {
                                if (String.IsNullOrEmpty(sTxt))
                                {
                                    sTxt = reader.ReadToEnd();
                                }
                                else
                                {
                                    sTxt = sTxt + Environment.NewLine + reader.ReadToEnd();
                                }
                            }
                        }
                    }
                }
                using (System.IO.StreamWriter file = new System.IO.StreamWriter(exportPath))
                {
                    file.Write(sTxt);
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }
        }

        private void ExportImageDocument(DocumentInfo LFDoc, String sExportFolder)
        {
            try
            {
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sExportFolder);
                if (!di.Exists)
                {
                    di.Create();
                }
                DocumentExporter docExporter = new DocumentExporter();
                docExporter.PageFormat = DocumentPageFormat.Tiff;
                String exportPath = System.IO.Path.Combine(sExportFolder, LFDoc.Name + ".tiff");
                docExporter.ExportPages(LFDoc, GetImagePageSet(LFDoc), exportPath);
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }
        }

        private void ExportImageDocumentToPDF(DocumentInfo LFDoc, String sExportFolder)
        {
            try
            {
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sExportFolder);
                if (!di.Exists)
                {
                    di.Create();
                }
                DocumentExporter docExporter = new DocumentExporter();
                String exportPath = System.IO.Path.Combine(sExportFolder, LFDoc.Name + ".pdf");
                docExporter.ExportPdf(LFDoc, GetImagePageSet(LFDoc), PdfExportOptions.None, exportPath);
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }
        }

        private void ExportElectronic(DocumentInfo LFDoc, String sExportFolder)
        {
            try
            {
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sExportFolder);
                if (!di.Exists)
                {
                    di.Create();
                }
                DocumentExporter docExporter = new DocumentExporter();
                String exportPath = System.IO.Path.Combine(sExportFolder, LFDoc.Name + "." + LFDoc.Extension);
                docExporter.ExportElecDoc(LFDoc, exportPath);
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }
        }

        private PageSet GetImagePageSet(DocumentInfo LFDoc)
        {
            PageSet psReturn = new PageSet();
            try
            {
                using (PageInfoReader LF_PageInfos = (PageInfoReader)LFDoc.GetPageInfos())
                {
                    foreach (PageInfo PI in LF_PageInfos)
                    {
                        using (LaserficheReadStream lrs = PI.ReadPagePart(new PagePart()))
                        {
                            if (lrs.Length > 0)
                            {
                                psReturn.AddPage(PI.PageNumber);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
                psReturn = new PageSet();
            }
            return psReturn;
        }

        private Boolean HasText(DocumentInfo LFDoc)
        {
            Boolean bReturn = false;
            try
            {
                using (PageInfoReader LF_PageInfos = LFDoc.GetPageInfos())
                {
                    foreach (PageInfo PI in LF_PageInfos)
                    {
                        if (PI.HasText)
                        {
                            bReturn = true;
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
                bReturn = false;
            }
            return bReturn;
        }

        private Boolean HasImagePages(DocumentInfo LFDoc)
        {
            Boolean bReturn = false;
            try
            {
                using (PageInfoReader LF_PageInfos = LFDoc.GetPageInfos())
                {
                    foreach (PageInfo PI in LF_PageInfos)
                    {
                        using (LaserficheReadStream lrs = PI.ReadPagePart(new PagePart()))
                        {
                            if (lrs.Length > 0)
                            {
                                bReturn = true;
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
                bReturn = false;
            }
            return bReturn;
        }

        private Boolean IsElectronicDocument(DocumentInfo LFDoc)
        {
            Boolean bReturn = false;
            try
            {
                bReturn = LFDoc.IsElectronicDocument;
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
                bReturn = false;
            }
            return bReturn;
        }

        private Boolean IsEntryDocument(EntryInfo LFEnt)
        {
            Boolean bReturn = false;
            try
            {
                if (LFEnt.EntryType == EntryType.Document)
                {
                    bReturn = true;
                }
                else
                {
                    bReturn = false;
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
                bReturn = false;
            }
            return bReturn;
        }

Please feel free to reply with any improvements you might have.

10 0
replied on October 31

Greetings Bert!

This is awesome!

I was hoping you could help with a bit of example code.

I've done work with LFSO and VB but really struggling with C# and the RA Methods.

Would it be possible for someone to share some code to use a field from the documents as part of the filename?

 

I'm still hacking away at it, but I figured the community might be able to help.

Thanks in advance!

0 0
replied on October 31

After you install the Full SDK, browse to the Sample folder in the Install location (C:\Program Files\Laserfiche\SDK 10.2\Samples) and copy the "LfSDKNetSamples.zip" file out to your Documents folder and then extract it.  You will find folder "LfSDKNetSamples\VisualBasic\MetadataPrinter" with a sample VB file that shows how to read metadata from an entry.

If you still have questions after that, create a new question to ask about what you are having issues with. 

2 0
replied on October 31

Thanks - I'm on it!  

0 0
replied on October 14

When running this code, I'm getting "The given path's format is not supported".  The export path I'm using is C:\Temp\WFExport.  Any ideas as to why it would give this error?

0 0
replied on October 14 Show version history

How/where are you defining the path?  If you are defining it within the script, are you escaping the "\" characters?

 

What is the document name in Laserfiche?  Does the document name contain illegal windows file name characters?  If so you will need to do string.replace on the name to replace the illegal characters before trying to export the document.  The windows file name cannot contain any of these:

/ \ : * ? " < > |

 

2 0
replied on October 14

Bert, you nailed it.  The document I was trying to export had a date/time stamp, so it had slashes and colons in it.  I removed them and it worked perfectly.  Thanks!

0 0
replied on October 14

Here is updated code that will replace the illegal characters in the name with an underscore.

        protected override void Execute()
        {
            // Write your code here. The BoundEntryInfo property will access the entry, RASession will get the Repository Access session
            try
            {
                // Get Setting for Exporting Image Documents
                String sImageToPDF = (String)GetTokenValue("ExportImagesAsPDF");
                // Get Path to Windows Folder for Exports
                String exportFolder = (String)GetTokenValue("DestinationPath");
                // Ensure the Destination folder exists
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(exportFolder);
                if (!di.Exists)
                {
                    // Create missing folder(s)
                    di.Create();
                }
                // Only Export Documents
                if (IsEntryDocument(BoundEntryInfo))
                {
                    // Get DocumentInfo object
                    using (DocumentInfo doc = (DocumentInfo)BoundEntryInfo)
                    {
                        if (IsElectronicDocument(doc)) // Check if it is an electronic document
                        {
                            // Export the electronic Portion of the document
                            ExportElectronic(doc, exportFolder);
                        }
                        else if (HasImagePages(doc)) // Check for Image pages
                        {
                            if (sImageToPDF.ToLower() == "true")
                            {
                                // Export images to PDF
                                ExportImageDocumentToPDF(doc, exportFolder);
                            }
                            else
                            {
                                // Export images to TIFF
                                ExportImageDocument(doc, exportFolder);
                            }
                        }
                        else
                        {
                            if (HasText(doc)) // if it has Text
                            {
                                // Export text file
                                ExportTextDocument(doc, exportFolder);
                            }
                            else
                            {
                                ExportEmptyDocument(doc, exportFolder);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }
        
        }
        
        private void ExportEmptyDocument(DocumentInfo LFDoc, String sExportFolder)
        {
            try
            {
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sExportFolder);
                if (!di.Exists)
                {
                    di.Create();
                }
                String exportPath= System.IO.Path.Combine(sExportFolder, WindowsFileName(LFDoc.Name));
                System.IO.File.Create(exportPath).Dispose();
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }
        }
        
        private void ExportTextDocument(DocumentInfo LFDoc, String sExportFolder)
        {
            try
            {
                String sTxt = null;
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sExportFolder);
                if (!di.Exists)
                {
                    di.Create();
                }
                String exportPath= System.IO.Path.Combine(sExportFolder, WindowsFileName(LFDoc.Name) + ".txt");
                using (PageInfoReader LF_PageInfos = LFDoc.GetPageInfos())
                {
                    foreach (PageInfo PI in LF_PageInfos)
                    {
                        if (PI.HasText)
                        {
                            using (System.IO.StreamReader reader = PI.ReadTextPagePart())
                            {
                                if (String.IsNullOrEmpty(sTxt))
                                {
                                    sTxt = reader.ReadToEnd();
                                }
                                else
                                {
                                    sTxt = sTxt + Environment.NewLine + reader.ReadToEnd();
                                }
                            }
                        }
                    }
                }
                using (System.IO.StreamWriter file = new System.IO.StreamWriter(exportPath))
                {
                    file.Write(sTxt);
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }
        }
        
        private void ExportImageDocument(DocumentInfo LFDoc, String sExportFolder)
        {
            try
            {
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sExportFolder);
                if (!di.Exists)
                {
                    di.Create();
                }
                DocumentExporter docExporter = new DocumentExporter();
                docExporter.PageFormat = DocumentPageFormat.Tiff;
                String exportPath = System.IO.Path.Combine(sExportFolder, WindowsFileName(LFDoc.Name) + ".tiff");
                docExporter.ExportPages(LFDoc, GetImagePageSet(LFDoc), exportPath);
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }
        }
        
        private void ExportImageDocumentToPDF(DocumentInfo LFDoc, String sExportFolder)
        {
            try
            {
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sExportFolder);
                if (!di.Exists)
                {
                    di.Create();
                }
                DocumentExporter docExporter = new DocumentExporter();
                String exportPath = System.IO.Path.Combine(sExportFolder, WindowsFileName(LFDoc.Name) + ".pdf");
                docExporter.ExportPdf(LFDoc, GetImagePageSet(LFDoc), PdfExportOptions.None, exportPath);
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }
        }
        
        private void ExportElectronic(DocumentInfo LFDoc, String sExportFolder)
        {
            try
            {
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sExportFolder);
                if (!di.Exists)
                {
                    di.Create();
                }
                DocumentExporter docExporter = new DocumentExporter();
                String exportPath = System.IO.Path.Combine(sExportFolder, WindowsFileName(LFDoc.Name) + "." + LFDoc.Extension);
                docExporter.ExportElecDoc(LFDoc, exportPath);
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
            }
        }
        
        private PageSet GetImagePageSet(DocumentInfo LFDoc)
        {
            PageSet psReturn = new PageSet();
            try
            {
                using (PageInfoReader LF_PageInfos = (PageInfoReader)LFDoc.GetPageInfos())
                {
                    foreach (PageInfo PI in LF_PageInfos)
                    {
                        using (LaserficheReadStream lrs = PI.ReadPagePart(new PagePart()))
                        {
                            if (lrs.Length > 0)
                            {
                                psReturn.AddPage(PI.PageNumber);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
                psReturn = new PageSet();
            }
            return psReturn;
        }
        
        private Boolean HasText(DocumentInfo LFDoc)
        {
            Boolean bReturn = false;
            try
            {
                using (PageInfoReader LF_PageInfos = LFDoc.GetPageInfos())
                {
                    foreach (PageInfo PI in LF_PageInfos)
                    {
                        if (PI.HasText)
                        {
                            bReturn = true;
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
                bReturn = false;
            }
            return bReturn;
        }
        
        private Boolean HasImagePages(DocumentInfo LFDoc)
        {
            Boolean bReturn = false;
            try
            {
                using (PageInfoReader LF_PageInfos = LFDoc.GetPageInfos())
                {
                    foreach (PageInfo PI in LF_PageInfos)
                    {
                        using (LaserficheReadStream lrs = PI.ReadPagePart(new PagePart()))
                        {
                            if (lrs.Length > 0)
                            {
                                bReturn = true;
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
                bReturn = false;
            }
            return bReturn;
        }
        
        private Boolean IsElectronicDocument(DocumentInfo LFDoc)
        {
            Boolean bReturn = false;
            try
            {
                bReturn = LFDoc.IsElectronicDocument;
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
                bReturn = false;
            }
            return bReturn;
        }
        
        private Boolean IsEntryDocument(EntryInfo LFEnt)
        {
            Boolean bReturn = false;
            try
            {
                if (LFEnt.EntryType == EntryType.Document)
                {
                    bReturn = true;
                }
                else
                {
                    bReturn = false;
                }
            }
            catch (Exception ex)
            {
                WorkflowApi.TrackError(ex.Message);
                bReturn = false;
            }
            return bReturn;
        }
        
        private String WindowsFileName(String LFDocName)
        {
            String sReturn = LFDocName.Replace(@"/", "_");
            sReturn = sReturn.Replace(@"\", "_");
            sReturn = sReturn.Replace(@":", "_");
            sReturn = sReturn.Replace(@"*", "_");
            sReturn = sReturn.Replace(@"?", "_");
            sReturn = sReturn.Replace(@"""", "_");
            sReturn = sReturn.Replace(@"<", "_");
            sReturn = sReturn.Replace(@">", "_");
            sReturn = sReturn.Replace(@"|", "_");
            return sReturn;
        }

 

2 0
replied on October 15

Awesome.  Thanks!

0 0
replied on October 17, 2018 Show version history

The only thing that I'd add is that you need to make sure that the account that the Workflow service runs as has permissions to the destination directory. We have Workflow running as an AD account so that we can achieve this. There are also a variety of ways to do it in code.

3 0
replied on October 17, 2018

Excellent point.

This is a very big "gotcha" because, as many of you already know, when you run the code from the Designer it runs as the current user, not the service account.

I figured that out after I had a script that worked great in testing, but suddenly failed when I tried to publish and run it the workflow on the server.

1 0
replied on October 16 Show version history

Bert,

I am trying to write a .net program to export all the documents in a given folder in Laserfiche to a export folder.  I am not familiar with C#.  But looking at your code I am trying to figure out how you are getting  the documents?  I understand it checking the document for the type of document and exporting it a given location. 

I have been able to Connect using RA and Export a Single Document that I Choose.  But I want to export all the documents in that folder not just the one.  Any help would be much apprectiated.

Thanks

0 0
replied on October 16 Show version history

In the above sample, the document is coming from workflow.  To do this in a standalone program, you will need to create your own way of getting the document(s) to export.

You state that you want to export documents found in a specific folder in Laserfiche.  I would run a search and then add each returned entry id into a List(Of Integer) object.

    Private Function GetDocumentListByPath(ByVal sParentPath As String, ByRef RASess As Session) As List(Of Integer)
        Dim lstReturn As List(Of Integer) = New List(Of Integer)
        Dim SearchString As String = "({LF:Name=""*"", Type=""D""} & {LF:LOOKIN=""" & sParentPath & """})"
        If RASess IsNot Nothing Then
            Try
                ' Gets a search object from the repository.
                Using RASearch As Search = New Search(RASess)
                    ' Defines the word that the search will look for.
                    RASearch.Command = SearchString
                    ' Begins the search
                    RASearch.Run()
                    ' Create Search Settings Object
                    Dim settings As SearchListingSettings = New SearchListingSettings()
                    ' Add Entry ID colum to search settings
                    settings.AddColumn(SystemColumn.Id)
                    ' Create Search Results listing
                    Using srl As SearchResultListing = RASearch.GetResultListing(settings)
                        For Each SearchResult As EntryListingRow In srl
                            lstReturn.Add(SearchResult(SystemColumn.Id))
                        Next
                    End Using
                End Using
            Catch ex As Exception
                ' Log Error Message
                ' And clear return list
                lstReturn = New List(Of Integer)
            End Try
        End If
        Return lstReturn
    End Function

Then loop through each entry id in the list, getting the entry by id and exporting it.

 

EDIT:  Updated function with "Using" blocks to ensure the Search and ResultListing objects are properly closed and disposed of after they are no longer needed.

0 0
replied on October 21

Bert,

Thank you for all your help.  I was able to get all the documents in a folder to export.  I still need to tweek my code, because it isn't getting the documents in sub folders.  But I am getting close to what I need. 

Again Thank You!

 

0 0
replied on October 31

Bert,

I have an additional question if you could help.  I am able to extract documents, but I was informed that some of the documents have a tag (Sealed Document).  I was able to extract the documents with the Sealed Document Tag, but I need to extract the documents that don't have the Sealed Document Tag.  I know in Laserfiche using the Tag in the search you can select None to exclude documents with tags. That is what I need to do.  My Search string that gets only the documents with tags looks like this:

 

    Dim SearchString As String = "({LF:Name=""*"", Type=""D""} & {LF:LOOKIN=""" & sParentPath & """} & {LF:Tags=""Sealed Document""})"     
 

Your help would be greatly appreciated.  I have tried looking through the documentation but haven't found anything that helps.  

If there is a way to get the tag  from the document and exclude that from the export list that would be even better.

Thanks,

Gary Schreader

0 0
replied on November 4

You can exclude the documents with the Sealed Documents tag like this:

Dim SearchString As String = "({LF:Name=""*"", Type=""D""} & {LF:LOOKIN=""" & sParentPath & """}) - ({LF:Tags=""Sealed Document""})" 
0 0
replied on November 8

Bert,

Thank you, that is what I needed.  You have been very helpful and I am very greatful.

 

Thank you!

Gary

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

Sign in to reply to this post.