Click here to Skip to main content
15,886,689 members
Articles / Web Development / ASP.NET
Article

Using PDF Forms to Improve User Interaction with DotPdf

29 May 2015CPOL4 min read 445.5K   25   3
Use Atalasoft's DotPdf SDK to improve workflow processes with external customers.

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

Introduction

This article will walk through the steps to programmatically create a PDF file using DotPdf, stream it to a client computer, then parse the data upon the client’s submission.

What you will need

  • Atalasoft DotPdf

    If you do not have DotPdf you can download the installer here. http://www.atalasoft.com/products/dotpdf/

  • Atalasoft DotPdf License

    Use the Activate DotPdf application in your start menu to generate a DotPdf license. If you deploy your application to IIS you will need to get a server license and put it in your bin folder of the application.

  • Visual Studio Standard C# IDE

Create a Web Project with handler

Open Visual Studio and create a new project. Select .ASP web application as the project type. Add two New Items to your project, a HTML page and a Generic Handler named PdfHandler.ashx. Set the HTML page as the start page for your application. The PdfHandler.ashx is where you will put all of the backend code for this project.

Generating a PDF form

First we will need to generate the PDF form. DotPdf has a class called PdfGeneratedDocument it is the starting point to generate a document. The document will also be storing our PdfForm object and contains any number of PdfPage objects. Using the following three method calls we will initialize the document to have a page and a form:

C#
PdfGeneratedDocument doc = new PdfGeneratedDocument();
doc.Form = new Atalasoft.PdfDoc.Generating.Forms.PdfForm();
PdfGeneratedPage page = doc.AddPage(PdfDefaultPages.Letter);

Next, we will create a data field for the client to submit text data. This is done with a TextWidgetAnnotation. To label the field we will use a PdfTextLine. Remember that PDF coordinates are drawn from the bottom left of the page with each inch being represented by 72 PDF points. To put the text annotation near the top of the document, I chose 700 for the Y component and generated the following code:

C#
TextWidgetAnnotation name = new TextWidgetAnnotation(
    new PdfBounds(72, 700, 200, 20), "name", null);
PdfTextLine nameLabel = new PdfTextLine(
    "Helvetica", 22.0, "Name:", new PdfPoint(72, 730));

Note: Using Helvetica for the PdfTextLine’s font allows you to not have to create a PdfFontResource. If you wish to have a custom font, you will need to create a PdfFontResource and add it to the document.

Once the objects are created, they will need to be added to the appropriate rendering lists. The PdfTextLine will need to be added to the page’s drawing list. Because the TextWidgetAnnotation is an annotation and part of our form, we will need to add it to both the annotation list and the form object.

C#
page.DrawingList.Add(nameLabel);
page.Annotations.Add(name);
doc.Form.Fields.Add(name);

The other form element is the submit button. When the client clicks the submit button, we want the PDF form to send a post request to our webhandler. Just like the other annotation, we need to give it a position. To make this a submit button we must give it a PdfSubmitFormAction initialized with URL that it will post to, and SubmitAsHtml set to true. Then we add it to the Form and Annotations collections:

C#
PushButtonWidgetAnnotation button = new PushButtonWidgetAnnotation(
    new PdfBounds(72, 550, 60, 20), "submit");
PdfSubmitFormAction submit = new PdfSubmitFormAction(context.Request.Url);
submit.SubmitAsHtml = true;
button.ClickActions.Add(submit);
page.Annotations.Add(button);
doc.Form.Fields.Add(button);

I recommend then wrapping all the PDF generation code in a method call CreatePdf(context).

Streaming the PDF to the client

To then stream the generated PDF to the client, we write the document out to the Context.Response.OutputStream. The following code will allow for the document to be streamed to the client and automatically opened in the adobe plugin or chromes PDF viewer:

C#
    private void SendPdfForm(HttpContext context)
{
    context.Response.Clear();
    context.Response.ContentType = "application/pdf";
    context.Response.AddHeader("Content-Disposition", "inline; filename=" + "PDFForm");

    PdfGeneratedDocument doc = CreatePdf(context);

    MemoryStream mem = new MemoryStream();
    doc.Save(mem);
    mem.Seek(0, SeekOrigin.Begin);
    byte[] pdfBytes = new byte[mem.Length];
    mem.Read(pdfBytes, 0, (int)(mem.Length));
    context.Response.AddHeader("Content-Length", pdfBytes.Length.ToString());
    context.Response.BinaryWrite(pdfBytes);
    context.Response.Flush();
    context.Response.End();
}

Routing the requests to the proper functions

In the ashx file, when it was generated, there is a method stub for ProcessRequest. This is where all of the requests to PdfHandler.ashx will be routed to. Due to the nature of our application, two different requests will be made of the handler: one to request the programmatically generated PDF and one to handle the PDF form submission. PDF form submission will always have information in the input stream. To distinguish when one of these calls is made I use the following code:

C#
if (context.Request.InputStream.Length !=0)
        HandleFormSubmission(context);

To distinguish a request for the PDF we can access a hidden form value though the query string like this:

C#
if(context.Request.QueryString["pdf"]!=null)
    SendPdfForm(context);

Requesting the PDF though HTML

In your HTML document, sending a request to the server for the dynamically generated PDF is simple. Make a HTML form with a submit button and a hidden data value (this will get consumed as a query string):

HTML
<body>
<form action="PdfHandler.ashx">
<input type="hidden" name="pdf" value="request" />
<input type="submit" id="Button1" value="Get Pdf Form" /> 
</form>
</body>

If you were to debug your application at this point, place a breakpoint on the SendPdfForm method call in your ProcessRequest method. If you press the button on your HTML page you should cause the breakpoint to trigger. After continuing you should be presented with a PDF document (assuming you are using Chrome or have Adobe Acrobat installed and plugged into your browser).

Handling the PdfForm POST request

Once the PDF is successfully streaming to the client, submit a form with the name field filled in and the InputStream of the resulting request to your webserver will contain an HTML query string style data pairing string (e.g. "name=Jeff&DOB=12021985"). There is a built in static .NET method to parse this style of return data into a NameValueCollection: it is HttpUtility.ParseQueryString(string). That data can then be processed into your solution in whatever way your workflow is designed.

History

Version 1.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Marketing Atalasoft
United States United States
This member doesn't quite have enough reputation to be able to display their biography and homepage.

Comments and Discussions

 
Question$3000? Pin
Member 445223220-Feb-15 8:22
Member 445223220-Feb-15 8:22 
AnswerRe: $3000? Pin
deepakdynamite23-Feb-15 16:54
deepakdynamite23-Feb-15 16:54 
AnswerRe: $3000? Pin
Kevin Hulse10-Apr-15 9:43
professionalKevin Hulse10-Apr-15 9:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.