How to Create Interactive PDF Forms with Golang PDF Library

In today’s digital world, interactive PDF forms have become an essential tool for collecting data and streamlining workflows. With the help of Golang PDF Library, creating interactive PDF forms has never been easier. In this blog post, we will guide you through the process of using Golang PDF Library to create dynamic and user-friendly PDF forms. So let’s dive in!

1. Getting Started with Golang PDF Library

Before we jump into creating interactive PDF forms, it is important to set up Golang PDF Library on your machine. Follow these steps to get started:

  1. Install Golang PDF Library by running the appropriate command in your terminal.
  2. Import the library into your Go project.
  3. Initialize a new PDF document using the library.

Once you have completed these initial steps, you are ready to start building your interactive PDF form.

Setting Up the Environment

Before we begin creating interactive PDF forms, let’s ensure we have the required environment set up:

  • Install Golang on your machine.
  • Create a new Golang project directory.
  • Install the “UniPDF” library.
mkdir golang_project
cd golang_project
go mod init interactive_form
go mod tidy
go get github.com/unidoc/unipdf/v3/...

Creating a Simple PDF Document

Let’s start by creating a basic PDF document using the “UniPDF” library:

Adding Form Fields

To create an interactive PDF form, we can utilize the “UniPDF” library. This powerful tool enables us to incorporate various form fields that users can conveniently fill in. With the help of this library, we can add text fields, checkboxes, radio buttons, and other essential form elements to enhance the interactivity of our PDF forms.

By leveraging the capabilities of “UniPDF”, we can create dynamic and user-friendly forms that cater to the specific needs of our audience. Whether it’s capturing user information, collecting feedback, or conducting surveys, the “UniPDF” library empowers us to design and implement interactive PDF forms with ease.

Adding Form Fields

In this example, the structure is created and then the fields are added to make it interactive. There is only one checkbox, and the rest of the fields are text. The code:

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/unidoc/unipdf/v3/common/license"
    "github.com/unidoc/unipdf/v3/creator"
)

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() {
    c := creator.New()
    ch := c.NewChapter("Introduction")
    p := c.NewParagraph("This chapter creates a form to later teach UniDoc's functionality in creating interactive forms.")
    p.SetMargins(0, 0, 10, 0)
    ch.Add(p)

    p = c.NewParagraph("Full Name:")
    p.SetMargins(5, 0, 62, 0)
    ch.Add(p)

    p = c.NewParagraph("Address Line 1:")
    p.SetMargins(5, 0, 12, 0)
    ch.Add(p)

    p = c.NewParagraph("Address Line 2:")
    p.SetMargins(5, 0, 12, 0)
    ch.Add(p)

    p = c.NewParagraph("Age:")
    p.SetMargins(5, 0, 12, 0)
    ch.Add(p)

    p = c.NewParagraph("Gender:          Male         Female")
    p.SetMargins(5, 0, 16, 0)
    ch.Add(p)

    p = c.NewParagraph("City:")
    p.SetMargins(5, 0, 10, 0)
    ch.Add(p)

    p = c.NewParagraph("Country:")
    p.SetMargins(5, 0, 12, 0)
    ch.Add(p)

    p = c.NewParagraph("Favorite Color:")
    p.SetMargins(5, 0, 12, 0)
    ch.Add(p)

    c.Draw(ch)

    err := c.WriteToFile("template.pdf")
    if err != nil {
        log.Fatalf("Error saving PDF: %v", err)
    }

    fmt.Println("Simple PDF generated successfully.")
}

2. Designing Your PDF Form

To create an engaging and user-friendly form, design plays a crucial role. Follow these best practices when designing your PDF form:

  • Keep the layout clean and organized to improve readability.
  • Use clear labels for form fields to provide explicit instructions.
  • Group related fields together to enhance user experience.
  • Incorporate visually appealing elements such as checkboxes, drop-down menus, and radio buttons to make the form interactive.
  • Test the form on different devices and screen sizes to ensure responsiveness.

Remember, a well-designed form can significantly enhance user engagement and increase the conversion rate.

3. Adding Interactivity to Your Form

Now that you have designed the structure of your PDF form, it’s time to make it interactive using Golang PDF Library. Here are the steps to follow:

  • Define form fields: Start by identifying the form fields you want to include, such as text fields, checkboxes, or radio buttons. Assign unique names to each field to distinguish them in the code.

  • Add form fields: Use Golang PDF Library’s functions to add the desired form fields to your PDF document. Specify properties such as field type, dimensions, and position.

  • Set field actions: Define the actions or behaviors associated with each form field. For instance, you can specify that a checkbox should trigger the visibility of another field when selected.

  • Customize appearance: Modify the appearance of form fields by changing colors, fonts, or borders to match your branding.

By incorporating these interactive features, your PDF form will become more engaging and user-friendly.

/*
 * Create and apply a new form to an existing PDF.
 * The example shows how to load template1.pdf and add an interactive form to it and save it
 * as template1_with_form.pdf.
 *
 * Run as: go run pdf_form_add.go
 */

package main

import (
    "fmt"
    "os"

    "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() {
    inputPath := `template.pdf`
    outputPath := `template1_with_form.pdf`

    err := addFormToPdf(inputPath, outputPath)
    if err != nil {
        fmt.Printf("Failed to add form: %#v\n", err)
        os.Exit(1)
    }

    fmt.Printf("Success, output in %s\n", outputPath)
}

// addFormToPdf adds the form to the PDF specified by `inputPath` and outputs to `outputPath`.
func addFormToPdf(inputPath string, outputPath string) error {
    // Read the input pdf file.
    f, err := os.Open(inputPath)
    if err != nil {
        return err
    }
    defer f.Close()

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

    var form *model.PdfAcroForm

    // Generate a new AcroForm instead of copying from the source PDF.
    opt := &model.ReaderToWriterOpts{
        SkipAcroForm: true,
        PageProcessCallback: func(pageNum int, page *model.PdfPage) error {
            if pageNum == 1 {
                form = createForm(page)
            }

            return nil
        },
    }

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

    // Set new AcroForm.
    err = pdfWriter.SetForms(form)
    if err != nil {
        return err
    }

    return pdfWriter.WriteToFile(outputPath)
}

// textFieldsDef is a list of text fields to add to the form. The Rect field specifies the coordinates of the
// field.
var textFieldsDef = []struct {
    Name string
    Rect []float64
}{
    {Name: "full_name", Rect: []float64{123.97, 619.02, 343.99, 633.6}},
    {Name: "address_line_1", Rect: []float64{142.86, 596.82, 347.3, 611.4}},
    {Name: "address_line_2", Rect: []float64{143.52, 574.28, 347.96, 588.86}},
    {Name: "age", Rect: []float64{95.15, 551.75, 125.3, 566.33}},
    {Name: "city", Rect: []float64{96.47, 506.35, 168.37, 520.93}},
    {Name: "country", Rect: []float64{114.69, 483.82, 186.59, 498.4}},
}

// checkboxFieldDefs is a list of checkboxes to add to the form.
var checkboxFieldDefs = []struct {
    Name    string
    Rect    []float64
    Checked bool
}{
    {Name: "male", Rect: []float64{113.7, 525.57, 125.96, 540.15}, Checked: true},
    {Name: "female", Rect: []float64{157.44, 525.24, 169.7, 539.82}, Checked: false},
}

// choiceFieldDefs is a list of comboboxes to add to the form with specified options.
var choiceFieldDefs = []struct {
    Name    string
    Rect    []float64
    Options []string
}{
    {
        Name:    "fav_color",
        Rect:    []float64{144.52, 461.61, 243.92, 476.19},
        Options: []string{"Black", "Blue", "Green", "Orange", "Red", "White", "Yellow"},
    },
}

// createForm creates the form and fields to be placed on the `page`.
func createForm(page *model.PdfPage) *model.PdfAcroForm {
    form := model.NewPdfAcroForm()

    // Add ZapfDingbats font.
    zapfdb := model.NewStandard14FontMustCompile(model.ZapfDingbatsName)
    form.DR = model.NewPdfPageResources()
    form.DR.SetFontByName(`ZaDb`, zapfdb.ToPdfObject())

    for _, fdef := range textFieldsDef {
        opt := annotator.TextFieldOptions{}

        textf, err := annotator.NewTextField(page, fdef.Name, fdef.Rect, opt)
        if err != nil {
            panic(err)
        }

        *form.Fields = append(*form.Fields, textf.PdfField)
        page.AddAnnotation(textf.Annotations[0].PdfAnnotation)
    }

    for _, cbdef := range checkboxFieldDefs {
        opt := annotator.CheckboxFieldOptions{}

        checkboxf, err := annotator.NewCheckboxField(page, cbdef.Name, cbdef.Rect, opt)
        if err != nil {
            panic(err)
        }

        *form.Fields = append(*form.Fields, checkboxf.PdfField)
        page.AddAnnotation(checkboxf.Annotations[0].PdfAnnotation)
    }

    for _, chdef := range choiceFieldDefs {
        opt := annotator.ComboboxFieldOptions{Choices: chdef.Options}

        comboboxf, err := annotator.NewComboboxField(page, chdef.Name, chdef.Rect, opt)
        if err != nil {
            panic(err)
        }

        *form.Fields = append(*form.Fields, comboboxf.PdfField)
        page.AddAnnotation(comboboxf.Annotations[0].PdfAnnotation)
    }

    return form
}

And the result:

Adding Interactivity to Your Form

4. Testing and Deployment

Once you have created your interactive PDF form using Golang PDF Library, it is crucial to thoroughly test its functionality. Here are some tips for testing:

  • Fill out the form and ensure that all entered data is captured correctly.

  • Verify that form validation rules are enforced, such as mandatory fields or specific format requirements.

  • Test the interactivity of the form by triggering various actions and verifying expected outcomes.

After successful testing, you are ready to deploy your interactive PDF form. Share it with your intended audience through email, website downloads, or any other appropriate channels.

Conclusion

Creating interactive PDF forms with the Golang PDF Library offers numerous opportunities to simplify data collection and improve user experience. By following the steps provided in this blog post, you will be able to design and implement dynamic PDF forms that are tailored to your unique requirements. So don’t hesitate any longer! Delve into the world of the Golang PDF Library and unleash the potential of interactive PDF forms right away!