FormDataSubmit.cs
  1. //
  2. // This code is part of Document Solutions for PDF demos.
  3. // Copyright (c) MESCIUS inc. All rights reserved.
  4. //
  5. using System.Drawing;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Xml;
  9. using System.Text;
  10. using System.Collections.Generic;
  11. using GrapeCity.Documents.Pdf;
  12. using GrapeCity.Documents.Pdf.AcroForms;
  13. using GrapeCity.Documents.Pdf.Actions;
  14. using GrapeCity.Documents.Pdf.Annotations;
  15. using GrapeCity.Documents.Text;
  16.  
  17. namespace DsPdfWeb.Demos
  18. {
  19. // This sample creates an AcroForm PDF that can be submitted to the server.
  20. // The server then uses the (new in DsPdf v3) GcPdfDocument.ImportFormDataFromCollection()
  21. // method to import the submitted data into a PDF that contains a similarly structured
  22. // PDF form, and sends the form filled with user provided data back to the client.
  23. //
  24. // Note that the produced PDF with filled form fields
  25. // is shown in the client browser's default PDF viewer.
  26. //
  27. // This sample is similar to the now obsolete FormSubmitXml sample,
  28. // but the server side is much simpler as it uses the new ImportFormDataFromCollection()
  29. // method that accepts a data structure very similar to how data is sent from the client form,
  30. // so almost no code is needed to manipulate that data.
  31. // See also the FormSubmit sample.
  32. public class FormDataSubmit
  33. {
  34. public int CreatePDF(Stream stream)
  35. {
  36. var doc = new GcPdfDocument();
  37. var page = doc.NewPage();
  38.  
  39. var rc = Common.Util.AddNote(
  40. "Fill the fields in the form and click 'Submit' to send it back to the server. " +
  41. "The sample server will use the GcPdfDocument.ImportFormDataFromCollection() method " +
  42. "to import the submitted data into a different but compatible PDF form, " +
  43. "and the filled form will be sent back to your browser. " +
  44. "Note that the filled form is opened in the browser's default PDF viewer, " +
  45. "and does not have the 'Submit' and 'Reset' buttons.",
  46. page);
  47.  
  48. var g = page.Graphics;
  49. var tf = new TextFormat() { Font = StandardFonts.Times, FontSize = 14 };
  50. var ip = new PointF(72, rc.Bottom + 36);
  51. float fldOffset = 72 * 2 + 46;
  52. float fldHeight = tf.FontSize * 1.2f;
  53. float dY = 32;
  54.  
  55. // Text field:
  56. g.DrawString("First name:", tf, ip);
  57. var fldFirstName = new TextField() { Name = "FirstName", Value = "John" };
  58. fldFirstName.Widget.Page = page;
  59. fldFirstName.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight);
  60. fldFirstName.Widget.DefaultAppearance.Font = tf.Font;
  61. fldFirstName.Widget.DefaultAppearance.FontSize = tf.FontSize;
  62. doc.AcroForm.Fields.Add(fldFirstName);
  63. ip.Y += dY;
  64.  
  65. // Text field:
  66. g.DrawString("Last name:", tf, ip);
  67. var fldLastName = new TextField() { Name = "LastName", Value = "Smith" };
  68. fldLastName.Widget.Page = page;
  69. fldLastName.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight);
  70. fldLastName.Widget.DefaultAppearance.Font = tf.Font;
  71. fldLastName.Widget.DefaultAppearance.FontSize = tf.FontSize;
  72. doc.AcroForm.Fields.Add(fldLastName);
  73. ip.Y += dY;
  74.  
  75. // Checkbox:
  76. g.DrawString("Subscribe to Mailing List:", tf, ip);
  77. var fldCheckbox = new CheckBoxField() { Name = "Subscribe", Checked = true };
  78. fldCheckbox.Widget.Page = page;
  79. fldCheckbox.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, fldHeight, fldHeight);
  80. doc.AcroForm.Fields.Add(fldCheckbox);
  81. ip.Y += dY;
  82.  
  83. // Multiline TextBox:
  84. g.DrawString("Additional information:", tf, ip);
  85. var fldAdditionalInfo = new TextField() { Name = "AdditionalInfo", Multiline = true };
  86. fldAdditionalInfo.Widget.Page = page;
  87. fldAdditionalInfo.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight * 2);
  88. fldAdditionalInfo.Widget.DefaultAppearance.Font = tf.Font;
  89. fldAdditionalInfo.Widget.DefaultAppearance.FontSize = tf.FontSize;
  90. doc.AcroForm.Fields.Add(fldAdditionalInfo);
  91. ip.Y += dY * 2;
  92.  
  93. // Submit form button:
  94. var btnSubmit = new PushButtonField();
  95. btnSubmit.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72, fldHeight);
  96. btnSubmit.Widget.ButtonAppearance.Caption = "Submit";
  97. btnSubmit.Widget.Highlighting = HighlightingMode.Invert;
  98. btnSubmit.Widget.Page = page;
  99.  
  100. // The URL for the submission:
  101. btnSubmit.Widget.Activate = new ActionSubmitForm("/Samples/HandleFormDataSubmit");
  102. doc.AcroForm.Fields.Add(btnSubmit);
  103.  
  104. // Reset form button:
  105. var btnReset = new PushButtonField();
  106. btnReset.Widget.Rect = new RectangleF(ip.X + fldOffset + 72 * 1.5f, ip.Y, 72, fldHeight);
  107. btnReset.Widget.ButtonAppearance.Caption = "Reset";
  108. btnReset.Widget.Highlighting = HighlightingMode.Invert;
  109. btnReset.Widget.Page = page;
  110. btnReset.Widget.Activate = new ActionResetForm();
  111. doc.AcroForm.Fields.Add(btnReset);
  112. ip.Y += dY;
  113.  
  114. // Done:
  115. doc.Save(stream);
  116. return doc.Pages.Count;
  117. }
  118.  
  119. //
  120. // NOTE: the code below is used by the web sample browser controller when the form
  121. // prepared by this sample is submitted, it is not directly called by the CreatePDF() method.
  122. //
  123.  
  124. // Creates a GcPdfDocument, loads an AcroForm PDF into it, and fills it with data
  125. // using the GcPdfDocument.ImportFormDataFromCollection() method.
  126. //
  127. // This method is called by the samples controller when the form prepared by this sample
  128. // is submitted by the user. The controller method converts the IFormCollection that it
  129. // receives to an array or key value pairs, where keys are field names and values are
  130. // lists of string values, then calls this method to import the values into the
  131. // compatible ImportFormXML.pdf PDF form. That form is then sent back to the client.
  132. //
  133. // The controller code that calls this method looks like this:
  134. //
  135. // public IActionResult HandleFormDataSubmit(IFormCollection fields)
  136. // {
  137. // var values = fields.ToList();
  138. // var fieldValues = values.Select(kvp_ => new KeyValuePair<string, IList<string>>(kvp_.Key, kvp_.Value.ToArray())).ToArray();
  139. // var ms = Samples.FormDataSubmit.ImportFormData(fieldValues);
  140. // var result = new FileStreamResult(ms, "application/pdf");
  141. // return result;
  142. // }
  143. public static Stream ImportFormData(KeyValuePair<string, IList<string>>[] fieldValues)
  144. {
  145. var pdf = new GcPdfDocument();
  146. using var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "ImportFormFromCollection.pdf"));
  147. // Load compatible empty form:
  148. pdf.Load(fs);
  149. // Import submitted data:
  150. pdf.ImportFormDataFromCollection(fieldValues);
  151. // Done:
  152. var outMs = new MemoryStream();
  153. pdf.Save(outMs);
  154. outMs.Seek(0, SeekOrigin.Begin);
  155. return outMs;
  156. }
  157. }
  158. }
  159.