pdf links

PDF Rendering
Convert PDF to Image (.NET)
Convert PDF to image on Android (Xamarin)
Convert PDF to image on iOS (Xamarin)
Convert PDF to image in Windows Store apps (.NET)
Convert PDF to image in Windows Phone apps (.NET)
PDF to image in Universal Windows Store apps (.NET)
Free PDF Viewer control for Windows Forms (.NET)
How to integrate PDF Viewer control in WPF app (.NET)
Creating WPF PDF Viewer supporting bookmarks (.NET)
Cross-platform PDF Viewer using GTK# (MONO)
Silverlight PDF viewer control (Silverlight 5)
Multithreaded PDF rendering (.NET)
Convert pdf to image in Silverlight app (C# sample)
How to set fallback fonts for PDF rendering (C#)
Avoiding the out-of-memory exception on rendering (C#)
PDF viewer single page application (WebAPI, AngularJS)
PDF viewer control for Windows 10 universal applications
Use custom ICC profile for CMYK to RGB conversion
PDF layers - separate images, text, annotations, graphics

PDF Forms Creation PDF Security
Conversion to PDF/A
Other topics
PDF Document Manipulation PDF Content Generation
Fixed and Flow layout document API (.NET)
Creation of grids and tables in PDF (C# sample)
How to create interactive documents using Actions (C# sample)
Text flow effects in PDF (C# sample)
How to generate ordered and bulleted lists in PDF (C# sample)
Convert HTML to PDF using flow layout API (C# sample)
How to use custom fonts for PDF generation (.NET)
Create document with differently sized pages (C#)
Create PDF documents using MONO (C#/MONO/Windows/OSX)
How to use background images for content elements (C#/PDF Kit/FlowLayout)
Add transparent images to PDF document (C#)
Draw round rect borders in PDF documents(C#)
ICC color profiles and and ICC based colors in PDF (C#)
How to use bidirectional and right to left text in PDF (C#)
Create PDF documents from XML templates (C# sample)
How to resize PDF pages and use custom stamps (C#)
Add header and footer to PDF page (.NET sample)
How to use clipping mask for drawing on PDF page
Fill graphics path with gradient brushes in PDF (Shadings)
Apitron PDF Kit and Rasterizer engine settings
Add layers to PDF page (optional content, C# sample)
How to create free text annotation with custom appearance
PDF Content Extraction PDF Navigation
PDF to TIFF conversion
Contact us if you have a PDF related question and we'll cover it in our blog.

2015-03-23

Create and load PDF Forms in Universal Applications using Windows Store and Windows Phone PDF library (C# sample)

Introduction


Universal Windows Store application project provides a good way to share code and develop Windows Phone and Windows Store version of the application at the same time. In case of our library it’s even more fun because API remains the same and you can use the same PDF .NET  library for both projects.

PDF files can contain forms consisting of fields where the information can be stored for later use and processing. If you’d like to read more about PDF forms and fields, official PDF specification is an invaluable resource. This topic is also covered in our pdf cookbook “Apitron PDF Kit in action” (available for free by the following link), see sections 3.7 “Interactive Forms” and section 4.4 “Content Element And Controls”. There are examples on how to create, edit or read data stored in PDF forms, written in C# with detailed explanation.

A good example demonstrating how to work with PDF forms is a questionnaire app gathering some data from the user and storing it in PDF document as a form. So we decided to go through and prepared sample universal app using our Apitron PDF Kit library that generates, saves and loads product questionnaire data. 

Solution overview 


To keep this sample as simple as possible we used single XAML page representing form layout and providing the data bound view for questionnaire data.

Data Model 


Data model is represented by base class called ProductQuestionnaireForm and by its specific implementation ApitronProductQuestionnaireForm. See the diagram below.

Pic. 1 Class digram, Apitron questionnaire sample

Page controls are bound to properties of ApitronProductQuestionnaireForm instance, so we don’t have to write any code to handle form updates if user changes their content.

Windows Phone App 


The view is represented by XAML app page, see picture below showing desktop and phone versions. They are almost identical and use same markup except some minor changes needed to fit content on the phone screen.


Pic. 2 Questionnaire App, Windows Phone version

Windows Store App 


Form layout for Windows Store app is shown here, below is a screenshot from Visual Studio XAML designer.


Pic. 3 Questionnaire app, Windows Store version

Workflow 


Using this app the user can fill the questionnaire form provided, in our case it’s a test form collecting opinions about Apitron products. After that, he can save entered data to local app storage as PDF form or load an existing form from it.

For simplicity, data is being saved as file “form.pdf” located in local app folder, which can be opened by using the following “known” folder: ApplicationData.Current.LocalFolder.

Output 


Generated questionnaire pdf form is shown on the image below. Both applications generate identical PDF files.


Pic. 4 Generated questionnaire pdf form
This file can be found by the following path:
C:\Users\[user name]\AppData\Local\Packages\[deployed package guid]\LocalState\form.pdf


Same form but opened in design mode is shown below. You can see field names assigned to each widget annotation present on page. Widget annotations are special kind of controls used to define visual representation of form fields data. In our case all controls created for this PDF form are made read-only, however it’s possible to make form data editable after generation if needed.


Pic. 5 Generated questionnaire pdf form opened in design mode

The code 


Complete app sample can be found in Apitron PDF Kit download package available on our website, check out this link.

Here we’d like to highlight PDF specific code that is responsible for form generation. It can be found in ProductQuestionnaireForm class and is provided below.

PDF Form generation and saving 


/// <summary>
/// Creates FlowDocument that represents PDF form.
/// </summary>
private FlowDocument CreatePDFDocument()
{
    FlowDocument document = new FlowDocument(){Margin = new Apitron.PDF.Kit.Styles.Thickness(10)};

    // add form fields and set text values based on form data
    document.Fields.Add(new TextField("SelectedProduct", SelectedProduct){IsReadOnly = true});
    document.Fields.Add(new TextField("UsagePeriod", UsagePeriod) { IsReadOnly = true });
    document.Fields.Add(new TextField("SatisfactionLevel", SatisfactionLevel) { IsReadOnly = true });
    document.Fields.Add(new TextField("UserCompanyName", UserCompanyName) { IsReadOnly = true });
    document.Fields.Add(new TextField("Feedback", Feedback) { IsReadOnly = true, IsMultiline = true});

    // register styles defining controls appearance
    document.StyleManager.RegisterStyle(".formHeader",new Apitron.PDF.Kit.Styles.Style()
{Display = Display.Block, Font = new Font(StandardFonts.HelveticaBold, 20)});
    document.StyleManager.RegisterStyle("TextBlock, TextBox", new Apitron.PDF.Kit.Styles.Style()
{ Font = new Font(StandardFonts.Helvetica, 14)});
    document.StyleManager.RegisterStyle("TextBlock + TextBox", new Apitron.PDF.Kit.Styles.Style()
{ BorderColor = RgbColors.Black, Border = new Border(1), Height = 20, Background = RgbColors.LightGray});
    document.StyleManager.RegisterStyle("Br", new Apitron.PDF.Kit.Styles.Style() { Height = 10});

    // add document content elements
    document.Add(new TextBlock("Product questionnaire form"){Class = "formHeader"});
    document.Add(new TextBlock("Generated on " + DateTime.Now.ToString("dd/MM/yyyy HH:mm")));
    document.Add(new Hr(){Height = 2, Margin = new Thickness(0,5,0,5)});
    document.Add(new TextBlock("Selected product:"));
    document.Add(new TextBox("SelectedProduct"));
    document.Add(new Br());
    document.Add(new TextBlock("Usage period:"));
    document.Add(new TextBox("UsagePeriod"));
    document.Add(new Br());
    document.Add(new TextBlock("SatisfactionLevel:"));
    document.Add(new TextBox("SatisfactionLevel"));
    document.Add(new Br());
    document.Add(new TextBlock("User company name:"));
    document.Add(new TextBox("UserCompanyName"));
    document.Add(new Br());
    document.Add(new TextBlock("Feedback:"));
    document.Add(new TextBox("Feedback"){Height = 100});

    return document;
}

/// <summary>
/// Saves current form data to local storage.
/// </summary>
public async Task<bool> SaveToLocalStorage(string fileName)
{
    try
    {
        FlowDocument pdfDocument = CreatePDFDocument();

        StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(fileName,CreationCollisionOption.ReplaceExisting);

        using (Stream outputStream = await file.OpenStreamForWriteAsync())
        {
            pdfDocument.Write(outputStream, new ResourceManager(), new PageBoundary(Boundaries.A4));
        }
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.Message);
        return false;
    }

    return true;
}

Loading stored PDF form data 


/// <summary>
/// Load form data from PDF file using given filename.
/// </summary>
public static async Task<ProductQuestionnaireForm> LoadFromLocalStorage(string fileName)
{
    try
    {              
        StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);

        using (Stream inputStream = await file.OpenStreamForReadAsync())
        {
            // use fixed document for reading form data
            FixedDocument pdfDocument = new FixedDocument(inputStream);

            // create and initialize form object instance
            ProductQuestionnaireForm form = new ApitronProductQuestionnaireForm();

            form.SelectedProduct = ((TextField)pdfDocument.AcroForm["SelectedProduct"]).Text;
            form.UsagePeriod = ((TextField)pdfDocument.AcroForm["UsagePeriod"]).Text;
            form.SatisfactionLevel = ((TextField)pdfDocument.AcroForm["SatisfactionLevel"]).Text;
            form.UserCompanyName = ((TextField)pdfDocument.AcroForm["UserCompanyName"]).Text;
            form.Feedback = ((TextField)pdfDocument.AcroForm["Feedback"]).Text;

            return form;
        }
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.Message);
    }

    return null;
}


Conclusion 


This approach can be used to create PDF forms in Windows Forms, WPF, Xamarin (Android and iOS), console, web or cloud applications. As you can see from samples above it takes less than 30 lines of code to produce a basic form having all necessary content set.

But Apitron PDF Kit library is not limited to just PDF forms, it provides full support for PDF features defined in official specification and can be used to create apps targeting all of the modern mobile, desktop or web platforms.  Free evaluation is available for all our products.

We’d be happy to get any feedback from you, feel free to contact our support with any questions you may have.

Downloadable version of this article can be found by the following link [PDF].

No comments:

Post a Comment