Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Database

Examining the FDF Toolkit


Aug01: Programmer's Toolchest

Lauren is a partner at Spin Solutions, LLC. She can be reached at lhightower@ spinsolutions.com.


Adobe's Portable Document Format (PDF) has become a standard format for creating and viewing documents that need to retain special formatting beyond what you can produce using HTML. The Adobe PDF Reader is built into Internet Explorer and Netscape Navigator, and is probably the most common plug-in downloaded for older browsers. As a result of the growing popularity and acceptance of PDF documents, the developer community has turned to them to alleviate some of the inherent printing and formatting weaknesses of HTML.

Organizations most frequently use PDF documents to deliver blank forms to users. For instance, the IRS uses PDFs to distribute tax forms to taxpayers who then download them, fill them out, and mail them in. This saves taxpayers the time and hassle of going to the Post Office or library to find forms, and saves the IRS the postage and manpower of mailing them out. But that only scratches the surface of what you can do with PDFs on web sites.

In this article, I'll show you how to use Adobe's Forms Data Format (FDF) Toolkit to make PDF documents come alive. When used in conjunction with other tools, you can use PDF documents in place of HTML forms, interact with databases, and deliver highly formatted, completed documents, even if the documents use complex logic to derive the contents of the fields.

The Adobe Forms Data Format (FDF) Toolkit

The FDF Toolkit (http://partners.adobe.com/asn/developer/acrosdk/forms.html) targets developers who want not only to deliver blank forms to users, but also want to work programmatically with the data that populates the form. You can use the toolkit with the full version of Adobe Acrobat to design smart forms that have functionality beyond static, blank PDF documents. The key to unlocking the power of the toolkit lies in understanding Acrobat Forms.

Acrobat Forms are extensions to the PDF format that overlay a PDF document and let you add form elements like buttons, text fields, radio buttons, drop-down listboxes, and the like. The elements you can add to a form are the same as those you can have on an HTML page. To add these elements, you use the Form tool in the full version of Adobe Acrobat. Once you add the fields using Acrobat, the FDF Toolkit lets you populate them programmatically before displaying them on the PDF.

The FDF Toolkit is a threadsafe API you can run on any web server under Windows NT, Windows 2000, any flavor of UNIX, or Linux. You can use the toolkit with C/C++, Java, Perl, Visual Basic, and Active Server Pages (ASP). For this article, I'll use Windows NT 4.0, Visual Basic, and Active Server Pages.

An FDF Example

To illustrate how to use a PDF document with the FDF Toolkit, I'll use the IRS Form 4868, Application for Automatic Extension of Time to File U.S. Individual Tax Return. As Figure 1 shows, this form has five short sections and two calculated fields.

The FDF Toolkit makes it possible for users to enter information directly into the PDF document, eliminating the need to create an HTML data-entry form. However, I prefer to assume the added work of creating an HTML form because I can do more validation and error checking using JavaScript in a familiar HTML development environment. The Adobe-specific Acrobat Forms JavaScript Object Model, which comes integrated into the full version of Acrobat, is clunky and difficult to use. Because users are so accustomed to PDF documents being static rather than interactive, it is also an unfamiliar environment for users entering the data who might be stumped when they see an empty PDF form with no instruction on how to enter data.

You can see the finished example in action at http://www.spinsolutions.com/pdfArticle/.

Creating HTML Forms

For this example, I'll assume the user is a CPA who is filing an extension for a client. The basic client information is stored in a database on the CPA firm's intranet. Using a component written for another application, I can call a function GetClient to retrieve the Identification information required in Part I of Form 4868.

The code that generates the HTML form in the extension.asp file is available electronically (see "Resource Center," page 5). The Visual Basic source code for retrieving the data from a relational database is also included. Because the focus of this article is not on COM objects or ASP, I won't delve into the details of either of those code snippets, but will assume you are familiar with a method of creating an ASP page with a form and populating the form fields with data.

Marking Up the PDF Document

You can retrieve a copy of IRS Form 4868 from the IRS at http://www.irs.gov/. To mark up a document, you need the full version of the Adobe Acrobat software, Version 4.0 or above. To draw the fields on the PDF document, you use the Form tool. For step-by-step instructions on drawing fields on a PDF, see the documentation that comes with Adobe Acrobat. Immediately after you finish drawing each form field, the Field Properties dialog appears so you can define the field.

For simplicity's sake, I assign the same name to each PDF field that I assigned to the corresponding HTML field. For instance, the TaxPayerName field on the HTML form corresponds with the TaxPayerName field on the PDF. As you'll see, this lets me cycle through the results of the form and set values on the PDF without mapping specific form names on the PDF to specific form names on the HTML form.

Acrobat gives you a lot of flexibility in defining the way a field looks and acts. I focus on the cosmetic aspects of the Properties dialog because I do most of the processing of data using other tools and let the PDF simply display the results. Using the Appearance tab, I set each of the fields as Text fields and mark them as Read Only, prohibiting users from changing the information once the PDF is generated. The Format tab lets me set all of the number fields in sections III, IV, and V on the form to Number fields that display with two decimal places and a dollar sign ($) preceding the number.

Although I do most of the processing of data in the ASP page, I let the PDF document handle one of the calculations for me. The Total Liability field in Section V of the form is a simple calculation that sums lines 6, 7, and 8. To set this field to display the sum of those fields, I choose the Calculate tab, then select the Pick button and add all three fields.

Once the PDF is marked up, save and close it. The next step is getting the data from the HTML form and displaying it on the PDF document. You can download a marked up copy of the IRS form from http://www.spinsolutions.com/pdfArticle/f4868.pdf.

Using the FDF Toolkit

Once you download the toolkit from http://partners.adobe.com/asn/developer/acrosdk/

forms.html, you must install it. The installation for each version of the toolkit is different, but to install the Windows version, simply double-click the downloaded executable and follow the directions. The download contains two DLLs: FdfacX.dll and FdfTk.dll. You must install and register FdfacX.dll into a directory that has execute permissions (Adobe recommends \winnt\system32\inetsrv\ASP\cmpnts). FdfTk.dll does not have to be registered, but it must be in the same directory as FdfacX.dll or in the system directory (\winnt\system32). If you are running NTFS, both DLLs must have execute permissions.

The FDF Toolkit can be used with a number of languages. For this example, I use it with VBScript in an Active Server Page. I instantiate the component the way I do any other component. Once instantiated, it has a series of methods and properties that I can call.

Listing One displays the ASP code that instantiates the object, then calls the function FDFCreate, which returns an object of type FDFACXLib.FdfDoc with 36 methods. One of the methods associated with the FDF object is FDFSetValue. I use this method to set the values for each field on the PDF document. The first code segment in Listing Two cycles through the fields on the HTML form and sets the value of the corresponding field on the PDF document. The second code segment calculates the Balance on line 6 of Part III, then sets the value on the corresponding field.

Listing Three shows the final step in creating the FDF — defining which PDF document it goes with and saving the file. (I've hard coded the paths for both files to make the example easy to read, but you should use the registry or an ini file to hold the values of a working directory so the application is easy to move from server to server.)

Once I create and save the file, I can look at the generated FDF in a text editor to see what I generated. Listing Four shows the contents of the generated FDF file.

The FDF Toolkit documentation describes the format of the file in detail. In reality, I don't need the FDF Toolkit to generate an FDF file, but it does make it easier. Because it is a simple text file, I could also use the FileSystem object to create and save an FDF file in the specific FDF format.

Displaying the Results

To display the completed Form 4868, I redirect the user's browser to the generated FDF file using Listing Five.

The big drawback of generating and displaying FDF files is that individual users must specifically set up their browser to display FDF files in the Adobe Acrobat Reader. To do this is not simple and could be a daunting experience for some inexperienced users. For instance, to accomplish this in Internet Explorer 5.0, users would:

1. Open Windows Explorer, choose Tools... Folder Options...File Types.

2. Scroll to FDF in the list of file types. (If FDF is not in the list, click the New button and add it to the list.)

3. Select the Change button, then select the Portable Document Format and click OK. (If PDF is not an option, users need to download and install the Adobe Acrobat Reader from http://www.adobe.com/.)

4. Click Close.

The instructions for associating FDF files with the Adobe Acrobat Reader are different for different browsers and different versions of the browsers. If your target audience is the general population, this is probably not the best option. Unfortunately, Adobe doesn't offer a way to dynamically merge FDF and PDF files, allowing you to redirect the user to a completed PDF document instead of an FDF file. The best bet is to invest in FDFMerge, a tool from Digital Applications (http://www.digapp.com/).

FDFMerge is a command-line utility that merges an FDF file and a marked up PDF, then uses flattening technology to display it as a completed PDF document. Once you merge the FDF and the PDF, you can display the completed PDF through a web browser like any PDF document. FDFMerge is easy to install, but a little more difficult to use.

Because FDFMerge is a synchronous utility, you must execute the application on a command line, then check for the completion of the process before you can display the PDF file to the user. Listing Six shows how to do this in Visual Basic.

The ExecCmd function is included in the downloadable code. The ExecCmd function starts the utility and stops processing of the calling function until the utility has completed its task. By breaking down the fdfmerge.exe command line, you can see the parts of the string that affect how the PDF is generated. Table 1 displays the pieces of the string and their functions.

Once I generate the PDF, I can redirect users to the generated PDF document just as I did the generated FDF document. But in this case, if users have the Adobe Acrobat Reader installed, the PDF opens automatically in the browser with no specific configuration required on the user's part.

Writing Contents of the PDF

In some cases, you might want to write the contents of the generated PDF document directly to the screen instead of redirecting users to a generated file. The benefit of this approach is that you can delete the file after generating it and it won't take up space on the server. It is also a more secure method of delivering sensitive data since a generated file is not stored on the server.

A PDF document is a Postscript binary file. To write the file directly to the browser, the page displaying the document must have a content type of "application/pdf." This automatically tells the browser to use the plug-in associated with content type "application/pdf," the Adobe Acrobat Reader.

Listing Seven shows the function Generate4868, which opens and reads the generated PDF file, returns the contents of the PDF file in binary format to the ASP page, then deletes the generated PDF. Once the object returns the binary contents of the PDF file, the ASP page can display the PDF file in the Acrobat Reader by writing the binary contents to the page with Listing Eight.

Conclusion

As the Web evolves into a true application platform, the necessity to gather, manipulate, and display data in highly formatted forms is outpacing the tools provided by Adobe. Until Adobe can offer a complete forms solution, using a combination of tools is the best strategy for delivering interactive forms.

The IRS has implemented its own version of the fill-in 4868 form (http://ftp.fedworld.gov/pub/irs-fill/f4868.pdf). This version allows the taxpayer to fill in the fields directly on the PDF, but provides no validation and no automatic calculation. This is fine for a simple form, but users are starting to expect smarter forms that are prepopulated with data and have automatic calculations and validation.

DDJ

Listing One

<%
    Set objFDF = Server.CreateObject("FdfApp.FdfApp")
    Set FDF = objFDF.FDFCreate
%>

Back to Article

Listing Two

<%
    For Each vpItem In Request.Form
        FDF.FDFSetValue vpItem, UCase(Request.Form(vpItem)), False
    Next
    fpBalance = Request.Form("Liability") - Request.Form("Payments")
    FDF.FDFSetValue "Balance",fpBalance,False
%>

Back to Article

Listing Three

<%        
    FDF.FDFSetFile "c:\prj\pdfarticle\f4868.pdf"
    FDF.FDFSaveToFile "c:\prj\pdfarticle\temp.fdf"
%>

Back to Article

Listing Four

%FDF-1.2
%bcOS
1 0 obj
<< 
/FDF << /Fields 2 0 R /F (c:\\prj\\pdfarticle\\f4868.pdf)>> >
> 
endobj

2 0 obj
[ 
<< /T (TaxPayerName)/V (JANE MARIE DOE)>> 
<< /T (TaxPayerAddress)/V (123 MAIN STREET)>> 
<< /T (TaxPayerCityStateZip)/V (ANYTOWN, CA  99097)>> 
<< /T (SSN_1)/V (111)>> 
<< /T (SSN_2)/V (11)>> 
<< /T (SpouseGiftGSTExtension)/V ()>> 
<< /T (SSN_3)/V (1111)>> 
<< /T (SpouseSSN_1)/V (999)>> 
<< /T (SpouseSSN_2)/V (99)>> 
<< /T (SpouseSSN_3)/V (9999)>> 
<< /T (Payments)/V (2000)>> 
<< /T (GiftGSTExtension)/V (X)>> 
<< /T (Payment)/V (5000)>> 
<< /T (Liability)/V (5000)>> 
<< /T (SpouseGSTPayment)/V (89)>> 
<< /T (GSTPayment)/V (3000)>> 
<< /T (Balance)/V (3000)>> 

]
endobj
trailer
<<
/Root 1 0 R 
>
>
%%EOF

Back to Article

Listing Five

<%  
    Response.Write "<a href=temp.fdf>Click Here to see the PDF</a>"
%>

Back to Article

Listing Six

spCommand = c:\fdfmerge\fdfmerge.exe -l Log.txt -o 
            c:\prj\pdfarticle\temppdf.pdf 
            c:\prj\pdfarticle\f4868.pdf 
            c:\prj\pdfarticle\temp.fdf
vpShell = ExecCmd(spCommand)

Back to Article

Listing Seven

Public Function Generate4868(ByVal vhPDFFileName As Variant, 
                              ByVal vhFDFFileName As Variant) As Variant
Dim spPDFTemp As String
Dim vpShell As Variant
Dim spCommand As String
Dim opFileSys As Object

'====================================================
' GET A TEMPORARY NAME FOR THE GENERATED PDF DOCUMENT
'====================================================
    Set opFileSys = CreateObject("Scripting.FileSystemObject")
    spPDFTemp = opFileSys.GetTempName()
    spPDFTemp = Replace(spPDFTemp, ".tmp", ".pdf")
    spPDFTemp = "c:\prj\pdfArticle\" & spPDFTemp
'=====================================
' GENERATE THE PDF FILE USING FDFMERGE
'=====================================
   spCommand = "c:\fdfmerge\fdfmerge.exe -l Log.txt -o " & spPDFTemp & " " &_
   vhPDFFileName & " " & vhFDFFileName
   vpShell = ExecCmd(spCommand) ' Run FDFMerge.
'====================================
' READ THE BINARY FILE AND SEND IT
' TO THE USER
'====================================
    If vpShell = 0 Then
        Generate4868 = readBinFile(spPDFTemp)
        opFileSys.DeleteFile vhFDFFileName, True
        opFileSys.DeleteFile spPDFTemp, True
    Else
        Generate4868 = "There was an error in the generation."
    End If
'====================================
' CLEAN UP
'====================================
    Set opFileSys = Nothing
End Function

Back to Article

Listing Eight

<%
Set oPDFGenerator = Server.CreateObject("pdfArticle.clsInterface") 
vPDFContent = oPDFGenerator.ReadPDF(TempPDF)
Response.BinaryWrite vPDFContent
%>

Back to Article


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.