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

Question

Question

Save as PDF from Quick Fields

asked on January 5, 2018

Is there a way to save processed documents as PDF out of Quick Fields?

 

Is there a way to save scanned documents as PDF within the scanning function of the Laserfiche Desktop Client? Looks like everything is converting to Tiff. 

 

Thanks!

0 0

Replies

replied on January 5, 2018 Show version history

I don't believe Quick Fields can generate PDF documents at this time, however, I am doing this within a SDK script and it is not terribly complicated; however, you need to be mindful of server resources (primarily CPU in my experience) and workflow configuration (such as the script domain model).

Below is the code I am using to generate my PDFs. Note that I preserve both the PDF and the TIFF images on the document, and I apply variable compression quality to the PDF to control the size of the resulting files, which you may or may not need to do depending on what you are processing.

namespace WorkflowActivity.Scripting.GeneratePDF
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text;
    using System.IO;
    using Laserfiche.RepositoryAccess;
    using Laserfiche.DocumentServices;

    public class GeneratePDF : RAScriptClass102
    {
        protected override void Execute()
        {
            // Set variables for image size, text size, document size, and average bytes per page
            long imageSize = 0;
            long textSize = 0;
            long bytesPerPage = 0;
            int compression = 0;

            // Get and lock source document
            DocumentInfo doc = (DocumentInfo)this.BoundEntryInfo;
            doc.Lock(LockType.Exclusive);

            // Try to generate and attach PDF
            try{
                // Retrieve page count
                int pageCount = doc.PageCount;

                // Read values of each page
                PageInfoReader pageReader = doc.GetPageInfos();
                foreach (PageInfo page in pageReader){
                    // Track cumulative page and text sizes
                    // to determine what level of compression to apply
                    imageSize += page.ImageDataSize;
                    textSize += page.TextDataSize;
                }

                // Get average bytes per page
                bytesPerPage = imageSize/pageCount;

                // Initialize compression variables
                int minSize = 62500;
                int midSize = 250000;
                int maxSize = 1000000;

                // Evaluate average page size
                if (bytesPerPage < minSize){
                    // default for low-quality images
                    compression = 90;
                }
                else {
                    // low-to-medium quality images
                    if (bytesPerPage < midSize){
                        compression = 75;
                    }
                    else {
                        // medium-to-high quality images
                        if (bytesPerPage < maxSize){
                            compression = 50;
                        }
                        // high-quality images
                        else {
                            compression = 25;
                        }
                    }
                }

                // Initialize document export
                DocumentExporter dExp = new DocumentExporter();

                // Configure document exporter settings
                dExp.CompressionQuality = compression;
                dExp.IncludeAnnotations = true;
                dExp.BlackoutRedactions = true;
                dExp.PageFormat = DocumentPageFormat.Jpeg;

                // Set PDF export options to flatten annotations and include searchable text
                PdfExportOptions ExportOptions = PdfExportOptions.RenderAnnotationsAsImage | PdfExportOptions.IncludeText;

                // Initialize memory stream and export PDF
                MemoryStream ms = new MemoryStream();
                dExp.ExportPdf(doc, doc.AllPages, ExportOptions, ms);

                // Write PDF to document
                using(Stream eDocStream = doc.WriteEdoc("application/pdf",ms.ToArray().LongLength)){
                    eDocStream.Write(ms.ToArray(),0,ms.ToArray().Length);
                }

                // Update document extension and save changes
                doc.Extension = ".pdf";

                // Save changes
                doc.Save();
            }

            // Ensure tokens are always updated and document is always unlocked
            finally{
                // Confirm eDoc attached and get eDoc Size
                SetTokenValue("eDoc",doc.IsElectronicDocument);
                SetTokenValue("eDocSize",doc.ElecDocumentSize);
                SetTokenValue("imageSize",imageSize);
                SetTokenValue("textSize",textSize);
                SetTokenValue("Quality",compression);

                // Release document
                doc.Unlock();
                doc.Dispose();
            }
        }
    }
}

I call this script within my workflow, then evaluate the output tokens to confirm that the PDF was generated without errors and track various information.

Also note that I have a Try-Finally instead of a Try-Catch-Finally as I personally prefer to put the script activity in a Try-Catch in workflow to handle errors outside of the script for this particular process.

4 0
replied on January 5, 2018

I've done something similar, and it can be done with a lot less code if all you want to do is get one or more entries out as PDFs.

 

namespace WorkflowActivity.Scripting.SDKScripttoBriefcaseArchiveFolder
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text;
    using Laserfiche.RepositoryAccess;
    using Laserfiche.DocumentServices;

    /// <summary>
    /// Provides one or more methods that can be run when the workflow scripting activity is performed.
    /// </summary>
    public class Script1 : RAScriptClass102
    {
        /// <summary>
        /// This method is run when the activity is performed.
        /// </summary>
        protected override void Execute()
        {
            // RASession will get the Repository Access session
            try
            {
                //get the document info for the current entry
                DocumentInfo DI = (DocumentInfo)this.BoundEntryInfo;
                DocumentExporter DE = new DocumentExporter();
                //DE.IncludeAnnotations = true; // convert Laserfiche annotations into Adobe Acrobat annotations.
                DE.CompressionQuality = 25;
                DE.ExportPdf(DI, DI.AllPages, PdfExportOptions.IncludeText , "c:\\temp\\" + GetTokenValue("ForEachEntryFound_CurrentEntry_Name").ToString() + ".pdf");
            }
            catch (Exception ex)
            {
               throw new LaserficheRepositoryException ("Script threw exception", ex);
            }

        }
    }
}

This SDK script is used in a For Each Entry loop that gets a set of entries from a search. You could just as easily use it in a one activity script that does the export whenever a new document is created by Quick Fields. 

this.BoundEntryInfo is how you point a Workflow SDK script at the entry you choose in the script activity.

0 0
replied on January 5, 2018 Show version history

As I noted, the reason for the extra code is to apply variable compression quality.

Some lower quality images, such as faxes, can look unacceptably bad at 25% so I've found it is best evaluate documents individually and apply variable settings for optimal quality.

For example, exporting a 200 dpi black and white document at 25% vs 75% could make a significant difference in appearance with a negligible difference in size compared to what you would see in higher resolution and/or color images.

Also, as he mentioned in his post, he wants to store the documents as PDFs instead of TIFF rather than just export them out of Laserfiche, which is where the other additional parts of my code come into play.

3 0
replied on May 7, 2024

Thanks. Does this output the pdf inside the repository please?

0 0
replied on May 7, 2024

If you're referring to the code I provided, it writes the PDF back to the source entry as an Electronic File, so it would be in the repository and part of the same entry used to generate the PDF.

0 0
replied on May 7, 2024

that is awesome, thanks.

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

Sign in to reply to this post.