FormSubmitXml.vb
  1. ''
  2. '' This code is part of Document Solutions for PDF demos.
  3. '' Copyright (c) MESCIUS inc. All rights reserved.
  4. ''
  5. Imports System.Drawing
  6. Imports System.IO
  7. Imports System.Linq
  8. Imports System.Xml
  9. Imports System.Text
  10. Imports System.Collections.Generic
  11. Imports GrapeCity.Documents.Pdf
  12. Imports GrapeCity.Documents.Pdf.AcroForms
  13. Imports GrapeCity.Documents.Pdf.Actions
  14. Imports GrapeCity.Documents.Pdf.Annotations
  15. Imports GrapeCity.Documents.Text
  16.  
  17. '' NOTE: This sample is obsolete as of DsPdf v3. Please see the new FormDataSubmit
  18. '' sample for a better solution.
  19. ''
  20. '' This sample creates an AcroForm PDF that can be submitted to the server.
  21. '' It relies on the server to put the submitted data into an XML,
  22. '' import that XML into a PDF containing a similar form,
  23. '' And send the form with loaded data back to the client.
  24. '' Note that the produced PDF with filled form fields
  25. '' Is shown in the client browser's default PDF viewer.
  26. '' The code Is similar to FormSubmit.
  27. Public Class FormSubmitXml
  28. Function CreatePDF(ByVal stream As Stream) As Integer
  29. Dim doc = New GcPdfDocument()
  30. Dim page = doc.NewPage()
  31.  
  32. Dim rc = Util.AddNote("Fill the fields in the form and click 'Submit' to send it back to the server. " +
  33. "The sample server will put the submitted data into an XML, feed that XML" +
  34. "to a PDF with a different but compatible form, and send the resulting form" +
  35. "filled with the submitted data back to your browser." +
  36. "Note that the form with the submitted data is opened in the browser's default PDF viewer," +
  37. "and does not have the 'Submit' and 'Reset' buttons.", page)
  38.  
  39. Dim g = page.Graphics
  40. Dim tf = New TextFormat() With {.Font = StandardFonts.Times, .FontSize = 14}
  41. Dim ip = New PointF(72, rc.Bottom + 36)
  42. Dim fldOffset = 72 * 2 + 46
  43. Dim fldHeight = tf.FontSize * 1.2F
  44. Dim dY = 32
  45.  
  46. '' Text field
  47. g.DrawString("First name:", tf, ip)
  48. Dim fldFirstName = New TextField() With {.Name = "FirstName", .Value = "John"}
  49. fldFirstName.Widget.Page = page
  50. fldFirstName.Widget.Rect = New RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight)
  51. fldFirstName.Widget.DefaultAppearance.Font = tf.Font
  52. fldFirstName.Widget.DefaultAppearance.FontSize = tf.FontSize
  53. doc.AcroForm.Fields.Add(fldFirstName)
  54. ip.Y += dY
  55.  
  56. '' Text field
  57. g.DrawString("Last name:", tf, ip)
  58. Dim fldLastName = New TextField() With {.Name = "LastName", .Value = "Smith"}
  59. fldLastName.Widget.Page = page
  60. fldLastName.Widget.Rect = New RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight)
  61. fldLastName.Widget.DefaultAppearance.Font = tf.Font
  62. fldLastName.Widget.DefaultAppearance.FontSize = tf.FontSize
  63. doc.AcroForm.Fields.Add(fldLastName)
  64. ip.Y += dY
  65.  
  66. '' Checkbox
  67. g.DrawString("Subscribe to Mailing List:", tf, ip)
  68. Dim fldCheckbox = New CheckBoxField() With {.Name = "Subscribe", .Checked = True}
  69. fldCheckbox.Widget.Page = page
  70. fldCheckbox.Widget.Rect = New RectangleF(ip.X + fldOffset, ip.Y, fldHeight, fldHeight)
  71. doc.AcroForm.Fields.Add(fldCheckbox)
  72. ip.Y += dY
  73.  
  74. '' Multiline TextBox
  75. g.DrawString("Additional information:", tf, ip)
  76. Dim fldAdditionalInfo = New TextField() With {.Name = "AdditionalInfo", .Multiline = True}
  77. fldAdditionalInfo.Widget.Page = page
  78. fldAdditionalInfo.Widget.Rect = New RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight * 2)
  79. fldAdditionalInfo.Widget.DefaultAppearance.Font = tf.Font
  80. fldAdditionalInfo.Widget.DefaultAppearance.FontSize = tf.FontSize
  81. doc.AcroForm.Fields.Add(fldAdditionalInfo)
  82. ip.Y += dY * 2
  83.  
  84. '' Submit form button:
  85. Dim btnSubmit = New PushButtonField()
  86. btnSubmit.Widget.Rect = New RectangleF(ip.X + fldOffset, ip.Y, 72, fldHeight)
  87. btnSubmit.Widget.ButtonAppearance.Caption = "Submit"
  88. btnSubmit.Widget.Highlighting = HighlightingMode.Invert
  89. btnSubmit.Widget.Page = page
  90.  
  91. '' The URL for the submission
  92. btnSubmit.Widget.Activate = New ActionSubmitForm("/Samples/HandleFormSubmitXml")
  93. doc.AcroForm.Fields.Add(btnSubmit)
  94.  
  95. '' Reset form button:
  96. Dim btnReset = New PushButtonField()
  97. btnReset.Widget.Rect = New RectangleF(ip.X + fldOffset + 72 * 1.5F, ip.Y, 72, fldHeight)
  98. btnReset.Widget.ButtonAppearance.Caption = "Reset"
  99. btnReset.Widget.Highlighting = HighlightingMode.Invert
  100. btnReset.Widget.Page = page
  101. btnReset.Widget.Activate = New ActionResetForm()
  102. doc.AcroForm.Fields.Add(btnReset)
  103. ip.Y += dY
  104.  
  105. '' Done
  106. doc.Save(stream)
  107. Return doc.Pages.Count
  108. End Function
  109.  
  110. ''
  111. '' NOTE: the code below Is used by the web sample browser controller When the form
  112. '' prepared by this sample Is submitted, it Is Not directly called by the CreatePDF() method.
  113. ''
  114.  
  115. '' Creates a GcPdfDocument, loads an AcroForm PDF into it, And fills it with data
  116. '' using the GcPdfDocument.ImportFormDataFromXML() method.
  117. ''
  118. '' This method Is called by the samples controller when the form prepared by this sample
  119. '' Is submitted by the user. The samples controller parses the client response And builds
  120. '' the 'values' collection filling it with the submitted field values, then calls
  121. '' this method to prepare the XML, imports it into a newly created PDF, And returns
  122. '' the resulting PDF to the controller, which sends it back to the client.
  123. Public Shared Function ImportFormData(ByVal values As List(Of FieldExportEntry)) As Stream
  124. Dim pdf = New GcPdfDocument()
  125. Using fs = New FileStream(Path.Combine("Resources", "PDFs", "ImportFormXML.pdf"), FileMode.Open, FileAccess.Read)
  126. pdf.Load(fs)
  127. Using ms = New MemoryStream()
  128. SaveFieldsToXML(values, ms)
  129. ms.Seek(0, SeekOrigin.Begin)
  130. pdf.ImportFormDataFromXML(ms)
  131. End Using
  132. Dim outMs = New MemoryStream()
  133. pdf.Save(outMs)
  134. outMs.Seek(0, SeekOrigin.Begin)
  135. Return outMs
  136. End Using
  137. End Function
  138.  
  139. '' Represents a form field And its value(s) for export to XML.
  140. Public Class FieldExportEntry
  141. Public Property Name As String
  142. Public Property Values As List(Of String)
  143. '' Note: this sample does Not support child fields:
  144. '' public List<FieldTreeNode> Children { get set }
  145. End Class
  146.  
  147. '' Saves the fields And their values to a stream.
  148. ''
  149. '' This method Is similar to GcPdfDocument.ExportFormDataToXML(), with the following
  150. '' important limitations:
  151. '' - it does Not support child fields (field.Children collection)
  152. '' - it does Not handle fields with names that are Not valid XML names (xfdf:original).
  153. Public Shared Sub SaveFieldsToXML(ByVal values As List(Of FieldExportEntry), ByVal stream As Stream)
  154. Dim xws = New XmlWriterSettings() With
  155. {
  156. .Indent = True,
  157. .CloseOutput = False,
  158. .Encoding = Encoding.UTF8
  159. }
  160. Using xw = XmlWriter.Create(stream, xws)
  161. xw.WriteStartElement("fields")
  162. xw.WriteAttributeString("xmlns", "xfdf", Nothing, "http:''ns.adobe.com/xfdf-transition/")
  163. For Each ftn In values
  164. xw.WriteStartElement(ftn.Name)
  165. For Each v In ftn.Values
  166. xw.WriteStartElement("value")
  167. '' NOTE: the values In the array are formed by the client PDF viewer,
  168. '' And it represents 'on' checkbox values as 'true', while ImportFormDataFromXML
  169. '' expects 'on' values to be represented as "Yes" (that's how ExportFormDataToXML
  170. '' works, similar to Acrobat). This here Is a quick And dirty hack just for the
  171. '' sake of this sample:
  172. If v = "true" Then
  173. xw.WriteString("Yes")
  174. Else
  175. xw.WriteString(v)
  176. End If
  177. xw.WriteEndElement()
  178. Next
  179. xw.WriteEndElement()
  180. Next
  181. xw.WriteEndElement()
  182. End Using
  183. End Sub
  184. End Class
  185.