Persits Software, Inc. Web Site
 Navigator:  Home |  Manual |  Chapter 11a: Existing Form Fill-in
Chapter 12: Miscellaneous Features Chapter 11: Form Creation
  Chapter 11a: Existing Form Fill-in
11a.1 Form Fill-in Overview
11a.2 Adobe Acrobat 7/Designer 7 Issues
11a.3 Code Sample

11a.1 Form Fill-in Overview

In Chapter 9 of this manual, we already described the process of filling in a form-like document (see Section 9.2).

The approach described in that chapter had one serious drawback: individual blanks in a "form" had to be referenced by their physical coordinates. This is because the Section 9.2 code sample did not involve a real form, but a regular (static) PDF document depicting a form.

Using tools such as Adobe Acrobat, it is possible to place interactive fields on an existing document using a graphical user interface. The form creator chooses a name, size, location and other options for each field. Once a form has been created, it can be filled in either interactively by a user, or automatically using tools such as AspPDF. A form field can be referenced by name, as opposed to (x, y)-coordinates, which simplifies the coding significantly.

The PdfForm object provides the method FindField which returns a PdfAnnot object representing a top-level form field with the specified name. If no field under this name is found, the method returns Nothing.

Set Field = Doc.Form.FindField("txtLastName")

To specify a text value for a field, the method SetFieldValue of the PdfAnnot object should be used. This method accepts two arguments: a text string, and a font to be used to render the string. The SetFieldValue method uses the field's pre-defined alignment and font size parameters. It also preserves an existing field border if there is one.

The SetFieldValue method can be used to set a value not only for text fields, but checkboxes, drop-down list boxes and radio buttons as well. To select or unselect a checkbox, you must specify a state name for the text string argument. The state name for the "on" state should be obtained via the FieldOnValue property. The state name for the "off" state is usually "Off".

When working with radio button groups, you need to use the PdfAnnot.Children collection to reference each individual radio button within a group. The code snippet below deselects radio button #1 (American Express) and selects radio button #2 via the SetFieldValue method.

The following code fragment fills out a credit card form generated in Section 11.2:

' Credit card number
Set Field = Doc.Form.FindField("ccNumber")
Field.SetFieldValue "324234324234", Doc.fonts("Helvetica")

' Expiration month
Set Field = Doc.Form.FindField("ccMonth")
Field.SetFieldValue "Mar", Doc.fonts("Helvetica")

' Expiration year
Set Field = Doc.Form.FindField("ccYear")
Field.SetFieldValue "2010", Doc.fonts("Helvetica")

' "Need Receipt?" checkbox
Set Field = Doc.Form.FindField("Receipt")
Field.SetFieldValue Field.FieldOnValue, Nothing
' "on" state

' Credit card type (radio buttons)
Set Field = Doc.Form.FindField("ccType")
field.Children(1).SetFieldValue "Off", Nothing '
Unselect Amex
field.Children(2).SetFieldValue field.Children(2).FieldOnValue, Nothing '
Select Visa

11a.2 Adobe Acrobat 7/Designer 7 Issues
The emergence of Adobe Acrobat 7.0 and Designed 7.0 brought about a number of significant changes to the PDF form specifications. Two changes that are most relevant to AspPDF's form fill-in functionality are a new way of naming form fields, and the Adobe XML Forms Architecture (XFA).

When you switch to PDF forms created by Version 7 and later of the Adobe Acrobat suite, you may have to make some changes to your AspPDF-based applications to accommodate the new Adobe specs.

11a.2.1 Field Naming

Adobe Designer 7 assigns hierarchically-built names to form fields, such as form1[0].#subform[0].Address[0]. It is these long names that have to be passed to the Form.FindField method.

If you are not sure as to the full name of a field in your PDF, we recommend opening this document in a text editor (such as WordPad) and searching for your short field name (such as "Address"). You are likely to find a fragment which looks similar to this:

33 0 obj<</Rect[118.701 659.835 501.165 681.165]/TM(form1[0].#subform[0].Address[0]) /Subtype/Widget/TU(Address:)/Parent 29 0 R/F 4/P 8 0 R/Q 0/T<FEFF0041006400640072006500730073005B0030005D> /StructParent 2/DA(/TimesNewRomanPSMT 10.00 Tf 0 g)/FT/Tx/Type/Annot/MK<<>>>>
endobj

The string in parentheses followed by the word /TM is likely this field's long name which you can copy and paste into your script.

11a.2.2 Adobe XML Forms Architecture (XFA)

In a nutshell, XFA is Adobe's new way to describe form structure and content using XML. XFA is only briefly mentioned in the official PDF 1.6 specifications, but the full description of this new standard is available from the Adobe.com web site as a 744-page document. You can download it here.

An attempt to programmatically fill in an XFA-based form (such as a form created by Adobe Designer 7) using AspPDF may fail as AspPDF currently lacks XFA support. As a temporary work-around, AspPDF 1.5.0.1+ offers a new method, PdfForm.RemoveXFA, which completely removes the XFA information from a form, thus making it compatible with older PDF form specifications, which AspPDF does support. In most cases, the user will not even notice any difference between an XFA-based and XFA-free form.

The following code snippet demonstrates the usage of the new method:

Set Doc = Pdf.OpenDocument("c:\path\TheForm.pdf")
Doc.Form.RemoveXFA

Set field = Doc.Form.FindField("form1[0].#subform[0].Name[0]")
field.SetFieldValue "John Smith", Doc.fonts("Times-Roman")
...
' Fill in other fields

11a.3 Code Sample
The following code sample fills in a simple form created in Adobe Designer 7.0.

VBScript
Set PDF = Server.CreateObject("Persits.PDF")

' Open an existing form
Set Doc = PDF.OpenDocument( Server.MapPath( "SimpleForm.pdf" ) )

' Create font object
Set Font = Doc.Fonts("Helvetica-Bold")

' Remove XFA support from it
Doc.Form.RemoveXFA

' Fill in Name
Set field = Doc.Form.FindField("form1[0].#subform[0].Name[0]")
field.SetFieldValue Request("Name"), Font

' Fill in Address
Set field = Doc.Form.FindField("form1[0].#subform[0].Address[0]")
field.SetFieldValue Request("Address"), Font

' Fill in marital status
Set field = Doc.Form.FindField("form1[0].#subform[0].RadioButtonList[0]")
Set ChildField = field.Children( Request("Type") )
ChildField.SetFieldValue ChildField.FieldOnValue, Nothing

' Fill in "How did you hear about us" checkboxes
If Request("Internet") <> "" Then
   Set field = Doc.Form.FindField("form1[0].#subform[0].Internet[0]")
   field.SetFieldValue field.FieldOnValue, Nothing
End if

If Request("WordOfMouth") <> "" Then
   Set field = Doc.Form.FindField("form1[0].#subform[0].WordOfMouth[0]")
   field.SetFieldValue field.FieldOnValue, Nothing
End if

If Request("Newspaper") <> "" Then
   Set field = Doc.Form.FindField("form1[0].#subform[0].Newspaper[0]")
   field.SetFieldValue field.FieldOnValue, Nothing
End if

'Save document
Path = Server.MapPath( "filledform.pdf")
FileName = Doc.Save( Path, false)

Set Doc = Nothing
Set Pdf = Nothing

C#
public void GeneratePDF(object sender, System.EventArgs args)
{
   // create instance of the PDF manager
   IPdfManager objPDF;
   objPDF = new PdfManager();

   // Open existing form
   IPdfDocument objDoc = objPDF.OpenDocument( Server.MapPath( "SimpleForm.pdf" ), Missing.Value );

   IPdfFont objFont = objDoc.Fonts["Helvetica-Bold", Missing.Value]; // a standard font

   // Remove XFA support from it
   objDoc.Form.RemoveXFA();

   // Fill in Name
   IPdfAnnot objField = objDoc.Form.FindField("form1[0].#subform[0].Name[0]");
   objField.SetFieldValue( txtName.Text, objFont );

   // Fill in Address
   objField = objDoc.Form.FindField("form1[0].#subform[0].Address[0]");
   objField.SetFieldValue( txtAddress.Text, objFont );

   // Fill in marital status
   int nIndex = 1;
   if( rdMarried.Checked )
      nIndex = 2;

   if( rdDivorced.Checked )
      nIndex = 3;

   objField = objDoc.Form.FindField("form1[0].#subform[0].RadioButtonList[0]");
   IPdfAnnot objChildField = objField.Children[nIndex];
   objChildField.SetFieldValue( objChildField.FieldOnValue, null );

   // Fill in "How did you hear about us" checkboxes
   if( chkInternet.Checked )
   {
      objField = objDoc.Form.FindField("form1[0].#subform[0].Internet[0]");
      objField.SetFieldValue( objField.FieldOnValue, null );
   }

   if( chkWordOfMouth.Checked )
   {
      objField = objDoc.Form.FindField("form1[0].#subform[0].WordOfMouth[0]");
      objField.SetFieldValue( objField.FieldOnValue, null );
   }

   if( chkNewspaper.Checked )
   {
      objField = objDoc.Form.FindField("form1[0].#subform[0].Newspaper[0]");
      objField.SetFieldValue( objField.FieldOnValue, null );
   }

   String strFileName = objDoc.Save( Server.MapPath( "filledform.pdf"), false );
}

Click the links below to run this code sample:

http://localhost/asppdf/manual_11/11_fill.asp
http://localhost/asppdf/manual_11/11_fill.aspx  Why is this link not working?

Chapter 12: Miscellaneous Features Chapter 11: Form Creation

Search AspPDF.com

  This site is owned and maintained by Persits Software, Inc. Copyright © 2003. All Rights Reserved.