Wednesday, January 30, 2008

Submit PDF Form as FDF with ColdFusion

In a previous entry I showed how I used iText to add a button to an existing PDF form that would submit the information as an html form. You could also use the default option, which submits the information as FDF. Simply change the last parameter from PdfAction.SUBMIT_HTML_FORMAT to zero (0). You can view the full code at the bottom of the entry here.


<cfscript>
PdfAction = createObject("java", "com.lowagie.text.pdf.PdfAction");
buttonAction = PdfAction.createSubmitForm( javacast("string", submitFormDataToURL),
javacast("null", ""),
0
);
</cfscript>


When the form is submitted, one way to process the received information from ColdFusion is to use iText's FdfReader class. Simply extract the bytes submitted using the GetHttpRequestData() function and pass them into the FdfReader class.


<cfset bytes = GetHttpRequestData().content>
<cfset reader = createObject("java", "com.lowagie.text.pdf.FdfReader").init(bytes)>


Then use the getFields() method to extract the names and values of the form fields that were submitted.


<cfset fields = reader.getFields()>

<cfloop collection="#fields#" item="key">
<!--- extract the value for this key --->
<cfset value = reader.getFieldValue(key)>
<!--- the value may be null --->
<cfif IsDefined("value")>
<cfset form[ key ] = trim(value) >
<cfelse>
<cfset form[ key ] = "" >
</cfif>
</cfloop>


Here is a simple example of processing form information submitted as FDF. It is intended as an example only and could certainly use improvement. But I will let you do that on your own ;)

RecieveForm.cfm

<!--- disable output so it does not interfere with fdf response --->
<cfsetting enablecfoutputonly="true" showdebugoutput="false">


<!--- use an FdfReader to extract the fields from the request content ---->
<cfset bytes = GetHttpRequestData().content>
<cfset reader = createObject("java", "com.lowagie.text.pdf.FdfReader").init(bytes)>
<cfset fields = reader.getFields()>

<cfloop collection="#fields#" item="key">
<!--- extract the value for this key --->
<cfset value = reader.getFieldValue(key)>
<!--- the value may be null --->
<cfif IsDefined("value")>
<cfset form[ key ] = trim(value) >
<cfelse>
<cfset form[ key ] = "" >
</cfif>
</cfloop>


<!--- verify the required fields exist and are non empty --->
<cfset wasValidated = true>
<cfset requiredFields = "Name,Address,Postal_Code,Email">
<cfloop list="#requiredFields#" index="fieldName">
<cfif NOT structKeyExists(form, fieldName) OR NOT len( form[fieldName] ) >
<cfset wasValidated = false>
<cfbreak>
</cfif>
</cfloop>

<cftry>
<cfquery name="logForm" datasource="MyDatasource">
INSERT INTO LogPDFForm ( PersonName, Address, PostalCode, Email, SubmitDate )
VALUES
(
<cfqueryparam value="#trim(form.Name)#" cfsqltype="cf_sql_varchar">,
<cfqueryparam value="#trim(form.Address)#" cfsqltype="cf_sql_varchar">,
<cfqueryparam value="#trim(form.Postal_Code)#" cfsqltype="cf_sql_varchar">,
<cfqueryparam value="#trim(form.Email)#" cfsqltype="cf_sql_varchar">,
<cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
)
</cfquery>
<cfset responseMessage = "Your form was successfully submitted!">

<cfcatch>
<cfset responseMessage = "Unable to process your form at this time. Please try again later.">
</cfcatch>
</cftry>

<!--- send a response --->
<cfcontent type="application/vnd.fdf">
<cfoutput>%FDF-1.2
%âãÏÓ
1 0 obj
<<
/FDF << /Status (#responseMessage#)>>
>>
endobj
trailer
<<
/Root 1 0 R

>>
%%EOF
</cfoutput>

0 comments:

  © Blogger templates The Professional Template by Ourblogtemplates.com 2008

Header image adapted from atomicjeep