'--------------------------------------------------------------------------------------- ' Copyright (c) 2001-2008 by PDFTron Systems Inc. All Rights Reserved. ' Consult legal.txt regarding legal and license information. '--------------------------------------------------------------------------------------- Imports System Imports pdftron Imports pdftron.Common Imports pdftron.Filters Imports pdftron.SDF Imports pdftron.PDF '--------------------------------------------------------------------------------------- ' This sample illustrates basic PDFNet capabilities related to interactive ' forms (also known as AcroForms). '--------------------------------------------------------------------------------------- Module Module1 Sub Main() PDFNet.Initialize() PDFNet.SetResourcesPath("../../../../resources") ' Relative path to the folder containing test files. ' Dim input_path As String = "../../../TestFiles/" Dim output_path As String = "../../../TestFiles/Output/" Try '---------------------------------------------------------------------------------- ' Example 1: Programatically create new Form Fields and Widget Annotations. '---------------------------------------------------------------------------------- Dim doc As PDFDoc = New PDFDoc Dim blank_page As Page = doc.PageCreate() ' Create a blank page and some new fields (aka "AcroForms"). ' Create new fields. Dim emp_first_name As Field = doc.FieldCreate("employee.name.first", _ Field.Type.e_text, doc.CreateIndirectString("John")) Dim emp_last_name As Field = doc.FieldCreate("employee.name.last", _ Field.Type.e_text, doc.CreateIndirectString("Doe")) Dim emp_last_check1 As Field = doc.FieldCreate("employee.name.check1", _ Field.Type.e_check, doc.CreateIndirectName("Yes")) Dim submit As Field = doc.FieldCreate("submit", _ Field.Type.e_button) ' Create page annotations for the above fields. Dim sdfdoc As SDFDoc = doc.GetSDFDoc() ' Create text annotations Dim annot1 As Annot = Annot.CreateWidget(sdfdoc, New Rect(50, 550, 350, 600), emp_first_name) Dim annot2 As Annot = Annot.CreateWidget(sdfdoc, New Rect(50, 450, 350, 500), emp_last_name) ' Create check-box annotation Dim annot3 As Annot = Annot.CreateWidget(sdfdoc, New Rect(64, 356, 120, 410), emp_last_check1) ' Set the annotation appearance for the "Yes" state... annot3.SetAppearance(CreateCheckmarkAppearance(doc), Annot.AnnotationState.e_normal, "Yes") ' Create button annotation Dim annot4 As Annot = Annot.CreateWidget(sdfdoc, New Rect(64, 284, 163, 320), submit) ' Set the annotation appearances for the down and up state... annot4.SetAppearance(CreateButtonAppearance(doc, False), Annot.AnnotationState.e_normal) annot4.SetAppearance(CreateButtonAppearance(doc, True), Annot.AnnotationState.e_down) ' Create 'SubmitForm' action. The action will be linked to the button. Dim url As FileSpec = FileSpec.CreateURL(sdfdoc, "http://www.pdftron.com") Dim button_action As Action = Action.CreateSubmitForm(url) ' Associate the above action with 'Down' event in annotations action dictionary. Dim annot_action As Obj = annot4.GetSDFObj().PutDict("AA") annot_action.Put("D", button_action.GetSDFObj()) blank_page.AnnotPushBack(annot1) ' Add annotations to the page blank_page.AnnotPushBack(annot2) blank_page.AnnotPushBack(annot3) blank_page.AnnotPushBack(annot4) doc.PagePushBack(blank_page) ' Add the page as the last page in the document. ' If you are not satisfied with the look of default auto-generated appearance ' streams you can delete "AP" entry from the Widget annotation and set ' "NeedAppearances" flag in AcroForm dictionary: ' doc.GetAcroForm().Put("NeedAppearances", Obj.CreateBool(true)) ' This will force viewer application to auto-generate new appearance streams ' every time the document is opened. ' ' Alternatively you can generate custom annotation appearance using ElementWriter ' and then set the "AP" entry in the widget dictionary to the new appearance ' stream. ' ' Yet another option is to pre-populate field entries with dummy text. When ' you edit the field values using PDFNet the new field appearances will match ' the old ones. doc.RefreshFieldAppearances() doc.Save(output_path + "forms_test1.pdf", 0) doc.Close() Console.WriteLine("Done.") '---------------------------------------------------------------------------------- ' Example 2: ' Fill-in forms / Modify values of existing fields. ' Traverse all form fields in the document (and print out their names). ' Search for specific fields in the document. '---------------------------------------------------------------------------------- Dim doc4 As PDFDoc = New PDFDoc(output_path + "forms_test1.pdf") doc4.InitSecurityHandler() Dim itr As FieldIterator = doc4.GetFieldIterator() While itr.HasNext() Console.WriteLine("Field name: {0}", itr.Current().GetName()) Console.WriteLine("Field partial name: {0}", itr.Current().GetPartialName()) Console.Write("Field type: ") Dim field As Field = itr.Current() Dim type As Field.Type = field.GetType() If type = Field.Type.e_button Then Console.WriteLine("Button") ElseIf type = Field.Type.e_radio Then Console.WriteLine("Radio button") ElseIf type = Field.Type.e_check Then Console.WriteLine("Check box") field.SetValue("Yes") ElseIf type = Field.Type.e_text Then Console.WriteLine("Text") ' Edit all variable text in the document Dim old_value As String = "none" If Not field.GetValue() Is Nothing Then old_value = field.GetValueAsString() End If field.SetValue("This is a new value. The old one was: ".Concat(old_value)) ElseIf type = Field.Type.e_choice Then Console.WriteLine("Choice") ElseIf type = Field.Type.e_signature Then Console.WriteLine("Signature") End If Console.WriteLine("------------------------------") itr.Next() End While ' Search for a specific field Dim fld As Field = doc4.GetField("employee.name.first") If Not fld Is Nothing Then Console.WriteLine("Field search for {0} was successful: ", fld.GetName(), fld.GetValueAsString()) Else Console.WriteLine("Field search failed.") End If ' Regenerate field appearances. doc4.RefreshFieldAppearances() doc4.Save(output_path + "forms_test_edit.pdf", 0) doc4.Close() Console.WriteLine("Done.") '---------------------------------------------------------------------------------- ' Sample: Form templating ' Replicate pages and form data within a document. Then rename field names to make ' them unique. '---------------------------------------------------------------------------------- Dim doc3 As PDFDoc = New PDFDoc(output_path + "forms_test1.pdf") doc3.InitSecurityHandler() Dim src_page3 As Page = doc3.GetPage(1) doc3.PagePushBack(src_page3) ' Append several copies of the second page doc3.PagePushBack(src_page3) ' Note that forms are successfully copied doc3.PagePushBack(src_page3) ' Now we rename fields in order to make every field unique. ' You can use this technique for dynamic template filling where you have a 'master' ' form page that should be replicated, but with unique field names on every page. RenameAllFields(doc3, "employee.name.first") RenameAllFields(doc3, "employee.name.last") RenameAllFields(doc3, "employee.name.check1") doc3.RefreshFieldAppearances() doc3.Save(output_path + "forms_test1_cloned.pdf", 0) doc3.Close() Console.WriteLine("Done.") '---------------------------------------------------------------------------------- ' Sample: ' Flatten all form fields in a document. ' Note that this sample is intended to show that it is possible to flatten ' individual fields. PDFNet provides a utility function PDFDoc::FlattenFields() ' that will automatically flatten all fields. '---------------------------------------------------------------------------------- Dim doc5 As PDFDoc = New PDFDoc(output_path + "forms_test1.pdf") doc5.InitSecurityHandler() Dim autoflat As Boolean = True If (autoflat) Then doc5.FlattenFields() Else ' Manual flattening Dim pitr As PageIterator = doc5.GetPageIterator() While pitr.HasNext() Dim page As Page = pitr.Current() Dim annots As Obj = page.GetAnnots() If Not annots Is Nothing Then ' Look for all widget annotations (in reverse order) Dim i As Integer = annots.Size() - 1 While i >= 0 Dim subtype As String = annots.GetAt(i).Get("Subtype").Value().GetName() If subtype.Equals("Widget") Then Dim field As Field = New Field(annots.GetAt(i)) field.Flatten(page) ' Another way of making a read only field is by modifying ' field's e_read_only flag: ' field.SetFlag(Field.FieldFlag.e_read_only, true) End If i = i - 1 End While End If pitr.Next() End While End If doc5.Save(output_path + "forms_test1_flattened.pdf", 0) doc5.Close() Console.WriteLine("Done.") Catch ex As PDFNetException Console.WriteLine(ex.Message) Catch ex As Exception MsgBox(ex.Message) End Try PDFNet.Terminate() End Sub Sub RenameAllFields(ByRef d As PDFDoc, ByVal name As String) Dim fld As Field = d.GetField(name) Dim counter As Integer = 0 While Not fld Is Nothing fld.Rename(name + counter.ToString()) fld = d.GetField(name) counter = counter + 1 End While End Sub Function CreateCheckmarkAppearance(ByRef doc As PDFDoc) As Obj ' Create a checkmark appearance stream ------------------------------------ Dim build As ElementBuilder = New ElementBuilder Dim writer As ElementWriter = New ElementWriter writer.Begin(doc.GetSDFDoc()) writer.WriteElement(build.CreateTextBegin()) ' other options are circle ("l"), diamond ("H"), cross ("\x35") ' See section D.4 "ZapfDingbats Set and Encoding" in PDF Reference Manual for ' the complete graphical map for ZapfDingbats font. Dim checkmark As Element = build.CreateTextRun("4", Font.Create(doc, Font.StandardType1Font.e_zapf_dingbats), 1) writer.WriteElement(checkmark) writer.WriteElement(build.CreateTextEnd()) Dim stm As Obj = writer.End() ' Set the bounding box stm.PutRect("BBox", -0.2, -0.2, 1, 1) stm.PutName("Subtype", "Form") Return stm End Function Function CreateButtonAppearance(ByRef doc As PDFDoc, ByVal button_down As Boolean) As Obj ' Create a button appearance stream ------------------------------------ Dim build As ElementBuilder = New ElementBuilder Dim writer As ElementWriter = New ElementWriter writer.Begin(doc.GetSDFDoc()) ' Draw background Dim element As Element = build.CreateRect(0, 0, 101, 37) element.SetPathFill(True) element.SetPathStroke(False) element.GetGState().SetFillColorSpace(ColorSpace.CreateDeviceGray()) element.GetGState().SetFillColor(New ColorPt(0.75)) writer.WriteElement(element) ' Draw 'Submit' text writer.WriteElement(build.CreateTextBegin()) element = build.CreateTextRun("Submit", Font.Create(doc, Font.StandardType1Font.e_helvetica_bold), 12) element.GetGState().SetFillColor(New ColorPt(0)) If (button_down) Then element.SetTextMatrix(1, 0, 0, 1, 33, 10) Else element.SetTextMatrix(1, 0, 0, 1, 30, 13) End If writer.WriteElement(element) writer.WriteElement(build.CreateTextEnd()) Dim stm As Obj = writer.End() ' Set the bounding box stm.PutRect("BBox", 0, 0, 101, 37) stm.PutName("Subtype", "Form") Return stm End Function End Module