How to Flatten Editable Fields in PDF using Go

PDF are fantastic for collecting information. They give structure to user input, making documents easier to read and process.

But what happens when you need to share a finalized PDF with flattened interactive fields? Maybe you want to prevent accidental changes or create a more streamlined, read-only version.

That’s where removing editable fields comes in, and UniPDF makes this process remarkably easy. Let’s explore how.

Why Flattening Editable PDF Fields?

Several scenarios might call for flattening editable fields from a PDF document:

  • Finalization: Once a form is filled out, you may want to lock in the content to prevent further modifications.
  • Distribution: If you’re sharing a PDF widely, removing editable fields streamlines the document and offers a cleaner presentation.
  • Security: In some cases, you might want to eliminate editable fields that contain sensitive information.
  • Data Conversion: If you need to extract data from a PDF form, removing the fields can make the process easier.

Introducing UniPDF:

UniPDF is a powerful PDF processing library designed for developers. Part of the broader UniDoc product suite, it offers an extensive range of features for manipulating PDF files within your applications.

Best Method to Flatten Editable Fields with UniPDF

UniPDF provides multiple ways to achieve this task. Flattening is the best method.

Flattening:

Flattening a PDF is a process that essentially converts all interactive elements and layers into static content. This includes form fields. Here’s how to flatten a PDF using UniPDF:

Opt for flattening if you want to remove all editable elements and create a completely non-interactive version of your PDF.

/*
 * Flatten form data in PDF files, moving to content stream from annotations, so cannot be edited.
 * Note: Works for forms that have been filled in an editor and have the appearance streams generated.
 *
 * Run as: go run pdf_form_flatten.go <outputdir> <pdf files...>
 */

package main

import (
    "fmt"
    "os"
    "path/filepath"
    "sort"

    "github.com/unidoc/unipdf/v3/annotator"
    "github.com/unidoc/unipdf/v3/common/license"
    "github.com/unidoc/unipdf/v3/model"
)

func init() {
    // Make sure to load your metered License API key prior to using the library.
    // If you need a key, you can sign up and create a free one at https://cloud.unidoc.io

    err := license.SetMeteredKey(os.Getenv(`UNIDOC_LICENSE_API_KEY`))
    if err != nil {
        panic(err)
    }
}



func main() {
    if len(os.Args) < 3 {
        fmt.Printf("Usage: go run pdf_form_flatten.go <outputdir> <input1.pdf> [input2.pdf] ...\n")
        os.Exit(1)
    }

    outputDir := os.Args[1]

    fails := map[string]string{}

    failKeys := []string{}

    processed := 0

    for i := 2; i < len(os.Args); i++ {
        inputPath := os.Args[i]
        name := filepath.Base(inputPath)
        outputPath := filepath.Join(outputDir, fmt.Sprintf("flattened_%s", name))

        err := flattenPdf(inputPath, outputPath)
        if err != nil {
            fmt.Printf("%s - Error: %v\n", inputPath, err)
            fails[inputPath] = err.Error()
            failKeys = append(failKeys, inputPath)
        }
        processed++
    }

    fmt.Printf("Total %d processed / %d failures\n", processed, len(failKeys))

    sort.Strings(failKeys)

    for _, k := range failKeys {
        fmt.Printf("%s: %v\n", k, fails[k])
    }
}

// flattenPdf flattens annotations and forms moving the appearance stream to the page contents so cannot be
// modified.

func flattenPdf(inputPath, outputPath string) error {
    f, err := os.Open(inputPath)
    if err != nil {
        return err
    }

    defer f.Close()

    pdfReader, err := model.NewPdfReader(f)
    if err != nil {
        return err
    }

    fieldAppearance := annotator.FieldAppearance{OnlyIfMissing: true}

    err = pdfReader.FlattenFields(true, fieldAppearance)
    if err != nil {
        return err
    }

    // AcroForm field is no longer needed.
    opt := &model.ReaderToWriterOpts{
        SkipAcroForm: true,
    }

    // Generate a PdfWriter instance from existing PdfReader.
    pdfWriter, err := pdfReader.ToWriter(opt)
    if err != nil {
        return err
    }

    // Write to file.
    err = pdfWriter.WriteToFile(outputPath)
    return err
}

Additional Considerations

  • Field Identification: it might be necessary to identify fields by name or type (field.T.String() in the example).
  • Partial Flattening: UniPDF offers advanced options for selectively flattening specific form fields if needed.

Step By Step Method

Now, let’s dive into the step-by-step process of removing editable fields using UniPDF:

To flatten PDF forms, you can follow a step-by-step process outlined in the provided code snippet using UniPDF. Here’s a breakdown of how you can fill and flatten PDF forms in a single step using UniPDF:

Prepare Input Data: Gather the necessary input data, such as the PDF form template, JSON file containing the data to fill into the form fields, and the desired output path for the flattened PDF.

Fill Fields: Use the fillFields function to load the data from the JSON file and populate the PDF form fields accordingly.

Flatten Form: After filling the form fields, the next step is to flatten the PDF form. This means that the form fields are rendered as part of the document content, making the data immutable and preventing further editing of the form fields. The pdfReader.FlattenFields() function is used for this purpose.

Generate Output PDF: Finally, generate the output PDF by writing the modified PDF content to a file using the pdfWriter.WriteToFile() function.

Here’s a summary of the key steps involved in flattening PDF forms using UniPDF:

  • Load Field Data: Load the field data from the JSON file.
  • Populate Form Fields: Use the loaded field data to fill in the PDF form fields.
  • Flatten Form Fields: Flatten the form fields to render them as part of the document content.
  • Generate Output PDF: Write the modified PDF content to a file, creating the flattened PDF form.

By following these steps, you can efficiently fill and flatten PDF forms in a single step using UniPDF, which is particularly useful for automating tasks such as collecting and processing orders, invoices, and other engagement documents. This streamlined approach improves operational efficiency and reduces the manual effort required for handling PDF forms.

Benefits of Using UniPDF for Flattening Editable Fields

UniPDF offers several advantages over alternative methods for removing editable fields from PDF documents:

  1. Efficiency: UniPDF’s intuitive interface and robust processing engine ensure that the removal process is quick and seamless, saving you time and effort.

  2. Accuracy: With UniPDF, you can trust that your documents will be handled with precision, preserving the original layout and formatting while removing editable fields.

  3. Versatility: In addition to removing editable fields, UniPDF offers a wide range of PDF manipulation features, making it a versatile tool for various document management tasks.

  4. Accessibility: Whether you’re using Windows or Mac, UniPDF provides a consistent user experience across different operating systems, ensuring accessibility for all users.

  5. Cost-effectiveness: UniPDF offers excellent value for money, providing advanced PDF manipulation capabilities at an affordable price point.

Get Started with UniPDF

Ready to try it yourself? Start by installing UniPDF. Then, experiment with the code examples above to tailor them to your specific PDF documents.