Unlock the Power of Direct PDF Editing with WebViewer 10.7

Flattening Dynamic XFA Forms to PDF Using Apryse Virtual Printer

By Apryse | 2023 Sep 05

Sanity Image
Read time

5 min

Introduction

Copied to clipboard

Flattening Dynamic XFA (XML Forms Architecture) forms to PDF involves converting interactive XFA forms into static PDF documents. There are several reasons why you might want to do this:

  1. Preserves Data: XFA forms with dynamic elements like calculations are "baked in," ensuring consistent appearance and data regardless of software.
  2. Enhances Compatibility: Flattening improves compatibility across various PDF viewers, including those not supporting XFA.
  3. Ensures Print Quality: Flattened PDFs maintain layout and data integrity when printed or shared, even without compatible software.
  4. Archives Accurately: Flattening aids archival by capturing the form's state, safeguarding data and appearance for future reference.
  5. Enhances Data Security: Prevents unauthorized changes by removing recipient manipulation of fields and calculations.
  6. Enables Offline Use: Flattening allows offline form to use by eliminating dependencies on external data or JavaScript.
  7. Meets Legal Standards: Compliance-driven industries benefit as static formats fulfill requirements for data consistency and adherence.
  8. Simplifies Distribution: Flattened PDFs are easily shared without worrying about recipient software compatibility or plugins.

Additionally, it’s important to note that Dynamic XFA forms have been deprecated in the latest PDF specification, which poses challenges when dealing with them programmatically. However, Apryse Virtual Printer capabilities for Windows can provide a solution. This guide will walk you through the step-by-step process of using Apryse Virtual Printer to flatten a substantial number of XFA forms to PDF.

Prerequisites

Copied to clipboard

Before we delve into the steps, make sure you have the following prerequisites in place:

  • Windows Operating System: The process relies on Windows OS.
  • Adobe Reader: Adobe Reader is the preferred software for handling deprecated XFA formats.
  • Apryse SDK: You need the Apryse SDK installed on your system, supporting any of the Windows-supported programming languages.
  • AprysePDFNet Virtual Printer: Make sure you have the PDFNet Virtual Printer installed. It can be downloaded from here.

Steps to Flatten Dynamic XFA Forms

Copied to clipboard

Follow these steps to programmatically flatten Dynamic XFA forms to PDF using PDFTron Virtual Printer:

Step 1: Printing XFA Forms

Acrobat Reader can be operated from the command line using the /t option. Here's the command to execute on the Windows command line:

# Assumes default installation directory

C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe /t C:\path\to\xfa\document.pdf "PDFTronPDFNet"

By default, this command generates an XPS file at:

C:\Users\%USERNAME%\AppData\Local\Temp\pdfnet.xps

To modify the output path, create a registry entry at:

HKEY_CURRENT_USER\SOFTWARE\PDFTron\PDFTronPDFNet\printto

with a value like

C:\my\output\path\pdfnet.xps

Step 2: Convert XPS to PDF

Use the PDFTron SDK to convert the XPS file generated in the previous step to a PDF format. Click here to be redirected to our guide for document conversion using Apryse SDK.

Step 3: Programmatic Batch Conversions

For batch conversions, follow these sub-steps:

a. Invoke ‘AcroRd32.exe’ in a similar manner as in Step 1, and use a built-in System IO method in your programming language to monitor the existence of the temporary XPS file.

b. Detect the print job starting and finishing using registry entries

HKEY_CURRENT_USER\SOFTWARE\PDFTron\PDFTronPDFNet\jobid’ and ‘HKEY_CURRENT_USER\SOFTWARE\PDFTron\PDFTronPDFNet\jobidComplete’.

c. Convert the generated XPS file to PDF using Apryse SDK using the link in step 2.

d. Delete the temporary XPS file after the conversion is complete.

Repeat these sub-steps for all XFA files you need to convert.

Sample Java Code

Here is a rough Java sample code to achieve this (please note the TODO for Production usage:

package pdftron; 

 

import java.io.File; 

import java.io.IOException; 

import java.io.InputStream; 

import java.nio.file.Files; 

import java.nio.file.Paths; 

 

import com.pdftron.common.PDFNetException; 

 

import com.pdftron.pdf.Convert; 

import com.pdftron.pdf.PDFDoc; 

import com.pdftron.pdf.PDFNet; 

import com.pdftron.sdf.SDFDoc; 

 

public class XFAtoPDF { 

  public XFAtoPDF() { 

    super(); 

  } 

 

  private static String checkForPdfnetXps(String pathToPdfnetXpsOutput) { 

    try { 

      InputStream is = Files.newInputStream(Paths.get(pathToPdfnetXpsOutput)); 

      return org.apache.commons.codec.digest.DigestUtils.md5Hex(is); 

    } catch (IOException e) { 

      // File doesn't exist or the program cannot read it 

      return ""; 

    } 

  } 

 

  public static void main(String[] args) throws PDFNetException, IOException, InterruptedException { 

    PDFNet.initialize("demo-key-goes-here"); 

    String[] filesToConvert = { 

      // List of XFA Documents 

    }; 

    final String tempXpsFile = "C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\pdfnet.xps"; 

    for (String filename: filesToConvert) { 

      String oldPdfnetXpsHash = checkForPdfnetXps(tempXpsFile); 

      if (!oldPdfnetXpsHash.equals("")) { 

        final File tempXpsFileObj = new File(tempXpsFile); 

        if (tempXpsFileObj.exists()) { 

          if (!tempXpsFileObj.delete()) {  

            System.err.println("Could not delete " + tempXpsFile); 

            System.err.println("Ending the conversion process."); 

            System.exit(1); 

          } 

        } 

      } 

      ProcessBuilder builder = new ProcessBuilder( 

        "C:\\Program Files (x86)\\Adobe\\Acrobat Reader DC\\Reader\\AcroRd32.exe", 

        "/t", 

        "\"C:\\path\\to\\" + filename + "\"", 

        "\"PDFTron PDFNet\"" 

      ); 

      builder.redirectErrorStream(true); 

      builder.start(); 

      String newPdfnetXpsHash = checkForPdfnetXps(tempXpsFile); 

      /** 

        * TODO Add a timeout on this, don't let it run indefinitely in-case the PDFNet Virtual Printer 

        * process didn't work 

        */ 

      while(oldPdfnetXpsHash.equals(newPdfnetXpsHash)) { 

        // Give the process some time to complete the print job 

        Thread.sleep(3000); 

        newPdfnetXpsHash = checkForPdfnetXps(tempXpsFile); 

      } 

      PDFDoc pdfDoc = new PDFDoc(); 

      Convert.toPdf(pdfDoc, tempXpsFile); 

      pdfDoc.save("C:\\path\\to\\output" + filename, SDFDoc.SaveMode.LINEARIZED, null); 

      final File tempXpsFileObj = new File(tempXpsFile); 

      if (tempXpsFileObj.exists()) { 

        if (!tempXpsFileObj.delete()) {  

          System.err.println("Could not delete " + tempXpsFile); 

          System.err.println("Ending the conversion process."); 

          System.exit(1); 

          } 

      } 

    } 

  } 

} 

Remember that this code is a starting point, and you should adapt it to your specific use case, handling errors, timeouts, and other scenarios as needed.

Why Installer Executable is a Better Choice for Virtual Printer

Copied to clipboard

When it comes to installing the virtual printer, we recommend utilizing the installer executable. There are several compelling reasons for this choice:

  • Simplicity of Installation: Our virtual printer only needs to be installed once on the computer, akin to any other type of printer, virtual or physical.
  • Bitness Compatibility: It's crucial for the bitness of the printer to match the operating system's. By opting for the executable installer, you circumvent the need to write complex installation code. Your focus can instead shift towards double-checking the installation status.
  • Decoupling Application Bitness: Utilizing the installer executable allows your application to remain independent of the printer's bitness. This decoupling is advantageous for your application's stability and future updates.

Regarding the process of testing, you can replicate a similar procedure as outlined below:

Verify the absence of the target file:

$ ls C:\Users\%USERNAME%\AppData\Local\Temp\pdfnet.xps

ls: cannot access 'C:\Users\Correy\AppData\Local\Temp\pdfnet.xps': No such file or directory

Employ Adobe Acrobat Reader's command-line functionality to print the PDF using the virtual printer:

$ "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" /t C:\Users\Correy\Desktop\mypdf.pdf "PDFTronPDFNet"

Adobe Reader will then automate the process of opening the PDF file accordingly.

After the operation, you should observe the presence of the designated file:

$ ls C:\Users\%USERNAME%\AppData\Local\Temp\pdfnet.xps

'C:\Users\Correy\AppData\Local\Temp\pdfnet.xps'

For more detailed assistance or to set up a call for further guidance, you can access the Apryse support page here and include the link to this specific topic in your submission. We're dedicated to helping you achieve successful outcomes with Apryse world-renowned PDF SDK library across various platforms, including web, mobile, server, and desktop.

Frequently Asked Questions

Copied to clipboard

What is the Difference Between Flatten and Compress PDF?

Flatten PDF: Flattening a PDF refers to the process of converting all dynamic or interactive elements within the PDF, such as form fields, annotations, layers, and transparency effects, into a static image or content. This results in a PDF where these elements are no longer editable or interactive, but instead, they become part of the main document's content.

Compress PDF: Compressing a PDF involves reducing the file size of the PDF document by employing various techniques. These techniques include removing unnecessary metadata, down sampling images, using more efficient compression algorithms, and eliminating redundant data. Compression aims to maintain the overall structure and content of the PDF while making it more manageable in terms of file size. Unlike flattening, compression does not impact the interactivity or editability of the document's elements.

What Does it Mean to Flatten a PDF?

Flattening a PDF is particularly useful when you want to preserve the visual appearance of a document with interactive elements (such as form fields, annotations, or layers) but remove their interactivity. This is often done to ensure that the document's appearance remains consistent across different PDF viewers or when printing, while preventing unintended changes to interactive elements. Flattening is commonly used for documents that need to be shared or printed in a static format, where the original interactive elements are no longer necessary.

Do I Need to Flatten a PDF to Print?

Flattening and Printing: Whether you need to flatten a PDF before printing depends on the nature of the PDF and the printing process you are using. In some cases, printing software or devices might handle interactive elements well, and flattening might not be necessary. However, if you're experiencing issues with interactive elements not displaying correctly or if you want to ensure that the printed output matches what you see on your screen, flattening the PDF before printing is a good practice. Flattening eliminates the possibility of unexpected changes during the printing process, providing more predictable results.

Sanity Image

Apryse

Share this post

email
linkedIn
twitter