FormSubmitXml.cs
C# VB
//// This code is part of Document Solutions for PDF .NET demos.// Copyright (c) MESCIUS inc. All rights reserved.//using System.Drawing;using System.IO;using System.Xml;using System.Text;using System.Collections.Generic;using GrapeCity.Documents.Pdf;using GrapeCity.Documents.Pdf.AcroForms;using GrapeCity.Documents.Pdf.Actions;using GrapeCity.Documents.Pdf.Annotations;using GrapeCity.Documents.Text;
namespace DsPdfWeb.Demos{ // Note that the FormDataSubmit sample shows a better and easier solution for submitting form data. // // This sample creates an AcroForm PDF that can be submitted to the server. // It relies on the server to put the submitted data into an XML, // import that XML into a PDF containing a similar form, // and send the form with loaded data back to the client. // Note that the produced PDF with filled form fields // is shown in the client browser's default PDF viewer. // The code is similar to FormSubmit. public class FormSubmitXml { public int CreatePDF(Stream stream) { var doc = new GcPdfDocument(); var page = doc.NewPage();
var rc = Common.Util.AddNote("Fill the fields in the form and click 'Submit' to send it back to the server. " + "The sample server will put the submitted data into an XML, feed that XML" + "to a PDF with a different but compatible form, and send the resulting form" + "filled with the submitted data back to your browser." + "Note that the form with the submitted data is opened in the browser's default PDF viewer," + "and does not have the 'Submit' and 'Reset' buttons.", page);
var g = page.Graphics; var tf = new TextFormat() { Font = StandardFonts.Times, FontSize = 14 }; var ip = new PointF(72, rc.Bottom + 36); float fldOffset = 72 * 2 + 46; float fldHeight = tf.FontSize * 1.2f; float dY = 32;
// Text field: g.DrawString("First name:", tf, ip); var fldFirstName = new TextField() { Name = "FirstName", Value = "John" }; fldFirstName.Widget.Page = page; fldFirstName.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight); fldFirstName.Widget.DefaultAppearance.Font = tf.Font; fldFirstName.Widget.DefaultAppearance.FontSize = tf.FontSize; doc.AcroForm.Fields.Add(fldFirstName); ip.Y += dY;
// Text field: g.DrawString("Last name:", tf, ip); var fldLastName = new TextField() { Name = "LastName", Value = "Smith" }; fldLastName.Widget.Page = page; fldLastName.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight); fldLastName.Widget.DefaultAppearance.Font = tf.Font; fldLastName.Widget.DefaultAppearance.FontSize = tf.FontSize; doc.AcroForm.Fields.Add(fldLastName); ip.Y += dY;
// Checkbox: g.DrawString("Subscribe to Mailing List:", tf, ip); var fldCheckbox = new CheckBoxField() { Name = "Subscribe", Checked = true }; fldCheckbox.Widget.Page = page; fldCheckbox.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, fldHeight, fldHeight); doc.AcroForm.Fields.Add(fldCheckbox); ip.Y += dY;
// Multiline TextBox: g.DrawString("Additional information:", tf, ip); var fldAdditionalInfo = new TextField() { Name = "AdditionalInfo", Multiline = true }; fldAdditionalInfo.Widget.Page = page; fldAdditionalInfo.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight * 2); fldAdditionalInfo.Widget.DefaultAppearance.Font = tf.Font; fldAdditionalInfo.Widget.DefaultAppearance.FontSize = tf.FontSize; doc.AcroForm.Fields.Add(fldAdditionalInfo); ip.Y += dY * 2;
// Submit form button: var btnSubmit = new PushButtonField(); btnSubmit.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72, fldHeight); btnSubmit.Widget.ButtonAppearance.Caption = "Submit"; btnSubmit.Widget.Highlighting = HighlightingMode.Invert; btnSubmit.Widget.Page = page;
// The URL for the submission: btnSubmit.Widget.Activate = new ActionSubmitForm("/Samples/HandleFormSubmitXml"); doc.AcroForm.Fields.Add(btnSubmit);
// Reset form button: var btnReset = new PushButtonField(); btnReset.Widget.Rect = new RectangleF(ip.X + fldOffset + 72 * 1.5f, ip.Y, 72, fldHeight); btnReset.Widget.ButtonAppearance.Caption = "Reset"; btnReset.Widget.Highlighting = HighlightingMode.Invert; btnReset.Widget.Page = page; btnReset.Widget.Activate = new ActionResetForm(); doc.AcroForm.Fields.Add(btnReset); ip.Y += dY;
// Done: doc.Save(stream); return doc.Pages.Count; }
// // NOTE: the code below is used by the web sample browser controller when the form // prepared by this sample is submitted, it is not directly called by the CreatePDF() method. //
// Creates a GcPdfDocument, loads an AcroForm PDF into it, and fills it with data // using the GcPdfDocument.ImportFormDataFromXML() method. // // This method is called by the samples controller when the form prepared by this sample // is submitted by the user. The samples controller parses the client response and builds // the 'values' collection filling it with the submitted field values, then calls // this method to prepare the XML, imports it into a newly created PDF, and returns // the resulting PDF to the controller, which sends it back to the client. public static Stream ImportFormData(List<FieldExportEntry> values) { var pdf = new GcPdfDocument(); using var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "ImportFormXML.pdf")); pdf.Load(fs); using (var ms = new MemoryStream()) { SaveFieldsToXML(values, ms); ms.Seek(0, SeekOrigin.Begin); pdf.ImportFormDataFromXML(ms); } var outMs = new MemoryStream(); pdf.Save(outMs); outMs.Seek(0, SeekOrigin.Begin); return outMs; }
// Represents a form field and its value(s) for export to XML. public class FieldExportEntry { public string Name { get; set; } public List<string> Values { get; set; } // Note: this sample does not support child fields: // public List<FieldTreeNode> Children { get; set; } }
// Saves the fields and their values to a stream. // // This method is similar to GcPdfDocument.ExportFormDataToXML(), with the following // important limitations: // - it does not support child fields (field.Children collection); // - it does not handle fields with names that are not valid XML names (xfdf:original). public static void SaveFieldsToXML(List<FieldExportEntry> values, Stream stream) { var xws = new XmlWriterSettings() { Indent = true, CloseOutput = false, Encoding = Encoding.UTF8, }; using XmlWriter xw = XmlWriter.Create(stream, xws); xw.WriteStartElement("fields"); xw.WriteAttributeString("xmlns", "xfdf", null, "http://ns.adobe.com/xfdf-transition/"); foreach (var ftn in values) { xw.WriteStartElement(ftn.Name); foreach (var v in ftn.Values) { xw.WriteStartElement("value"); // NOTE: the values in the array are formed by the client PDF viewer, // and it represents 'on' checkbox values as 'true', while ImportFormDataFromXML // expects 'on' values to be represented as "Yes" (that's how ExportFormDataToXML // works, similar to Acrobat). This here is a quick and dirty hack just for the // sake of this sample: xw.WriteString(v == "true" ? "Yes" : v); xw.WriteEndElement(); } xw.WriteEndElement(); } xw.WriteEndElement(); } }}