Sample C# code for using Apryse SDK with interactive forms (also known as AcroForms). Capabilities include programatically creating new fields and widget annotations, form filling, modifying existing field values, form templating, and flattening form fields. Learn more about our Server SDK and PDF Data Extraction SDK Capabilities.
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6using System;
7using System.Collections.Generic;
8using pdftron;
9using pdftron.Common;
10using pdftron.SDF;
11using pdftron.PDF;
12using pdftron.PDF.Annots;
13
14namespace FormsTestCS
15{
16 /// <summary>
17 ///---------------------------------------------------------------------------------------
18 /// This sample illustrates basic PDFNet capabilities related to interactive
19 /// forms (also known as AcroForms).
20 ///---------------------------------------------------------------------------------------
21 /// </summary>
22 class Class1
23 {
24 private static pdftron.PDFNetLoader pdfNetLoader = pdftron.PDFNetLoader.Instance();
25 static Class1() {}
26
27 static void Main(string[] args)
28 {
29 PDFNet.Initialize(PDFTronLicense.Key);
30
31 // Relative path to the folder containing test files.
32 // string input_path = "../../../../TestFiles/";
33 string output_path = "../../../../TestFiles/Output/";
34
35 // The vector used to store the name and count of all fields.
36 // This is used later on to clone the fields
37 Dictionary<string, int> field_names = new Dictionary<string, int>();
38
39 //----------------------------------------------------------------------------------
40 // Example 1: Programatically create new Form Fields and Widget Annotations.
41 //----------------------------------------------------------------------------------
42 try
43 {
44 using (PDFDoc doc = new PDFDoc())
45 {
46 // Create a blank new page and add some form fields.
47 Page blank_page = doc.PageCreate();
48
49 // Text Widget Creation
50 // Create an empty text widget with black text.
51 TextWidget text1 = TextWidget.Create(doc, new Rect(110, 700, 380, 730));
52 text1.SetText("Basic Text Field");
53 text1.RefreshAppearance();
54 blank_page.AnnotPushBack(text1);
55 // Create a vertical text widget with blue text and a yellow background.
56 TextWidget text2 = TextWidget.Create(doc, new Rect(50, 400, 90, 730));
57 text2.SetRotation(90);
58 // Set the text content.
59 text2.SetText(" ****Lucky Stars!****");
60 // Set the font type, text color, font size, border color and background color.
61 text2.SetFont(Font.Create(doc, Font.StandardType1Font.e_helvetica_oblique));
62 text2.SetFontSize(28);
63 text2.SetTextColor(new ColorPt(0, 0, 1), 3);
64 text2.SetBorderColor(new ColorPt(0, 0, 0), 3);
65 text2.SetBackgroundColor(new ColorPt(1, 1, 0), 3);
66 text2.RefreshAppearance();
67 // Add the annotation to the page.
68 blank_page.AnnotPushBack(text2);
69 // Create two new text widget with Field names employee.name.first and employee.name.last
70 // This logic shows how these widgets can be created using either a field name string or
71 // a Field object
72 TextWidget text3 = TextWidget.Create(doc, new Rect(110, 660, 380, 690), "employee.name.first");
73 text3.SetText("Levi");
74 text3.SetFont(Font.Create(doc, Font.StandardType1Font.e_times_bold));
75 text3.RefreshAppearance();
76 blank_page.AnnotPushBack(text3);
77 Field emp_last_name = doc.FieldCreate("employee.name.last", Field.Type.e_text, "Ackerman");
78 TextWidget text4 = TextWidget.Create(doc, new Rect(110, 620, 380, 650), emp_last_name);
79 text4.SetFont(Font.Create(doc, Font.StandardType1Font.e_times_bold));
80 text4.RefreshAppearance();
81 blank_page.AnnotPushBack(text4);
82
83 // Signature Widget Creation (unsigned)
84 SignatureWidget signature1 = SignatureWidget.Create(doc, new Rect(110, 560, 260, 610));
85 signature1.RefreshAppearance();
86 blank_page.AnnotPushBack(signature1);
87
88 // CheckBox Widget Creation
89 // Create a check box widget that is not checked.
90 CheckBoxWidget check1 = CheckBoxWidget.Create(doc, new Rect(140, 490, 170, 520));
91 check1.RefreshAppearance();
92 blank_page.AnnotPushBack(check1);
93 // Create a check box widget that is checked.
94 CheckBoxWidget check2 = CheckBoxWidget.Create(doc, new Rect(190, 490, 250, 540), "employee.name.check1");
95 check2.SetBackgroundColor(new ColorPt(1, 1, 1), 3);
96 check2.SetBorderColor(new ColorPt(0, 0, 0), 3);
97 // Check the widget (by default it is unchecked).
98 check2.SetChecked(true);
99 check2.RefreshAppearance();
100 blank_page.AnnotPushBack(check2);
101
102 // PushButton Widget Creation
103 PushButtonWidget pushbutton1 = PushButtonWidget.Create(doc, new Rect(380, 490, 520, 540));
104 pushbutton1.SetTextColor(new ColorPt(1, 1, 1), 3);
105 pushbutton1.SetFontSize(36);
106 pushbutton1.SetBackgroundColor(new ColorPt(0, 0, 0), 3);
107 // Add a caption for the pushbutton.
108 pushbutton1.SetStaticCaptionText("PushButton");
109 pushbutton1.RefreshAppearance();
110 blank_page.AnnotPushBack(pushbutton1);
111
112 // ComboBox Widget Creation
113 ComboBoxWidget combo1 = ComboBoxWidget.Create(doc, new Rect(280, 560, 580, 610));
114 // Add options to the combobox widget.
115 combo1.AddOption("Combo Box No.1");
116 combo1.AddOption("Combo Box No.2");
117 combo1.AddOption("Combo Box No.3");
118 // Make one of the options in the combo box selected by default.
119 combo1.SetSelectedOption("Combo Box No.2");
120 combo1.SetTextColor(new ColorPt(1, 0, 0), 3);
121 combo1.SetFontSize(28);
122 combo1.RefreshAppearance();
123 blank_page.AnnotPushBack(combo1);
124
125 // ListBox Widget Creation
126 ListBoxWidget list1 = ListBoxWidget.Create(doc, new Rect(400, 620, 580, 730));
127 // Add one option to the listbox widget.
128 list1.AddOption("List Box No.1");
129 // Add multiple options to the listbox widget in a batch.
130 string[] list_options = new string[2] {"List Box No.2", "List Box No.3"};
131 list1.AddOptions(list_options);
132 // Select some of the options in list box as default options
133 list1.SetSelectedOptions(list_options);
134 // Enable list box to have multi-select when editing.
135 list1.GetField().SetFlag(Field.Flag.e_multiselect, true);
136 list1.SetFont(Font.Create(doc, Font.StandardType1Font.e_times_italic));
137 list1.SetTextColor(new ColorPt(1, 0, 0), 3);
138 list1.SetFontSize(28);
139 list1.SetBackgroundColor(new ColorPt(1, 1, 1), 3);
140 list1.RefreshAppearance();
141 blank_page.AnnotPushBack(list1);
142
143 // RadioButton Widget Creation
144 // Create a radio button group and add three radio buttons in it.
145 RadioButtonGroup radio_group = RadioButtonGroup.Create(doc, "RadioGroup");
146 RadioButtonWidget radiobutton1 = radio_group.Add(new Rect(140, 410, 190, 460));
147 radiobutton1.SetBackgroundColor(new ColorPt(1, 1, 0), 3);
148 radiobutton1.RefreshAppearance();
149 RadioButtonWidget radiobutton2 = radio_group.Add(new Rect(310, 410, 360, 460));
150 radiobutton2.SetBackgroundColor(new ColorPt(0, 1, 0), 3);
151 radiobutton2.RefreshAppearance();
152 RadioButtonWidget radiobutton3 = radio_group.Add(new Rect(480, 410, 530, 460));
153 // Enable the third radio button. By default the first one is selected
154 radiobutton3.EnableButton();
155 radiobutton3.SetBackgroundColor(new ColorPt(0, 1, 1), 3);
156 radiobutton3.RefreshAppearance();
157 radio_group.AddGroupButtonsToPage(blank_page);
158
159 // Custom push button annotation creation
160 PushButtonWidget custom_pushbutton1 = PushButtonWidget.Create(doc, new Rect(260, 320, 360, 360));
161 // Set the annotation appearance.
162 custom_pushbutton1.SetAppearance(CreateCustomButtonAppearance(doc, false), Annot.AnnotationState.e_normal);
163 // Create 'SubmitForm' action. The action will be linked to the button.
164 FileSpec url = FileSpec.CreateURL(doc, "http://www.pdftron.com");
165 pdftron.PDF.Action button_action = pdftron.PDF.Action.CreateSubmitForm(url);
166 // Associate the above action with 'Down' event in annotations action dictionary.
167 Obj annot_action = custom_pushbutton1.GetSDFObj().PutDict("AA");
168 annot_action.Put("D", button_action.GetSDFObj());
169 blank_page.AnnotPushBack(custom_pushbutton1);
170
171 // Add the page as the last page in the document.
172 doc.PagePushBack(blank_page);
173
174 // If you are not satisfied with the look of default auto-generated appearance
175 // streams you can delete "AP" entry from the Widget annotation and set
176 // "NeedAppearances" flag in AcroForm dictionary:
177 // doc.GetAcroForm().PutBool("NeedAppearances", true);
178 // This will force the viewer application to auto-generate new appearance streams
179 // every time the document is opened.
180 //
181 // Alternatively you can generate custom annotation appearance using ElementWriter
182 // and then set the "AP" entry in the widget dictionary to the new appearance
183 // stream.
184 //
185 // Yet another option is to pre-populate field entries with dummy text. When
186 // you edit the field values using PDFNet the new field appearances will match
187 // the old ones.
188 doc.RefreshFieldAppearances();
189
190 doc.Save(output_path + "forms_test1.pdf", 0);
191
192 Console.WriteLine("Done.");
193 }
194 }
195 catch (PDFNetException e)
196 {
197 Console.WriteLine(e.Message);
198 }
199
200 //----------------------------------------------------------------------------------
201 // Example 2:
202 // Fill-in forms / Modify values of existing fields.
203 // Traverse all form fields in the document (and print out their names).
204 // Search for specific fields in the document.
205 //----------------------------------------------------------------------------------
206 try
207 {
208 using (PDFDoc doc = new PDFDoc(output_path + "forms_test1.pdf"))
209 {
210 doc.InitSecurityHandler();
211
212 FieldIterator itr;
213 for(itr=doc.GetFieldIterator(); itr.HasNext(); itr.Next())
214 {
215 Field field = itr.Current();
216 string cur_field_name = field.GetName();
217 // Add one to the count for this field name for later processing
218 field_names[cur_field_name] = (field_names.ContainsKey(cur_field_name) ? field_names[cur_field_name] + 1 : 1);
219
220 Console.WriteLine("Field name: {0}", field.GetName());
221 Console.WriteLine("Field partial name: {0}", field.GetPartialName());
222 string str_val = field.GetValueAsString();
223
224 Console.Write("Field type: ");
225 Field.Type type = field.GetType();
226 switch(type)
227 {
228 case Field.Type.e_button:
229 Console.WriteLine("Button");
230 break;
231 case Field.Type.e_radio:
232 Console.WriteLine("Radio button: Value = " + str_val);
233 break;
234 case Field.Type.e_check:
235 field.SetValue(true);
236 Console.WriteLine("Check box: Value = " + str_val);
237 break;
238 case Field.Type.e_text:
239 {
240 Console.WriteLine("Text");
241
242 // Edit all variable text in the document
243 String old_value = "none";
244 if (field.GetValue() != null)
245 old_value = field.GetValue().GetAsPDFText();
246
247 field.SetValue("This is a new value. The old one was: " + old_value);
248 }
249 break;
250 case Field.Type.e_choice:
251 Console.WriteLine("Choice");
252 break;
253 case Field.Type.e_signature:
254 Console.WriteLine("Signature");
255 break;
256 }
257
258 Console.WriteLine("------------------------------");
259 }
260
261 // Search for a specific field
262 Field fld = doc.GetField("employee.name.first");
263 if (fld != null)
264 {
265 Console.WriteLine("Field search for {0} was successful", fld.GetName());
266 }
267 else
268 {
269 Console.WriteLine("Field search failed.");
270 }
271
272 // Regenerate field appearances.
273 doc.RefreshFieldAppearances();
274 doc.Save(output_path + "forms_test_edit.pdf", 0);
275 Console.WriteLine("Done.");
276 }
277 }
278 catch (PDFNetException e)
279 {
280 Console.WriteLine(e.Message);
281 }
282
283 //----------------------------------------------------------------------------------
284 // Sample: Form templating
285 // Replicate pages and form data within a document. Then rename field names to make
286 // them unique.
287 //----------------------------------------------------------------------------------
288 try
289 {
290 // Sample: Copying the page with forms within the same document
291 using (PDFDoc doc = new PDFDoc(output_path + "forms_test1.pdf"))
292 {
293 doc.InitSecurityHandler();
294
295 Page src_page = doc.GetPage(1);
296 doc.PagePushBack(src_page); // Append several copies of the second page
297 doc.PagePushBack(src_page); // Note that forms are successfully copied
298 doc.PagePushBack(src_page);
299 doc.PagePushBack(src_page);
300
301 // Now we rename fields in order to make every field unique.
302 // You can use this technique for dynamic template filling where you have a 'master'
303 // form page that should be replicated, but with unique field names on every page.
304 foreach (KeyValuePair<string, int> cur_field in field_names)
305 {
306 RenameAllFields(doc, cur_field.Key, cur_field.Value);
307 }
308
309 doc.Save(output_path + "forms_test1_cloned.pdf", 0);
310 Console.WriteLine("Done.");
311 }
312 }
313 catch (PDFNetException e)
314 {
315 Console.WriteLine(e.Message);
316 }
317
318 //----------------------------------------------------------------------------------
319 // Sample:
320 // Flatten all form fields in a document.
321 // Note that this sample is intended to show that it is possible to flatten
322 // individual fields. PDFNet provides a utility function PDFDoc.FlattenAnnotations()
323 // that will automatically flatten all fields.
324 //----------------------------------------------------------------------------------
325 try
326 {
327 using (PDFDoc doc = new PDFDoc(output_path + "forms_test1.pdf"))
328 {
329 doc.InitSecurityHandler();
330
331 bool auto = true;
332 if (auto)
333 {
334 doc.FlattenAnnotations();
335 }
336 else // Manual flattening
337 {
338 // Traverse all pages
339 PageIterator pitr = doc.GetPageIterator();
340 for (; pitr.HasNext(); pitr.Next())
341 {
342 Page page = pitr.Current();
343 for (int i = page.GetNumAnnots() - 1; i >= 0; --i)
344 {
345 Annot annot = page.GetAnnot(i);
346 if (annot.GetType() == Annot.Type.e_Widget)
347 {
348 annot.Flatten(page);
349 }
350 }
351 }
352 }
353
354 doc.Save(output_path + "forms_test1_flattened.pdf", 0);
355 Console.WriteLine("Done.");
356 }
357 }
358 catch (PDFNetException e)
359 {
360 Console.WriteLine(e.Message);
361 }
362 PDFNet.Terminate();
363 }
364
365 // field_nums has to be greater than 0.
366 static void RenameAllFields(PDFDoc doc, String name, int field_nums = 1)
367 {
368 Field fld = doc.GetField(name);
369 for (int counter = 1; fld != null; ++counter)
370 {
371 string field_new_name = name;
372 int update_count = System.Convert.ToInt32(Math.Ceiling(counter / (double)field_nums));
373 fld.Rename(name + "-" + update_count.ToString());
374 fld = doc.GetField(name);
375 }
376 }
377
378 static Obj CreateCustomButtonAppearance(PDFDoc doc, bool button_down)
379 {
380 // Create a button appearance stream ------------------------------------
381 using (ElementBuilder builder = new ElementBuilder())
382 using (ElementWriter writer = new ElementWriter())
383 {
384 writer.Begin(doc);
385
386 // Draw background
387 Element element = builder.CreateRect(0, 0, 101, 37);
388 element.SetPathFill(true);
389 element.SetPathStroke(false);
390 element.GetGState().SetFillColorSpace(ColorSpace.CreateDeviceGray());
391 element.GetGState().SetFillColor(new ColorPt(0.75, 0.0, 0.0));
392 writer.WriteElement(element);
393
394 // Draw 'Submit' text
395 writer.WriteElement(builder.CreateTextBegin());
396
397 element = builder.CreateTextRun("Submit", Font.Create(doc, Font.StandardType1Font.e_helvetica_bold), 12);
398 element.GetGState().SetFillColor(new ColorPt(0, 0, 0));
399
400 if (button_down)
401 element.SetTextMatrix(1, 0, 0, 1, 33, 10);
402 else
403 element.SetTextMatrix(1, 0, 0, 1, 30, 13);
404 writer.WriteElement(element);
405 writer.WriteElement(builder.CreateTextEnd());
406
407 Obj stm = writer.End();
408
409 // Set the bounding box
410 stm.PutRect("BBox", 0, 0, 101, 37);
411 stm.PutName("Subtype", "Form");
412 return stm;
413 }
414 }
415 }
416}
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6#include <PDF/PDFNet.h>
7#include <PDF/PDFDoc.h>
8#include <PDF/Annot.h>
9#include <PDF/Field.h>
10#include <PDF/Font.h>
11#include <PDF/ElementBuilder.h>
12#include <PDF/ElementWriter.h>
13#include <PDF/Annots/Widget.h>
14#include <PDF/ViewChangeCollection.h>
15#include <PDF/Annots/TextWidget.h>
16#include <PDF/Annots/CheckBoxWidget.h>
17#include <PDF/Annots/ComboBoxWidget.h>
18#include <PDF/Annots/ListBoxWidget.h>
19#include <PDF/Annots/PushButtonWidget.h>
20#include <PDF/Annots/RadioButtonWidget.h>
21#include <PDF/Annots/RadioButtonGroup.h>
22#include <PDF/Annots/SignatureWidget.h>
23#include <iostream>
24#include <map>
25#include <cmath>
26#include "../../LicenseKey/CPP/LicenseKey.h"
27
28using namespace std;
29using namespace pdftron;
30using namespace SDF;
31using namespace PDF;
32using namespace Annots;
33//---------------------------------------------------------------------------------------
34// This sample illustrates basic PDFNet capabilities related to interactive
35// forms (also known as AcroForms).
36//---------------------------------------------------------------------------------------
37
38// field_nums has to be greater than 0.
39void RenameAllFields(PDFDoc& doc, const UString& name, int field_nums = 1)
40{
41 char tmp[32];
42 FieldIterator itr = doc.GetFieldIterator(name);
43 for (int counter = 1; itr.HasNext();
44 itr = doc.GetFieldIterator(name), ++counter)
45 {
46 Field f = itr.Current();
47 int update_count = int(ceil(counter/(double)field_nums));
48 sprintf(tmp, "-%d", update_count);
49 f.Rename(name + tmp);
50 }
51}
52
53Obj CreateCustomButtonAppearance(PDFDoc& doc, bool button_down)
54{
55 // Create a button appearance stream ------------------------------------
56 ElementBuilder build;
57 ElementWriter writer;
58 writer.Begin(doc);
59
60 // Draw background
61 Element element = build.CreateRect(0, 0, 101, 37);
62 element.SetPathFill(true);
63 element.SetPathStroke(false);
64 element.GetGState().SetFillColorSpace(ColorSpace::CreateDeviceGray());
65 element.GetGState().SetFillColor(ColorPt(0.75));
66 writer.WriteElement(element);
67
68 // Draw 'Submit' text
69 writer.WriteElement(build.CreateTextBegin());
70 {
71 const char* text = "Submit";
72 element = build.CreateTextRun(text, UInt32(strlen(text)), Font::Create(doc, PDF::Font::e_helvetica_bold), 12);
73 element.GetGState().SetFillColor(ColorPt(0));
74
75 if (button_down)
76 element.SetTextMatrix(1, 0, 0, 1, 33, 10);
77 else
78 element.SetTextMatrix(1, 0, 0, 1, 30, 13);
79 writer.WriteElement(element);
80 }
81 writer.WriteElement(build.CreateTextEnd());
82
83 Obj stm = writer.End();
84
85 // Set the bounding box
86 stm.PutRect("BBox", 0, 0, 101, 37);
87 stm.PutName("Subtype","Form");
88 return stm;
89}
90
91int main(int argc, char *argv[])
92{
93 int ret = 0;
94 PDFNet::Initialize(LicenseKey);
95
96 // Relative path to the folder containing test files.
97 // string input_path = "../../TestFiles/";
98 string output_path = "../../TestFiles/Output/";
99
100 // The vector used to store the name and count of all fields.
101 // This is used later on to clone the fields
102 map<UString, int> field_names;
103
104 //----------------------------------------------------------------------------------
105 // Example 1: Programatically create new Form Fields and Widget Annotations.
106 //----------------------------------------------------------------------------------
107 try
108 {
109 PDFDoc doc;
110 // Create a blank new page and add some form fields.
111 Page blank_page = doc.PageCreate();
112
113 // Text Widget Creation
114 // Create an empty text widget with black text.
115 TextWidget text1 = TextWidget::Create(doc, Rect(110, 700, 380, 730));
116 text1.SetText(UString("Basic Text Field"));
117 text1.RefreshAppearance();
118 blank_page.AnnotPushBack(text1);
119 // Create a vertical text widget with blue text and a yellow background.
120 TextWidget text2 = TextWidget::Create(doc, Rect(50, 400, 90, 730));
121 text2.SetRotation(90);
122 // Set the text content.
123 text2.SetText(UString(" ****Lucky Stars!****"));
124 // Set the font type, text color, font size, border color and background color.
125 text2.SetFont(Font::Create(doc, Font::e_helvetica_oblique));
126 text2.SetFontSize(28);
127 text2.SetTextColor(ColorPt(0, 0, 1), 3);
128 text2.SetBorderColor(ColorPt(0, 0, 0), 3);
129 text2.SetBackgroundColor(ColorPt(1, 1, 0), 3);
130 text2.RefreshAppearance();
131 // Add the annotation to the page.
132 blank_page.AnnotPushBack(text2);
133 // Create two new text widget with Field names employee.name.first and employee.name.last
134 // This logic shows how these widgets can be created using either a field name string or
135 // a Field object
136 TextWidget text3 = TextWidget::Create(doc, Rect(110, 660, 380, 690), "employee.name.first");
137 text3.SetText(UString("Levi"));
138 text3.SetFont(Font::Create(doc, Font::e_times_bold));
139 text3.RefreshAppearance();
140 blank_page.AnnotPushBack(text3);
141 Field emp_last_name = doc.FieldCreate("employee.name.last", Field::e_text, "Ackerman");
142 TextWidget text4 = TextWidget::Create(doc, Rect(110, 620, 380, 650), emp_last_name);
143 text4.SetFont(Font::Create(doc, Font::e_times_bold));
144 text4.RefreshAppearance();
145 blank_page.AnnotPushBack(text4);
146
147 // Signature Widget Creation (unsigned)
148 SignatureWidget signature1 = SignatureWidget::Create(doc, Rect(110, 560, 260, 610));
149 signature1.RefreshAppearance();
150 blank_page.AnnotPushBack(signature1);
151
152 // CheckBox Widget Creation
153 // Create a check box widget that is not checked.
154 CheckBoxWidget check1 = CheckBoxWidget::Create(doc, Rect(140, 490, 170, 520));
155 check1.RefreshAppearance();
156 blank_page.AnnotPushBack(check1);
157 // Create a check box widget that is checked.
158 CheckBoxWidget check2 = CheckBoxWidget::Create(doc, Rect(190, 490, 250, 540), "employee.name.check1");
159 check2.SetBackgroundColor(ColorPt(1, 1, 1), 3);
160 check2.SetBorderColor(ColorPt(0, 0, 0), 3);
161 // Check the widget (by default it is unchecked).
162 check2.SetChecked(true);
163 check2.RefreshAppearance();
164 blank_page.AnnotPushBack(check2);
165
166 // PushButton Widget Creation
167 PushButtonWidget pushbutton1 = PushButtonWidget::Create(doc, Rect(380, 490, 520, 540));
168 pushbutton1.SetTextColor(ColorPt(1, 1, 1), 3);
169 pushbutton1.SetFontSize(36);
170 pushbutton1.SetBackgroundColor(ColorPt(0, 0, 0), 3);
171 // Add a caption for the pushbutton.
172 pushbutton1.SetStaticCaptionText("PushButton");
173 pushbutton1.RefreshAppearance();
174 blank_page.AnnotPushBack(pushbutton1);
175
176 // ComboBox Widget Creation
177 ComboBoxWidget combo1 = ComboBoxWidget::Create(doc, Rect(280, 560, 580, 610));
178 // Add options to the combobox widget.
179 combo1.AddOption("Combo Box No.1");
180 combo1.AddOption("Combo Box No.2");
181 combo1.AddOption("Combo Box No.3");
182 // Make one of the options in the combo box selected by default.
183 combo1.SetSelectedOption(UString("Combo Box No.2"));
184 combo1.SetTextColor(ColorPt(1, 0, 0), 3);
185 combo1.SetFontSize(28);
186 combo1.RefreshAppearance();
187 blank_page.AnnotPushBack(combo1);
188
189 // ListBox Widget Creation
190 ListBoxWidget list1 = ListBoxWidget::Create(doc, Rect(400, 620, 580, 730));
191 // Add one option to the listbox widget.
192 list1.AddOption("List Box No.1");
193 // Add multiple options to the listbox widget in a batch.
194 vector<UString> list_options;
195 list_options.push_back("List Box No.2");
196 list_options.push_back("List Box No.3");
197 list1.AddOptions(list_options);
198 // Select some of the options in list box as default options
199 list1.SetSelectedOptions(list_options);
200 // Enable list box to have multi-select when editing.
201 list1.GetField().SetFlag(Field::e_multiselect, true);
202 list1.SetFont(Font::Create(doc, Font::e_times_italic));
203 list1.SetTextColor(ColorPt(1, 0, 0), 3);
204 list1.SetFontSize(28);
205 list1.SetBackgroundColor(ColorPt(1, 1, 1), 3);
206 list1.RefreshAppearance();
207 blank_page.AnnotPushBack(list1);
208
209 // RadioButton Widget Creation
210 // Create a radio button group and add three radio buttons in it.
211 RadioButtonGroup radio_group = RadioButtonGroup::Create(doc, "RadioGroup");
212 RadioButtonWidget radiobutton1 = radio_group.Add(Rect(140, 410, 190, 460));
213 radiobutton1.SetBackgroundColor(ColorPt(1, 1, 0), 3);
214 radiobutton1.RefreshAppearance();
215 RadioButtonWidget radiobutton2 = radio_group.Add(Rect(310, 410, 360, 460));
216 radiobutton2.SetBackgroundColor(ColorPt(0, 1, 0), 3);
217 radiobutton2.RefreshAppearance();
218 RadioButtonWidget radiobutton3 = radio_group.Add(Rect(480, 410, 530, 460));
219 // Enable the third radio button. By default the first one is selected
220 radiobutton3.EnableButton();
221 radiobutton3.SetBackgroundColor(ColorPt(0, 1, 1), 3);
222 radiobutton3.RefreshAppearance();
223 radio_group.AddGroupButtonsToPage(blank_page);
224
225 // Custom push button annotation creation
226 PushButtonWidget custom_pushbutton1 = PushButtonWidget::Create(doc, Rect(260, 320, 360, 360));
227 // Set the annotation appearance.
228 custom_pushbutton1.SetAppearance(CreateCustomButtonAppearance(doc, false), Annot::e_normal);
229 // Create 'SubmitForm' action. The action will be linked to the button.
230 FileSpec url = FileSpec::CreateURL(doc, "http://www.pdftron.com");
231 Action button_action = Action::CreateSubmitForm(url);
232 // Associate the above action with 'Down' event in annotations action dictionary.
233 Obj annot_action = custom_pushbutton1.GetSDFObj().PutDict("AA");
234 annot_action.Put("D", button_action.GetSDFObj());
235 blank_page.AnnotPushBack(custom_pushbutton1);
236
237 // Add the page as the last page in the document.
238 doc.PagePushBack(blank_page);
239 // If you are not satisfied with the look of default auto-generated appearance
240 // streams you can delete "AP" entry from the Widget annotation and set
241 // "NeedAppearances" flag in AcroForm dictionary:
242 // doc.GetAcroForm().PutBool("NeedAppearances", true);
243 // This will force the viewer application to auto-generate new appearance streams
244 // every time the document is opened.
245 //
246 // Alternatively you can generate custom annotation appearance using ElementWriter
247 // and then set the "AP" entry in the widget dictionary to the new appearance
248 // stream.
249 //
250 // Yet another option is to pre-populate field entries with dummy text. When
251 // you edit the field values using PDFNet the new field appearances will match
252 // the old ones.
253
254 //doc.GetAcroForm().PutBool("NeedAppearances", true);
255 // NOTE: RefreshFieldAppearances will replace previously generated appearance streams
256 doc.RefreshFieldAppearances();
257
258 doc.Save((output_path + "forms_test1.pdf").c_str(), 0, 0);
259 cout << "Done." << endl;
260 }
261 catch(Common::Exception& e)
262 {
263 cout << e << endl;
264 ret = 1;
265 }
266 catch(...)
267 {
268 cout << "Unknown Exception" << endl;
269 ret = 1;
270 }
271
272 //----------------------------------------------------------------------------------
273 // Example 2:
274 // Fill-in forms / Modify values of existing fields.
275 // Traverse all form fields in the document (and print out their names).
276 // Search for specific fields in the document.
277 //----------------------------------------------------------------------------------
278 try
279 {
280 PDFDoc doc((output_path + "forms_test1.pdf").c_str());
281 doc.InitSecurityHandler();
282
283 FieldIterator itr = doc.GetFieldIterator();
284 for(; itr.HasNext(); itr.Next())
285 {
286 UString cur_field_name = itr.Current().GetName();
287
288 // Add one to the count for this field name for later processing
289 field_names[cur_field_name] = (field_names.count(cur_field_name) ? field_names[cur_field_name] + 1 : 1);
290
291 cout << "Field name: " << itr.Current().GetName() << endl;
292 cout << "Field partial name: " << itr.Current().GetPartialName() << endl;
293 cout << "Field type: ";
294 Field::Type type = itr.Current().GetType();
295 UString str_val = itr.Current().GetValueAsString();
296
297 switch(type)
298 {
299 case Field::e_button:
300 cout << "Button" << endl;
301 break;
302 case Field::e_radio:
303 cout << "Radio button: Value = " << str_val << endl;
304 break;
305 case Field::e_check:
306 itr.Current().SetValue(true);
307 cout << "Check box: Value = " << str_val << endl;
308 break;
309 case Field::e_text:
310 {
311 cout << "Text" << endl;
312 // Edit all variable text in the document
313 itr.Current().SetValue(UString("This is a new value. The old one was: ") + str_val);
314 }
315 break;
316 case Field::e_choice: cout << "Choice" << endl; break;
317 case Field::e_signature: cout << "Signature" << endl; break;
318 }
319
320 cout << "------------------------------" << endl;
321 }
322
323 // Search for a specific field
324 Field f = doc.GetField("employee.name.first");
325 if (f)
326 {
327 cout << "Field search for " << f.GetName() << " was successful" << endl;
328 }
329 else
330 {
331 cout << "Field search failed" << endl;
332 }
333
334 // Regenerate field appearances.
335 doc.RefreshFieldAppearances();
336 doc.Save((output_path + "forms_test_edit.pdf").c_str(), 0, NULL);
337 cout << "Done." << endl;
338 }
339 catch(Common::Exception& e)
340 {
341 cout << e << endl;
342 ret = 1;
343 }
344 catch(...)
345 {
346 cout << "Unknown Exception" << endl;
347 ret = 1;
348 }
349
350 //----------------------------------------------------------------------------------
351 // Sample: Form templating
352 // Replicate pages and form data within a document. Then rename field names to make
353 // them unique.
354 //----------------------------------------------------------------------------------
355 try
356 {
357 // Sample: Copying the page with forms within the same document
358 PDFDoc doc((output_path + "forms_test1.pdf").c_str());
359 doc.InitSecurityHandler();
360
361 Page src_page = doc.GetPage(1);
362 doc.PagePushBack(src_page); // Append several copies of the first page
363 doc.PagePushBack(src_page); // Note that forms are successfully copied
364 doc.PagePushBack(src_page);
365 doc.PagePushBack(src_page);
366
367 // Now we rename fields in order to make every field unique.
368 // You can use this technique for dynamic template filling where you have a 'master'
369 // form page that should be replicated, but with unique field names on every page.
370 for (map<UString, int>::iterator i = field_names.begin(); i != field_names.end(); i++)
371 {
372 RenameAllFields(doc, i->first, i->second);
373 }
374
375 doc.Save((output_path + "forms_test1_cloned.pdf").c_str(), 0, 0);
376 cout << "Done." << endl;
377 }
378 catch(Common::Exception& e)
379 {
380 cout << e << endl;
381 ret = 1;
382 }
383 catch(...)
384 {
385 cout << "Unknown Exception" << endl;
386 ret = 1;
387 }
388
389 //----------------------------------------------------------------------------------
390 // Sample:
391 // Flatten all form fields in a document.
392 // Note that this sample is intended to show that it is possible to flatten
393 // individual fields. PDFNet provides a utility function PDFDoc.FlattenAnnotations()
394 // that will automatically flatten all fields.
395 //----------------------------------------------------------------------------------
396 try
397 {
398 PDFDoc doc((output_path + "forms_test1.pdf").c_str());
399 doc.InitSecurityHandler();
400
401 // Traverse all pages
402 if (true) {
403 doc.FlattenAnnotations();
404 }
405 else // Manual flattening
406 {
407 for (PageIterator pitr = doc.GetPageIterator();
408 pitr.HasNext(); pitr.Next())
409 {
410 Page page = pitr.Current();
411 for (Int32 i = ((Int32)page.GetNumAnnots()) - 1; i >= 0; --i)
412 {
413 Annot annot = page.GetAnnot(i);
414 if (annot.GetType() == Annot::e_Widget)
415 {
416 annot.Flatten(page);
417 }
418 }
419 }
420 }
421
422 doc.Save((output_path + "forms_test1_flattened.pdf").c_str(), 0, 0);
423 cout << "Done." << endl;
424 }
425 catch(Common::Exception& e)
426 {
427 cout << e << endl;
428 ret = 1;
429 }
430 catch(...)
431 {
432 cout << "Unknown Exception" << endl;
433 ret = 1;
434 }
435
436 PDFNet::Terminate();
437 return ret;
438}
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2021 by PDFTron Systems Inc. All Rights Reserved.
3// Consult LICENSE.txt regarding license information.
4//---------------------------------------------------------------------------------------
5
6package main
7import (
8 "fmt"
9 "strconv"
10 "os"
11 "math"
12 . "pdftron"
13)
14
15import "pdftron/Samples/LicenseKey/GO"
16
17// Relative path to the folder containing the test files.
18var inputPath = "../../TestFiles/"
19var outputPath = "../../TestFiles/Output/"
20
21//---------------------------------------------------------------------------------------
22// This sample illustrates basic PDFNet capabilities related to interactive
23// forms (also known as AcroForms).
24//---------------------------------------------------------------------------------------
25
26// fieldNums has to be greater than 0.
27func RenameAllFields(doc PDFDoc, name string, fieldNums int){
28 itr := doc.GetFieldIterator(name)
29 counter := 1
30 for itr.HasNext(){
31 f := itr.Current()
32 radioCounter := (int)(math.Ceil(float64(counter/fieldNums)))
33 f.Rename(name + "-" + strconv.Itoa(radioCounter))
34 itr = doc.GetFieldIterator(name)
35 counter = counter + 1
36 }
37}
38func CreateCustomButtonAppearance(doc PDFDoc, buttonDown bool) Obj {
39 // Create a button appearance stream ------------------------------------
40 build := NewElementBuilder()
41 writer := NewElementWriter()
42 writer.Begin(doc.GetSDFDoc())
43
44 // Draw background
45 element := build.CreateRect(0.0, 0.0, 101.0, 37.0)
46 element.SetPathFill(true)
47 element.SetPathStroke(false)
48 element.GetGState().SetFillColorSpace(ColorSpaceCreateDeviceGray())
49 element.GetGState().SetFillColor(NewColorPt(0.75, 0.0, 0.0))
50 writer.WriteElement(element)
51
52 // Draw 'Submit' text
53 writer.WriteElement(build.CreateTextBegin())
54 text := "Submit"
55 element = build.CreateTextRun(text, FontCreate(doc.GetSDFDoc(), FontE_helvetica_bold), 12.0)
56 element.GetGState().SetFillColor(NewColorPt(0.0, 0.0, 0.0))
57
58 if buttonDown{
59 element.SetTextMatrix(1.0, 0.0, 0.0, 1.0, 33.0, 10.0)
60 }else{
61 element.SetTextMatrix(1.0, 0.0, 0.0, 1.0, 30.0, 13.0)
62 }
63 writer.WriteElement(element)
64
65 writer.WritePlacedElement(build.CreateTextEnd())
66
67 stm := writer.End()
68
69 // Set the bounding box
70 stm.PutRect("BBox", 0.0, 0.0, 101.0, 37.0)
71 stm.PutName("Subtype","Form")
72 return stm
73}
74func main(){
75 PDFNetInitialize(PDFTronLicense.Key)
76
77 // The map (vector) used to store the name and count of all fields.
78 // This is used later on to clone the fields
79 fieldNames:= make(map[string]int)
80 //----------------------------------------------------------------------------------
81 // Example 1: Programatically create new Form Fields and Widget Annotations.
82 //----------------------------------------------------------------------------------
83
84 doc := NewPDFDoc()
85
86 // Create a blank new page and Add some form fields.
87 blankPage := doc.PageCreate()
88
89 // Text Widget Creation
90 // Create an empty text widget with black text.
91 text1 := TextWidgetCreate(doc, NewRect(110.0, 700.0, 380.0, 730.0))
92 text1.SetText("Basic Text Field")
93 text1.RefreshAppearance()
94 blankPage.AnnotPushBack(text1)
95 // Create a vertical text widget with blue text and a yellow background.
96 text2 := TextWidgetCreate(doc, NewRect(50.0, 400.0, 90.0, 730.0))
97 text2.SetRotation(90)
98 // Set the text content.
99 text2.SetText(" ****Lucky Stars!****");
100 // Set the font type, text color, font size, border color and background color.
101 text2.SetFont(FontCreate(doc.GetSDFDoc(), FontE_helvetica_oblique))
102 text2.SetFontSize(28)
103 text2.SetTextColor(NewColorPt(0.0, 0.0, 1.0), 3)
104 text2.SetBorderColor(NewColorPt(0.0, 0.0, 0.0), 3)
105 text2.SetBackgroundColor(NewColorPt(1.0, 1.0, 0.0), 3)
106 text2.RefreshAppearance()
107 // Add the annotation to the page.
108 blankPage.AnnotPushBack(text2)
109 // Create two new text widget with Field names employee.name.first and employee.name.last
110 // This logic shows how these widgets can be created using either a field name string or
111 // a Field object
112 text3 := TextWidgetCreate(doc, NewRect(110.0, 660.0, 380.0, 690.0), "employee.name.first")
113 text3.SetText("Levi")
114 text3.SetFont(FontCreate(doc.GetSDFDoc(), FontE_times_bold))
115 text3.RefreshAppearance()
116 blankPage.AnnotPushBack(text3)
117 empLastName := doc.FieldCreate("employee.name.last", FieldE_text, "Ackerman")
118 text4 := TextWidgetCreate(doc, NewRect(110.0, 620.0, 380.0, 650.0), empLastName)
119 text4.SetFont(FontCreate(doc.GetSDFDoc(), FontE_times_bold))
120 text4.RefreshAppearance()
121 blankPage.AnnotPushBack(text4)
122
123 // Signature Widget Creation (unsigned)
124 signature1 := SignatureWidgetCreate(doc, NewRect(110.0, 560.0, 260.0, 610.0))
125 signature1.RefreshAppearance()
126 blankPage.AnnotPushBack(signature1)
127
128 // CheckBox Widget Creation
129 // Create a check box widget that is not checked.
130 check1 := CheckBoxWidgetCreate(doc, NewRect(140.0, 490.0, 170.0, 520.0))
131 check1.RefreshAppearance()
132 blankPage.AnnotPushBack(check1)
133 // Create a check box widget that is checked.
134 check2 := CheckBoxWidgetCreate(doc, NewRect(190.0, 490.0, 250.0, 540.0), "employee.name.check1")
135 check2.SetBackgroundColor(NewColorPt(1.0, 1.0, 1.0), 3)
136 check2.SetBorderColor(NewColorPt(0.0, 0.0, 0.0), 3)
137 // Check the widget (by default it is unchecked).
138 check2.SetChecked(true)
139 check2.RefreshAppearance()
140 blankPage.AnnotPushBack(check2)
141
142 // PushButton Widget Creation
143 pushbutton1 := PushButtonWidgetCreate(doc, NewRect(380.0, 490.0, 520.0, 540.0))
144 pushbutton1.SetTextColor(NewColorPt(1.0, 1.0, 1.0), 3)
145 pushbutton1.SetFontSize(36)
146 pushbutton1.SetBackgroundColor(NewColorPt(0.0, 0.0, 0.0), 3)
147 // Add a caption for the pushbutton.
148 pushbutton1.SetStaticCaptionText("PushButton")
149 pushbutton1.RefreshAppearance()
150 blankPage.AnnotPushBack(pushbutton1)
151
152 // ComboBox Widget Creation
153 combo1 := ComboBoxWidgetCreate(doc, NewRect(280.0, 560.0, 580.0, 610.0));
154 // Add options to the combobox widget.
155 combo1.AddOption("Combo Box No.1")
156 combo1.AddOption("Combo Box No.2")
157 combo1.AddOption("Combo Box No.3")
158 // Make one of the options in the combo box selected by default.
159 combo1.SetSelectedOption("Combo Box No.2")
160 combo1.SetTextColor(NewColorPt(1.0, 0.0, 0.0), 3)
161 combo1.SetFontSize(28)
162 combo1.RefreshAppearance()
163 blankPage.AnnotPushBack(combo1)
164
165 // ListBox Widget Creation
166 list1 := ListBoxWidgetCreate(doc, NewRect(400.0, 620.0, 580.0, 730.0))
167 // Add one option to the listbox widget.
168 list1.AddOption("List Box No.1")
169 // Add multiple options to the listbox widget in a batch.
170 listOptions := NewVectorString()
171 listOptions.Add("List Box No.2")
172 listOptions.Add("List Box No.3")
173 list1.AddOptions(listOptions)
174 // Select some of the options in list box as default options
175 list1.SetSelectedOptions(listOptions)
176 // Enable list box to have multi-select when editing.
177 list1.GetField().SetFlag(FieldE_multiselect, true)
178 list1.SetFont(FontCreate(doc.GetSDFDoc(),FontE_times_italic))
179 list1.SetTextColor(NewColorPt(1.0, 0.0, 0.0), 3)
180 list1.SetFontSize(28)
181 list1.SetBackgroundColor(NewColorPt(1.0, 1.0, 1.0), 3)
182 list1.RefreshAppearance()
183 blankPage.AnnotPushBack(list1)
184
185 // RadioButton Widget Creation
186 // Create a radio button group and Add three radio buttons in it.
187 radioGroup := RadioButtonGroupCreate(doc, "RadioGroup")
188 radiobutton1 := radioGroup.Add(NewRect(140.0, 410.0, 190.0, 460.0))
189 radiobutton1.SetBackgroundColor(NewColorPt(1.0, 1.0, 0.0), 3)
190 radiobutton1.RefreshAppearance()
191 radiobutton2 := radioGroup.Add(NewRect(310.0, 410.0, 360.0, 460.0))
192 radiobutton2.SetBackgroundColor(NewColorPt(0.0, 1.0, 0.0), 3)
193 radiobutton2.RefreshAppearance()
194 radiobutton3 := radioGroup.Add(NewRect(480.0, 410.0, 530.0, 460.0))
195 // Enable the third radio button. By default the first one is selected
196 radiobutton3.EnableButton()
197 radiobutton3.SetBackgroundColor(NewColorPt(0.0, 1.0, 1.0), 3)
198 radiobutton3.RefreshAppearance()
199 radioGroup.AddGroupButtonsToPage(blankPage)
200
201 // Custom push button annotation creation
202 customPushbutton1 := PushButtonWidgetCreate(doc, NewRect(260.0, 320.0, 360.0, 360.0))
203 // Set the annotation appearance.
204 customPushbutton1.SetAppearance(CreateCustomButtonAppearance(doc, false), AnnotE_normal)
205 // Create 'SubmitForm' action. The action will be linked to the button.
206 url := FileSpecCreateURL(doc.GetSDFDoc(), "http://www.pdftron.com")
207 buttonAction := ActionCreateSubmitForm(url)
208 // Associate the above action with 'Down' event in annotations action dictionary.
209 annotAction := customPushbutton1.GetSDFObj().PutDict("AA")
210 annotAction.Put("D", buttonAction.GetSDFObj())
211 blankPage.AnnotPushBack(customPushbutton1)
212
213 // Add the page as the last page in the document.
214 doc.PagePushBack(blankPage)
215
216 // If you are not satisfied with the look of default auto-generated appearance
217 // streams you can delete "AP" entry from the Widget annotation and set
218 // "NeedAppearances" flag in AcroForm dictionary:
219 // doc.GetAcroForm().PutBool("NeedAppearances", true);
220 // This will force the viewer application to auto-generate new appearance streams
221 // every time the document is opened.
222 //
223 // Alternatively you can generate custom annotation appearance using ElementWriter
224 // and then set the "AP" entry in the widget dictionary to the new appearance
225 // stream.
226 //
227 // Yet another option is to pre-populate field entries with dummy text. When
228 // you edit the field values using PDFNet the new field appearances will match
229 // the old ones.
230
231 //doc.GetAcroForm().PutBool("NeedAppearances", true)
232 doc.RefreshFieldAppearances()
233
234 doc.Save(outputPath + "forms_test1.pdf", uint(0))
235 doc.Close()
236 fmt.Println("Done.")
237
238 //----------------------------------------------------------------------------------
239 // Example 2:
240 // Fill-in forms / Modify values of existing fields.
241 // Traverse all form fields in the document (and sys.stdout.write(out their names).
242 // Search for specific fields in the document.
243 //----------------------------------------------------------------------------------
244
245 doc = NewPDFDoc(outputPath + "forms_test1.pdf")
246 doc.InitSecurityHandler()
247
248 itr := doc.GetFieldIterator()
249 for itr.HasNext(){
250 curFieldName := itr.Current().GetName()
251 // Add one to the count for this field name for later processing
252 if val, found := fieldNames[curFieldName]; found{
253 fieldNames[curFieldName] = val + 1
254 }else{
255 fieldNames[curFieldName] = 1
256 }
257
258 fmt.Println("Field name: " + itr.Current().GetName())
259 fmt.Println("Field partial name: " + itr.Current().GetPartialName())
260 os.Stdout.Write([]byte("Field type: "))
261 fieldType := itr.Current().GetType()
262 strVal := itr.Current().GetValueAsString()
263 if (fieldType == FieldE_button){
264 os.Stdout.Write([]byte("Button\n"))
265 }else if (fieldType == FieldE_radio){
266 os.Stdout.Write([]byte("Radio button: Value = " + strVal + "\n"))
267 }else if (fieldType == FieldE_check){
268 itr.Current().SetValue(true)
269 os.Stdout.Write([]byte("Check box: Value = " + strVal + "\n"))
270 }else if (fieldType == FieldE_text){
271 os.Stdout.Write([]byte("Text" + "\n"))
272 // Edit all variable text in the document
273 if itr.Current().GetValue().GetMp_obj().Swigcptr() != 0 {
274 old_value := itr.Current().GetValueAsString();
275 itr.Current().SetValue("This is a new value. The old one was: " + old_value)
276 }
277 }else if (fieldType == FieldE_choice){
278 os.Stdout.Write([]byte("Choice" + "\n"))
279 }else if (fieldType == FieldE_signature){
280 os.Stdout.Write([]byte("Signature" + "\n"))
281 }
282 fmt.Println("------------------------------")
283 itr.Next()
284 }
285 // Search for a specific field
286 f := doc.GetField("employee.name.first")
287 if f.GetMp_field().Swigcptr() != 0{
288 fmt.Println("Field search for " + f.GetName() + " was successful")
289 }else{
290 fmt.Println("Field search failed")
291 }
292
293 // Regenerate field appearances.
294 doc.RefreshFieldAppearances()
295 doc.Save(outputPath + "forms_test_edit.pdf", uint(0))
296 doc.Close()
297 fmt.Println("Done.")
298
299 //----------------------------------------------------------------------------------
300 // Sample: Form templating
301 // Replicate pages and form data within a document. Then rename field names to make
302 // them unique.
303 //----------------------------------------------------------------------------------
304
305 // Sample: Copying the page with forms within the same document
306 doc = NewPDFDoc(outputPath + "forms_test1.pdf")
307 doc.InitSecurityHandler()
308
309 srcPage := doc.GetPage(1)
310 doc.PagePushBack(srcPage) // Append several copies of the first page
311 doc.PagePushBack(srcPage) // Note that forms are successfully copied
312 doc.PagePushBack(srcPage)
313 doc.PagePushBack(srcPage)
314
315 // Now we rename fields in order to make every field unique.
316 // You can use this technique for dynamic template filling where you have a 'master'
317 // form page that should be replicated, but with unique field names on every page.
318 for key, curField := range fieldNames{
319 RenameAllFields(doc, key, curField)
320 }
321
322 doc.Save(outputPath + "forms_test1_cloned.pdf", uint(0))
323 doc.Close()
324 fmt.Println("Done.")
325
326 //----------------------------------------------------------------------------------
327 // Sample:
328 // Flatten all form fields in a document.
329 // Note that this sample is intended to show that it is possible to flatten
330 // individual fields. PDFNet provides a utility function PDFDoc.FlattenAnnotations()
331 // that will automatically flatten all fields.
332 //----------------------------------------------------------------------------------
333 doc = NewPDFDoc(outputPath + "forms_test1.pdf")
334 doc.InitSecurityHandler()
335
336 // Traverse all pages
337 if false{
338 doc.FlattenAnnotations()
339 }else{ // Manual flattening
340 for pitr := doc.GetPageIterator(); pitr.HasNext(); pitr.Next(){
341 page := pitr.Current()
342 for i := int(page.GetNumAnnots()) - 1; i >= 0; i-- {
343 annot := page.GetAnnot(uint(i))
344 if (annot.GetType() == AnnotE_Widget){
345 annot.Flatten(page)
346 }
347 }
348 }
349 }
350 doc.Save(outputPath + "forms_test1_flattened.pdf", uint(0))
351 doc.Close()
352 PDFNetTerminate()
353 fmt.Println("Done.")
354}
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6import com.pdftron.common.PDFNetException;
7import com.pdftron.pdf.*;
8import com.pdftron.sdf.Obj;
9import com.pdftron.sdf.SDFDoc;
10import com.pdftron.pdf.annots.*;
11import java.util.*;
12
13//---------------------------------------------------------------------------------------
14// This sample illustrates basic PDFNet capabilities related to interactive
15// forms (also known as AcroForms).
16//---------------------------------------------------------------------------------------
17
18public class InteractiveFormsTest {
19
20 // field_nums has to be greater than 0.
21 static void renameAllFields(PDFDoc doc, String name, int field_nums) throws PDFNetException {
22 FieldIterator itr = doc.getFieldIterator(name);
23 for (int counter = 1; itr.hasNext(); itr = doc.getFieldIterator(name), ++counter) {
24 Field f = itr.next();
25 int update_count = (int)java.lang.Math.ceil(counter/(double)field_nums);
26 f.rename(name + "-" + update_count);
27 }
28 }
29
30 static Obj createCustomButtonAppearance(PDFDoc doc, boolean button_down) throws PDFNetException {
31 // Create a button appearance stream ------------------------------------
32 ElementBuilder build = new ElementBuilder();
33 ElementWriter writer = new ElementWriter();
34 writer.begin(doc);
35
36 // Draw background
37 Element element = build.createRect(0, 0, 101, 37);
38 element.setPathFill(true);
39 element.setPathStroke(false);
40 element.getGState().setFillColorSpace(ColorSpace.createDeviceGray());
41 element.getGState().setFillColor(new ColorPt(0.75, 0, 0));
42 writer.writeElement(element);
43
44 // Draw 'Submit' text
45 writer.writeElement(build.createTextBegin());
46 {
47 String text = "Submit";
48 element = build.createTextRun(text, Font.create(doc, Font.e_helvetica_bold), 12);
49 element.getGState().setFillColor(new ColorPt(0, 0, 0));
50
51 if (button_down)
52 element.setTextMatrix(1, 0, 0, 1, 33, 10);
53 else
54 element.setTextMatrix(1, 0, 0, 1, 30, 13);
55 writer.writeElement(element);
56 }
57 writer.writeElement(build.createTextEnd());
58
59 Obj stm = writer.end();
60
61 // Set the bounding box
62 stm.putRect("BBox", 0, 0, 101, 37);
63 stm.putName("Subtype", "Form");
64 return stm;
65 }
66
67 public static void main(String[] args) {
68 PDFNet.initialize(PDFTronLicense.Key());
69
70 // Relative path to the folder containing test files.
71 // string input_path = "../../TestFiles/";
72 String output_path = "../../TestFiles/Output/";
73
74 // The vector used to store the name and count of all fields.
75 // This is used later on to clone the fields
76 Map<String, Integer> field_names = new HashMap<String, Integer>();
77
78 //----------------------------------------------------------------------------------
79 // Example 1: Programatically create new Form Fields and Widget Annotations.
80 //----------------------------------------------------------------------------------
81 try (PDFDoc doc = new PDFDoc()) {
82 // Create a blank new page and add some form fields.
83 Page blank_page = doc.pageCreate();
84
85 // Text Widget Creation
86 // Create an empty text widget with black text.
87 TextWidget text1 = TextWidget.create(doc, new Rect(110, 700, 380, 730));
88 text1.setText("Basic Text Field");
89 text1.refreshAppearance();
90 blank_page.annotPushBack(text1);
91 // Create a vertical text widget with blue text and a yellow background.
92 TextWidget text2 = TextWidget.create(doc, new Rect(50, 400, 90, 730));
93 text2.setRotation(90);
94 // Set the text content.
95 text2.setText(" ****Lucky Stars!****");
96 // Set the font type, text color, font size, border color and background color.
97 text2.setFont(Font.create(doc, Font.e_helvetica_oblique));
98 text2.setFontSize(28);
99 text2.setTextColor(new ColorPt(0, 0, 1), 3);
100 text2.setBorderColor(new ColorPt(0, 0, 0), 3);
101 text2.setBackgroundColor(new ColorPt(1, 1, 0), 3);
102 text2.refreshAppearance();
103 // Add the annotation to the page.
104 blank_page.annotPushBack(text2);
105 // Create two new text widget with Field names employee.name.first and employee.name.last
106 // This logic shows how these widgets can be created using either a field name string or
107 // a Field object
108 TextWidget text3 = TextWidget.create(doc, new Rect(110, 660, 380, 690), "employee.name.first");
109 text3.setText("Levi");
110 text3.setFont(Font.create(doc, Font.e_times_bold));
111 text3.refreshAppearance();
112 blank_page.annotPushBack(text3);
113 Field emp_last_name = doc.fieldCreate("employee.name.last", Field.e_text, "Ackerman");
114 TextWidget text4 = TextWidget.create(doc, new Rect(110, 620, 380, 650), emp_last_name);
115 text4.setFont(Font.create(doc, Font.e_times_bold));
116 text4.refreshAppearance();
117 blank_page.annotPushBack(text4);
118
119 // Signature Widget Creation (unsigned)
120 SignatureWidget signature1 = SignatureWidget.create(doc, new Rect(110, 560, 260, 610));
121 signature1.refreshAppearance();
122 blank_page.annotPushBack(signature1);
123
124 // CheckBox Widget Creation
125 // Create a check box widget that is not checked.
126 CheckBoxWidget check1 = CheckBoxWidget.create(doc, new Rect(140, 490, 170, 520));
127 check1.refreshAppearance();
128 blank_page.annotPushBack(check1);
129 // Create a check box widget that is checked.
130 CheckBoxWidget check2 = CheckBoxWidget.create(doc, new Rect(190, 490, 250, 540), "employee.name.check1");
131 check2.setBackgroundColor(new ColorPt(1, 1, 1), 3);
132 check2.setBorderColor(new ColorPt(0, 0, 0), 3);
133 // Check the widget (by default it is unchecked).
134 check2.setChecked(true);
135 check2.refreshAppearance();
136 blank_page.annotPushBack(check2);
137
138 // PushButton Widget Creation
139 PushButtonWidget pushbutton1 = PushButtonWidget.create(doc, new Rect(380, 490, 520, 540));
140 pushbutton1.setTextColor(new ColorPt(1, 1, 1), 3);
141 pushbutton1.setFontSize(36);
142 pushbutton1.setBackgroundColor(new ColorPt(0, 0, 0), 3);
143 // Add a caption for the pushbutton.
144 pushbutton1.setStaticCaptionText("PushButton");
145 pushbutton1.refreshAppearance();
146 blank_page.annotPushBack(pushbutton1);
147
148 // ComboBox Widget Creation
149 ComboBoxWidget combo1 = ComboBoxWidget.create(doc, new Rect(280, 560, 580, 610));
150 // Add options to the combobox widget.
151 combo1.addOption("Combo Box No.1");
152 combo1.addOption("Combo Box No.2");
153 combo1.addOption("Combo Box No.3");
154 // Make one of the options in the combo box selected by default.
155 combo1.setSelectedOption("Combo Box No.2");
156 combo1.setTextColor(new ColorPt(1, 0, 0), 3);
157 combo1.setFontSize(28);
158 combo1.refreshAppearance();
159 blank_page.annotPushBack(combo1);
160
161 // ListBox Widget Creation
162 ListBoxWidget list1 = ListBoxWidget.create(doc, new Rect(400, 620, 580, 730));
163 // Add one option to the listbox widget.
164 list1.addOption("List Box No.1");
165 // Add multiple options to the listbox widget in a batch.
166 String[] list_options = new String[] { "List Box No.2", "List Box No.3" };
167 list1.addOptions(list_options);
168 // Select some of the options in list box as default options
169 list1.setSelectedOptions(list_options);
170 // Enable list box to have multi-select when editing.
171 list1.getField().setFlag(Field.e_multiselect, true);
172 list1.setFont(Font.create(doc,Font.e_times_italic));
173 list1.setTextColor(new ColorPt(1, 0, 0), 3);
174 list1.setFontSize(28);
175 list1.setBackgroundColor(new ColorPt(1, 1, 1), 3);
176 list1.refreshAppearance();
177 blank_page.annotPushBack(list1);
178
179 // RadioButton Widget Creation
180 // Create a radio button group and add three radio buttons in it.
181 RadioButtonGroup radio_group = RadioButtonGroup.create(doc, "RadioGroup");
182 RadioButtonWidget radiobutton1 = radio_group.add(new Rect(140, 410, 190, 460));
183 radiobutton1.setBackgroundColor(new ColorPt(1, 1, 0), 3);
184 radiobutton1.refreshAppearance();
185 RadioButtonWidget radiobutton2 = radio_group.add(new Rect(310, 410, 360, 460));
186 radiobutton2.setBackgroundColor(new ColorPt(0, 1, 0), 3);
187 radiobutton2.refreshAppearance();
188 RadioButtonWidget radiobutton3 = radio_group.add(new Rect(480, 410, 530, 460));
189 // Enable the third radio button. By default the first one is selected
190 radiobutton3.enableButton();
191 radiobutton3.setBackgroundColor(new ColorPt(0, 1, 1), 3);
192 radiobutton3.refreshAppearance();
193 radio_group.addGroupButtonsToPage(blank_page);
194
195 // Custom push button annotation creation
196 PushButtonWidget custom_pushbutton1 = PushButtonWidget.create(doc, new Rect(260, 320, 360, 360));
197 // Set the annotation appearance.
198 custom_pushbutton1.setAppearance(createCustomButtonAppearance(doc, false), Annot.e_normal);
199 // Create 'SubmitForm' action. The action will be linked to the button.
200 FileSpec url = FileSpec.createURL(doc, "http://www.pdftron.com");
201 Action button_action = Action.createSubmitForm(url);
202 // Associate the above action with 'Down' event in annotations action dictionary.
203 Obj annot_action = custom_pushbutton1.getSDFObj().putDict("AA");
204 annot_action.put("D", button_action.getSDFObj());
205 blank_page.annotPushBack(custom_pushbutton1);
206
207 // Add the page as the last page in the document.
208 doc.pagePushBack(blank_page);
209
210 // If you are not satisfied with the look of default auto-generated appearance
211 // streams you can delete "AP" entry from the Widget annotation and set
212 // "NeedAppearances" flag in AcroForm dictionary:
213 // doc.GetAcroForm().PutBool("NeedAppearances", true);
214 // This will force the viewer application to auto-generate new appearance streams
215 // every time the document is opened.
216 //
217 // Alternatively you can generate custom annotation appearance using ElementWriter
218 // and then set the "AP" entry in the widget dictionary to the new appearance
219 // stream.
220 //
221 // Yet another option is to pre-populate field entries with dummy text. When
222 // you edit the field values using PDFNet the new field appearances will match
223 // the old ones.
224
225 //doc.GetAcroForm().Put("NeedAppearances", new Bool(true));
226 doc.refreshFieldAppearances();
227
228 doc.save(output_path + "forms_test1.pdf", SDFDoc.SaveMode.NO_FLAGS, null);
229 System.out.println("Done.");
230 } catch (Exception e) {
231 e.printStackTrace();
232 }
233
234 //----------------------------------------------------------------------------------
235 // Example 2:
236 // Fill-in forms / Modify values of existing fields.
237 // Traverse all form fields in the document (and print out their names).
238 // Search for specific fields in the document.
239 //----------------------------------------------------------------------------------
240 try (PDFDoc doc = new PDFDoc((output_path + "forms_test1.pdf"))) {
241 doc.initSecurityHandler();
242
243 FieldIterator itr = doc.getFieldIterator();
244 while (itr.hasNext()) {
245 Field current = itr.next();
246 String cur_field_name = current.getName();
247 // Add one to the count for this field name for later processing
248 if (field_names.containsKey(cur_field_name)) {
249 field_names.put(cur_field_name, field_names.get(cur_field_name) + 1);
250 }
251 else {
252 field_names.put(cur_field_name, 1);
253 }
254
255 System.out.println("Field name: " + current.getName());
256 System.out.println("Field partial name: " + current.getPartialName());
257
258 System.out.print("Field type: ");
259 int type = current.getType();
260 String str_val = current.getValueAsString();
261 switch (type) {
262 case Field.e_button:
263 System.out.println("Button");
264 break;
265 case Field.e_radio:
266 System.out.println("Radio button: Value = " + str_val);
267 break;
268 case Field.e_check:
269 current.setValue(true);
270 System.out.println("Check box: Value = " + str_val);
271 break;
272 case Field.e_text: {
273 System.out.println("Text");
274 // Edit all variable text in the document
275 String old_value;
276 if (current.getValue() != null) {
277 old_value = current.getValueAsString();
278 current.setValue("This is a new value. The old one was: " + old_value);
279 }
280 }
281 break;
282 case Field.e_choice:
283 System.out.println("Choice");
284 break;
285 case Field.e_signature:
286 System.out.println("Signature");
287 break;
288 }
289
290 System.out.println("------------------------------");
291 }
292
293 // Search for a specific field
294 Field f = doc.getField("employee.name.first");
295 if (f != null) {
296 System.out.println("Field search for " + f.getName() + " was successful");
297 } else {
298 System.out.println("Field search failed");
299 }
300
301 // Regenerate field appearances.
302 doc.refreshFieldAppearances();
303 doc.save((output_path + "forms_test_edit.pdf"), SDFDoc.SaveMode.NO_FLAGS, null);
304 System.out.println("Done.");
305 } catch (Exception e) {
306 e.printStackTrace();
307 }
308
309
310 //----------------------------------------------------------------------------------
311 // Sample: Form templating
312 // Replicate pages and form data within a document. Then rename field names to make
313 // them unique.
314 //----------------------------------------------------------------------------------
315 try (PDFDoc doc = new PDFDoc((output_path + "forms_test1.pdf"))) {
316 // Sample: Copying the page with forms within the same document
317 doc.initSecurityHandler();
318
319 Page src_page = (Page) (doc.getPage(1));
320 doc.pagePushBack(src_page); // Append several copies of the first page
321 doc.pagePushBack(src_page); // Note that forms are successfully copied
322 doc.pagePushBack(src_page);
323 doc.pagePushBack(src_page);
324
325 // Now we rename fields in order to make every field unique.
326 // You can use this technique for dynamic template filling where you have a 'master'
327 // form page that should be replicated, but with unique field names on every page.
328 for (String cur_field : field_names.keySet()) {
329 renameAllFields(doc, cur_field, field_names.get(cur_field));
330 }
331
332 doc.save(output_path + "forms_test1_cloned.pdf", SDFDoc.SaveMode.NO_FLAGS, null);
333 System.out.println("Done.");
334 } catch (Exception e) {
335 e.printStackTrace();
336 }
337
338
339 //----------------------------------------------------------------------------------
340 // Sample:
341 // Flatten all form fields in a document.
342 // Note that this sample is intended to show that it is possible to flatten
343 // individual fields. PDFNet provides a utility function PDFDoc.flattenAnnotations()
344 // that will automatically flatten all fields.
345 //----------------------------------------------------------------------------------
346 try (PDFDoc doc = new PDFDoc((output_path + "forms_test1.pdf"))) {
347 doc.initSecurityHandler();
348
349 // Traverse all pages
350 if (true) {
351 doc.flattenAnnotations();
352 } else // Manual flattening
353 {
354
355 for (PageIterator pitr = doc.getPageIterator(); pitr.hasNext(); ) {
356 Page page = pitr.next();
357 for (int i = page.getNumAnnots() - 1; i >= 0; --i) {
358 Annot annot = page.getAnnot(i);
359 if (annot.getType() == Annot.e_Widget)
360 {
361 annot.flatten(page);
362 }
363 }
364 }
365 }
366
367 doc.save(output_path + "forms_test1_flattened.pdf", SDFDoc.SaveMode.NO_FLAGS, null);
368 System.out.println("Done.");
369 } catch (Exception e) {
370 e.printStackTrace();
371 }
372
373 PDFNet.terminate();
374 }
375}
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6//---------------------------------------------------------------------------------------
7// This sample illustrates basic PDFNet capabilities related to interactive
8// forms (also known as AcroForms).
9//---------------------------------------------------------------------------------------
10const { PDFNet } = require('@pdftron/pdfnet-node');
11const PDFTronLicense = require('../LicenseKey/LicenseKey');
12
13((exports) => {
14 'use strict';
15
16 exports.runInteractiveFormsTest = () => {
17
18 // field_nums has to be greater than 0.
19 const RenameAllFields = async (doc, name, field_nums = 1) => {
20 let itr = await doc.getFieldIterator(name);
21 for (let counter = 0; (await itr.hasNext()); itr = (await doc.getFieldIterator(name)), ++counter) {
22 const f = await itr.current();
23 const update_count = Math.ceil(counter / field_nums);
24 f.rename(name + update_count);
25 }
26 };
27
28 const CreateCustomButtonAppearance = async (doc, buttonDown) => {
29 // Create a button appearance stream ------------------------------------
30
31 const builder = await PDFNet.ElementBuilder.create();
32 const writer = await PDFNet.ElementWriter.create();
33 writer.begin(doc);
34
35 // Draw background
36 let element = await builder.createRect(0, 0, 101, 37);
37 element.setPathFill(true);
38 element.setPathStroke(false);
39
40 let elementGState = await element.getGState();
41 elementGState.setFillColorSpace(await PDFNet.ColorSpace.createDeviceGray());
42 elementGState.setFillColorWithColorPt(await PDFNet.ColorPt.init(0.75));
43 writer.writeElement(element);
44
45 // Draw 'Submit' text
46 writer.writeElement((await builder.createTextBegin()));
47
48 const text = 'Submit';
49 const helveticaBoldFont = await PDFNet.Font.create(doc, PDFNet.Font.StandardType1Font.e_helvetica_bold);
50 element = await builder.createTextRun(text, helveticaBoldFont, 12);
51 elementGState = await element.getGState();
52 elementGState.setFillColorWithColorPt((await PDFNet.ColorPt.init(0)));
53
54 if (buttonDown) {
55 element.setTextMatrixEntries(1, 0, 0, 1, 33, 10);
56 } else {
57 element.setTextMatrixEntries(1, 0, 0, 1, 30, 13);
58 }
59 writer.writeElement(element);
60
61 writer.writeElement((await builder.createTextEnd()));
62
63 const stm = await writer.end();
64
65 // Set the bounding box
66 await stm.putRect('BBox', 0, 0, 101, 37);
67 await stm.putName('Subtype', 'Form');
68 return stm;
69 };
70
71 const main = async () => {
72 const outputPath = '../TestFiles/Output/';
73
74 //----------------------------------------------------------------------------------
75 // Example 1: Programatically create new Form Fields and Widget Annotations.
76 //----------------------------------------------------------------------------------
77 try {
78 const doc = await PDFNet.PDFDoc.create();
79 doc.initSecurityHandler();
80
81 // Create a blank new page and add some form fields.
82 const blankPage = await doc.pageCreate();
83
84 // Text Widget Creation
85 // Create an empty text widget with black text..
86 const text1 = await PDFNet.TextWidget.create(doc, await PDFNet.Rect.init(110, 700, 380, 730));
87 text1.setText('Basic Text Field');
88 await text1.refreshAppearance();
89 blankPage.annotPushBack(text1);
90 // Create a vertical text widget with blue text and a yellow background.
91 const text2 = await PDFNet.TextWidget.create(doc, await PDFNet.Rect.init(50, 400, 90, 730));
92 text2.setRotation(90);
93 // Set the text content.
94 text2.setText(' ****Lucky Stars!****');
95 // Set the font type, text color, font size, border color and background color.
96 text2.setFont(await PDFNet.Font.create(doc, PDFNet.Font.StandardType1Font.e_helvetica_oblique));
97 text2.setFontSize(28);
98 text2.setTextColor(await PDFNet.ColorPt.init(0, 0, 1), 3);
99 text2.setBorderColor(await PDFNet.ColorPt.init(0, 0, 0), 3);
100 text2.setBackgroundColor(await PDFNet.ColorPt.init(1, 1, 0), 3);
101 await text2.refreshAppearance();
102 // Add the annotation to the page.
103 blankPage.annotPushBack(text2);
104 // Create two new text widget with Field names employee.name.first and employee.name.last
105 // This logic shows how these widgets can be created using either a field name string or
106 // a Field object
107 const text3 = await PDFNet.TextWidget.create(doc, await PDFNet.Rect.init(110, 660, 380, 690), 'employee.name.first');
108 text3.setText('Levi');
109 text3.setFont(await PDFNet.Font.create(doc, PDFNet.Font.StandardType1Font.e_times_bold));
110 await text3.refreshAppearance();
111 blankPage.annotPushBack(text3);
112 const empLastName = await doc.fieldCreateFromStrings('employee.name.last', PDFNet.Field.Type.e_text, 'Ackerman');
113 const text4 = await PDFNet.TextWidget.createWithField(doc, await PDFNet.Rect.init(110, 620, 380, 650), empLastName);
114 text4.setFont(await PDFNet.Font.create(doc, PDFNet.Font.StandardType1Font.e_times_bold));
115 await text4.refreshAppearance();
116 blankPage.annotPushBack(text4);
117
118 // Signature Widget Creation (unsigned)
119 const signature1 = await PDFNet.SignatureWidget.create(doc, await PDFNet.Rect.init(110, 560, 260, 610));
120 await signature1.refreshAppearance();
121 blankPage.annotPushBack(signature1);
122
123 // CheckBox Widget Creation
124 // Create a check box widget that is not checked.
125 const check1 = await PDFNet.CheckBoxWidget.create(doc, await PDFNet.Rect.init(140, 490, 170, 520));
126 await check1.refreshAppearance();
127 blankPage.annotPushBack(check1);
128 // Create a check box widget that is checked.
129 const check2 = await PDFNet.CheckBoxWidget.create(doc, await PDFNet.Rect.init(190, 490, 250, 540), 'employee.name.check1');
130 check2.setBackgroundColor(await PDFNet.ColorPt.init(1, 1, 1), 3);
131 check2.setBorderColor(await PDFNet.ColorPt.init(0, 0, 0), 3);
132 // Check the widget (by default it is unchecked).
133 check2.setChecked(true);
134 await check2.refreshAppearance();
135 blankPage.annotPushBack(check2);
136
137 // PushButton Widget Creation
138 const pushbutton1 = await PDFNet.PushButtonWidget.create(doc, await PDFNet.Rect.init(380, 490, 520, 540));
139 pushbutton1.setTextColor(await PDFNet.ColorPt.init(1, 1, 1), 3);
140 pushbutton1.setFontSize(36);
141 pushbutton1.setBackgroundColor(await PDFNet.ColorPt.init(0, 0, 0), 3);
142 // Add a caption for the pushbutton.
143 pushbutton1.setStaticCaptionText('PushButton');
144 await pushbutton1.refreshAppearance();
145 blankPage.annotPushBack(pushbutton1);
146
147 // ComboBox Widget Creation
148 const combo1 = await PDFNet.ComboBoxWidget.create(doc, await PDFNet.Rect.init(280, 560, 580, 610));
149 // Add options to the combobox widget.
150 combo1.addOption('Combo Box No.1');
151 combo1.addOption('Combo Box No.2');
152 combo1.addOption('Combo Box No.3');
153 // Make one of the options in the combo box selected by default.
154 combo1.setSelectedOption('Combo Box No.2');
155 combo1.setTextColor(await PDFNet.ColorPt.init(1, 0, 0), 3);
156 combo1.setFontSize(28);
157 await combo1.refreshAppearance();
158 blankPage.annotPushBack(combo1);
159
160 // ListBox Widget Creation
161 const list1 = await PDFNet.ListBoxWidget.create(doc, await PDFNet.Rect.init(400, 620, 580, 730));
162 // Add one option to the listbox widget.
163 list1.addOption('List Box No.1');
164 // Add multiple options to the listbox widget in a batch.
165 const list_options = ['List Box No.2', 'List Box No.3'];
166 list1.addOptions(list_options);
167 // Select some of the options in list box as default options
168 list1.setSelectedOptions(list_options);
169 // Enable list box to have multi-select when editing.
170 await (await list1.getField()).setFlag(PDFNet.Field.Flag.e_multiselect, true);
171 list1.setFont(await PDFNet.Font.create(doc, PDFNet.Font.StandardType1Font.e_times_italic));
172 list1.setTextColor(await PDFNet.ColorPt.init(1, 0, 0), 3);
173 list1.setFontSize(28);
174 list1.setBackgroundColor(await PDFNet.ColorPt.init(1, 1, 1), 3);
175 await list1.refreshAppearance();
176 await blankPage.annotPushBack(list1);
177
178 // RadioButton Widget Creation
179 // Create a radio button group and add three radio buttons in it.
180 const radio_group = await PDFNet.RadioButtonGroup.create(doc, 'RadioGroup');
181 const radiobutton1 = await radio_group.add(await PDFNet.Rect.init(140, 410, 190, 460));
182 radiobutton1.setBackgroundColor(await PDFNet.ColorPt.init(1, 1, 0), 3);
183 await radiobutton1.refreshAppearance();
184 const radiobutton2 = await radio_group.add(await PDFNet.Rect.init(310, 410, 360, 460));
185 radiobutton2.setBackgroundColor(await PDFNet.ColorPt.init(0, 1, 0), 3);
186 await radiobutton2.refreshAppearance();
187 const radiobutton3 = await radio_group.add(await PDFNet.Rect.init(480, 410, 530, 460));
188 // Enable the third radio button. By default the first one is selected
189 radiobutton3.enableButton();
190 radiobutton3.setBackgroundColor(await PDFNet.ColorPt.init(0, 1, 1), 3);
191 await radiobutton3.refreshAppearance();
192 await radio_group.addGroupButtonsToPage(blankPage);
193
194 // Custom push button annotation creation
195 const custom_pushbutton1 = await PDFNet.PushButtonWidget.create(doc, await PDFNet.Rect.init(260, 320, 360, 360));
196 // Set the annotation appearance.
197 custom_pushbutton1.setAppearance(await CreateCustomButtonAppearance(doc, false), PDFNet.Annot.State.e_normal);
198 // Create 'SubmitForm' action. The action will be linked to the button.
199 const url = await PDFNet.FileSpec.createURL(doc, 'http://www.pdftron.com');
200 const button_action = await PDFNet.Action.createSubmitForm(url);
201 // Associate the above action with 'Down' event in annotations action dictionary.
202 const annot_action = await (await custom_pushbutton1.getSDFObj()).putDict('AA');
203 await annot_action.put('D', await button_action.getSDFObj());
204 await blankPage.annotPushBack(custom_pushbutton1);
205
206 // Add the page as the last page in the document.
207 doc.pagePushBack(blankPage);
208 // If you are not satisfied with the look of default auto-generated appearance
209 // streams you can delete "AP" entry from the Widget annotation and set
210 // "NeedAppearances" flag in AcroForm dictionary:
211 // doc.GetAcroForm().PutBool("NeedAppearances", true);
212 // This will force the viewer application to auto-generate new appearance streams
213 // every time the document is opened.
214 //
215 // Alternatively you can generate custom annotation appearance using ElementWriter
216 // and then set the "AP" entry in the widget dictionary to the new appearance
217 // stream.
218 //
219 // Yet another option is to pre-populate field entries with dummy text. When
220 // you edit the field values using PDFNet the new field appearances will match
221 // the old ones.
222
223 //doc.GetAcroForm().PutBool("NeedAppearances", true);
224 // NOTE: RefreshFieldAppearances will replace previously generated appearance streams
225
226 doc.refreshFieldAppearances();
227
228 await doc.save(outputPath + 'forms_test1.pdf', 0);
229
230 console.log('Done.');
231 } catch (err) {
232 console.log(err.stack);
233 }
234
235 //----------------------------------------------------------------------------------
236 // Example 2:
237 // Fill-in forms / Modify values of existing fields.
238 // Traverse all form fields in the document (and print out their names).
239 // Search for specific fields in the document.
240 //----------------------------------------------------------------------------------
241
242 // This is used later on to clone the fields
243 const field_names = {};
244 try {
245 const doc = await PDFNet.PDFDoc.createFromFilePath(outputPath + 'forms_test1.pdf');
246 doc.initSecurityHandler();
247
248 const itr = await doc.getFieldIteratorBegin();
249 for (; (await itr.hasNext()); itr.next()) {
250 const currentItr = await itr.current();
251 const curFieldName = await currentItr.getName();
252
253 // Add one to the count for this field name for later processing
254 field_names[curFieldName] = (curFieldName in field_names ? field_names[curFieldName] + 1 : 1);
255
256 console.log('Field name: ' + curFieldName);
257 console.log('Field partial name: ' + (await currentItr.getPartialName()));
258
259 const typeStr = 'Field type: ';
260 const type = await currentItr.getType();
261 const strVal = await currentItr.getValueAsString();
262
263 switch (type) {
264 case PDFNet.Field.Type.e_button:
265 console.log(typeStr + 'Button');
266 break;
267 case PDFNet.Field.Type.e_radio:
268 console.log(typeStr + 'Radio button: Value = ' + strVal);
269 break;
270 case PDFNet.Field.Type.e_check:
271 currentItr.setValueAsBool(true);
272 console.log(typeStr + 'Check box: Value = ' + strVal);
273 break;
274 case PDFNet.Field.Type.e_text:
275 console.log(typeStr + 'Text');
276 // Edit all variable text in the document
277 currentItr.setValueAsString('This is a new value. The old one was: ' + strVal);
278 break;
279 case PDFNet.Field.Type.e_choice:
280 console.log(typeStr + 'Choice');
281 break;
282 case PDFNet.Field.Type.e_signature:
283 console.log(typeStr + 'Signature');
284 break;
285 }
286 console.log('------------------------------');
287 }
288 const f = await doc.getField('employee.name.first');
289 if (f) {
290 console.log('Field search for ' + (await f.getName()) + ' was successful');
291 } else {
292 console.log('Field search failed');
293 }
294 // Regenerate field appearances.
295 doc.refreshFieldAppearances();
296
297 await doc.save(outputPath + 'forms_test_edit.pdf', 0);
298 console.log('Done.');
299 } catch (err) {
300 console.log(err);
301 }
302 //----------------------------------------------------------------------------------
303 // Sample 3: Form templating
304 // Replicate pages and form data within a document. Then rename field names to make
305 // them unique.
306 //----------------------------------------------------------------------------------
307 try {
308 const doc = await PDFNet.PDFDoc.createFromFilePath(outputPath + 'forms_test1.pdf');
309 doc.initSecurityHandler();
310
311 const srcPage = await doc.getPage(1);
312 doc.pagePushBack(srcPage); // Append several copies of the first page
313 doc.pagePushBack(srcPage); // Note that forms are successfully copied
314 doc.pagePushBack(srcPage);
315 doc.pagePushBack(srcPage);
316
317 // Now we rename fields in order to make every field unique.
318 // You can use this technique for dynamic template filling where you have a 'master'
319 // form page that should be replicated, but with unique field names on every page.
320 for (const fieldName in field_names) {
321 await RenameAllFields(doc, fieldName, field_names[fieldName]);
322 }
323
324 await doc.save(outputPath + 'forms_test1_cloned.pdf', 0);
325 console.log('Done.');
326 } catch (err) {
327 console.log(err);
328 }
329
330 //----------------------------------------------------------------------------------
331 // Sample:
332 // Flatten all form fields in a document.
333 // Note that this sample is intended to show that it is possible to flatten
334 // individual fields. PDFNet provides a utility function PDFDoc.FlattenAnnotations()
335 // that will automatically flatten all fields.
336 //----------------------------------------------------------------------------------
337
338 try {
339 const doc = await PDFNet.PDFDoc.createFromFilePath(outputPath + 'forms_test1.pdf');
340 doc.initSecurityHandler();
341
342 // Flatten all pages
343 // eslint-disable-next-line no-constant-condition
344 if (true) {
345 doc.flattenAnnotations();
346 } else {
347 // Manual flattening
348 for (let pitr = await doc.getPageIterator(); (await pitr.hasNext()); (await pitr.next())) {
349 const page = await pitr.current();
350 const annots = await page.getAnnots();
351
352 if (annots) { // Look for all widget annotations (in reverse order)
353 for (let i = parseInt(await annots.size(), 10) - 1; i >= 0; --i) {
354 const annotObj = await annots.getAt(i);
355 const annotObjSubtype = await annotObj.get('Subtype');
356 // eslint-disable-next-line no-unused-vars
357 const annotObjVal = await annotObjSubtype.value();
358 const annotObjName = await annotObjVal.getName();
359
360 if (annotObjName === 'Widget') {
361 const field = await PDFNet.Field.create(annotObj);
362 field.flatten(page);
363 }
364 }
365 }
366 }
367 }
368
369 await doc.save(outputPath + 'forms_test1_flattened.pdf', 0);
370 console.log('Done.');
371 } catch (err) {
372 console.log(err);
373 }
374 };
375 PDFNet.runWithCleanup(main, PDFTronLicense.Key).catch(function (error) {
376 console.log('Error: ' + JSON.stringify(error));
377 }).then(function () { return PDFNet.shutdown(); });
378 };
379 exports.runInteractiveFormsTest();
380})(exports);
381// eslint-disable-next-line spaced-comment
382//# sourceURL=InteractiveFormsTest.js
1<?php
2//---------------------------------------------------------------------------------------
3// Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
4// Consult LICENSE.txt regarding license information.
5//---------------------------------------------------------------------------------------
6if(file_exists("../../../PDFNetC/Lib/PDFNetPHP.php"))
7include("../../../PDFNetC/Lib/PDFNetPHP.php");
8include("../../LicenseKey/PHP/LicenseKey.php");
9
10// Relative path to the folder containing the test files.
11$input_path = getcwd()."/../../TestFiles/";
12$output_path = $input_path."Output/";
13
14//---------------------------------------------------------------------------------------
15// This sample illustrates basic PDFNet capabilities related to interactive
16// forms (also known as AcroForms).
17//---------------------------------------------------------------------------------------
18
19function RenameAllFields($doc, $name, $field_nums = 1)
20{
21 $itr = $doc->GetFieldIterator($name);
22 for ($counter = 1; $itr->HasNext(); $itr = $doc->GetFieldIterator($name), ++$counter) {
23 $f = $itr->Current();
24 $tmp = (int)ceil($counter*1.0/$field_nums);
25 $f->Rename($name."-".$tmp);
26
27 }
28}
29
30// Note: The visual appearance of check-marks and radio-buttons in PDF documents is
31// not limited to CheckStyle-s. It is possible to create a visual appearance using
32// arbitrary glyph, text, raster image, or path object. Although most PDF producers
33// limit the options to the above 'standard' styles, using PDFNet you can generate
34// arbitrary appearances.
35
36function CreateCheckmarkAppearance($doc)
37{
38 // Create a checkmark appearance stream ------------------------------------
39 $build = new ElementBuilder();
40 $writer = new ElementWriter();
41 $writer->Begin($doc->GetSDFDoc());
42 $writer->WriteElement($build->CreateTextBegin());
43
44 $symbol = "4";
45 # other options are circle ("l"), diamond ("H"), cross ("\x35")
46 # See section D.4 "ZapfDingbats Set and Encoding" in PDF Reference Manual for
47 # the complete graphical map for ZapfDingbats font.
48
49 $checkmark = $build->CreateTextRun($symbol, Font::Create($doc->GetSDFDoc(), Font::e_zapf_dingbats), 1.0);
50 $writer->WriteElement($checkmark);
51 $writer->WriteElement($build->CreateTextEnd());
52
53 $stm = $writer->End();
54 $stm->PutRect("BBox", -0.2, -0.2, 1.0, 1.0); // Clip
55 $stm->PutName("Subtype", "Form");
56 return $stm;
57}
58
59function CreateCustomButtonAppearance($doc, $button_down)
60{
61 // Create a button appearance stream ------------------------------------
62 $build = new ElementBuilder();
63 $writer = new ElementWriter();
64 $writer->Begin($doc->GetSDFDoc());
65
66 // Draw background
67 $element = $build->CreateRect(0, 0, 101, 37);
68 $element->SetPathFill(true);
69 $element->SetPathStroke(false);
70 $element->GetGState()->SetFillColorSpace(ColorSpace::CreateDeviceGray());
71 $element->GetGState()->SetFillColor(new ColorPt(0.75, 0.0, 0.0));
72 $writer->WriteElement($element);
73
74 // Draw 'Submit' text
75 $writer->WriteElement($build->CreateTextBegin());
76
77 $text = "Submit";
78 $element = $build->CreateTextRun($text, Font::Create($doc->GetSDFDoc(), Font::e_helvetica_bold), 12.0);
79 $element->GetGState()->SetFillColor(new ColorPt(0.0, 0.0, 0.0));
80
81 if ($button_down)
82 $element->SetTextMatrix(1.0, 0.0, 0.0, 1.0, 33.0, 10.0);
83 else
84 $element->SetTextMatrix(1.0, 0.0, 0.0, 1.0, 30.0, 13.0);
85 $writer->WriteElement($element);
86
87 $writer->WriteElement($build->CreateTextEnd());
88
89 $stm = $writer->End();
90
91 // Set the bounding box
92 $stm->PutRect("BBox", 0, 0, 101, 37);
93 $stm->PutName("Subtype","Form");
94 return $stm;
95}
96
97 PDFNet::Initialize($LicenseKey);
98 PDFNet::GetSystemFontList(); // Wait for fonts to be loaded if they haven't already. This is done because PHP can run into errors when shutting down if font loading is still in progress.
99
100 //----------------------------------------------------------------------------------
101 // Example 1: Programatically create new Form Fields and Widget Annotations.
102 //----------------------------------------------------------------------------------
103
104 $doc = new PDFDoc();
105
106 // Create a blank new page and add some form fields.
107 $blank_page = $doc->PageCreate();
108
109 // Text Widget Creation
110 // Create an empty text widget with black text.
111 $text1 = TextWidget::Create($doc, new Rect(110.0, 700.0, 380.0, 730.0));
112 $text1->SetText("Basic Text Field");
113 $text1->RefreshAppearance();
114 $blank_page->AnnotPushBack($text1);
115 // Create a vertical text widget with blue text and a yellow background.
116 $text2 = TextWidget::Create($doc, new Rect(50.0, 400.0, 90.0, 730.0));
117 $text2->SetRotation(90);
118 // Set the text content.
119 $text2->SetText(" ****Lucky Stars!****");
120 // Set the font type, text color, font size, border color and background color.
121 $text2->SetFont(Font::Create($doc->GetSDFDoc(), Font::e_helvetica_oblique));
122 $text2->SetFontSize(28);
123 $text2->SetTextColor(new ColorPt(0.0, 0.0, 1.0), 3);
124 $text2->SetBorderColor(new ColorPt(0.0, 0.0, 0.0), 3);
125 $text2->SetBackgroundColor(new ColorPt(1.0, 1.0, 0.0), 3);
126 $text2->RefreshAppearance();
127 // Add the annotation to the page.
128 $blank_page->AnnotPushBack($text2);
129 // Create two new text widget with Field names employee.name.first and employee.name.last
130 // This logic shows how these widgets can be created using either a field name string or
131 // a Field object
132 $text3 = TextWidget::Create($doc, new Rect(110.0, 660.0, 380.0, 690.0), "employee.name.first");
133 $text3->SetText("Levi");
134 $text3->SetFont(Font::Create($doc->GetSDFDoc(), Font::e_times_bold));
135 $text3->RefreshAppearance();
136 $blank_page->AnnotPushBack($text3);
137 $emp_last_name = $doc->FieldCreate("employee.name.last", Field::e_text, "Ackerman");
138 $text4 = TextWidget::Create($doc, new Rect(110.0, 620.0, 380.0, 650.0), $emp_last_name);
139 $text4->SetFont(Font::Create($doc->GetSDFDoc(), Font::e_times_bold));
140 $text4->RefreshAppearance();
141 $blank_page->AnnotPushBack($text4);
142
143 // Signature Widget Creation (unsigned)
144 $signature1 = SignatureWidget::Create($doc, new Rect(110.0, 560.0, 260.0, 610.0));
145 $signature1->RefreshAppearance();
146 $blank_page->AnnotPushBack($signature1);
147
148 // CheckBox Widget Creation
149 // Create a check box widget that is not checked.
150 $check1 = CheckBoxWidget::Create($doc, new Rect(140.0, 490.0, 170.0, 520.0));
151 $check1->RefreshAppearance();
152 $blank_page->AnnotPushBack($check1);
153 // Create a check box widget that is checked.
154 $check2 = CheckBoxWidget::Create($doc, new Rect(190.0, 490.0, 250.0, 540.0), "employee.name.check1");
155 $check2->SetBackgroundColor(new ColorPt(1.0, 1.0, 1.0), 3);
156 $check2->SetBorderColor(new ColorPt(0.0, 0.0, 0.0), 3);
157 // Check the widget (by default it is unchecked).
158 $check2->SetChecked(true);
159 $check2->RefreshAppearance();
160 $blank_page->AnnotPushBack($check2);
161
162 // PushButton Widget Creation
163 $pushbutton1 = PushButtonWidget::Create($doc, new Rect(380.0, 490.0, 520.0, 540.0));
164 $pushbutton1->SetTextColor(new ColorPt(1.0, 1.0, 1.0), 3);
165 $pushbutton1->SetFontSize(36);
166 $pushbutton1->SetBackgroundColor(new ColorPt(0.0, 0.0, 0.0), 3);
167 // Add a caption for the pushbutton.
168 $pushbutton1->SetStaticCaptionText("PushButton");
169 $pushbutton1->RefreshAppearance();
170 $blank_page->AnnotPushBack($pushbutton1);
171
172 // ComboBox Widget Creation
173 $combo1 = ComboBoxWidget::Create($doc, new Rect(280.0, 560.0, 580.0, 610.0));
174 // Add options to the combobox widget.
175 $combo1->AddOption("Combo Box No.1");
176 $combo1->AddOption("Combo Box No.2");
177 $combo1->AddOption("Combo Box No.3");
178 // Make one of the options in the combo box selected by default.
179 $combo1->SetSelectedOption("Combo Box No.2");
180 $combo1->SetTextColor(new ColorPt(1.0, 0.0, 0.0), 3);
181 $combo1->SetFontSize(28);
182 $combo1->RefreshAppearance();
183 $blank_page->AnnotPushBack($combo1);
184
185 // ListBox Widget Creation
186 $list1 = ListBoxWidget::Create($doc, new Rect(400.0, 620.0, 580.0, 730.0));
187 // Add one option to the listbox widget.
188 $list1->AddOption("List Box No.1");
189 // Add multiple options to the listbox widget in a batch.
190 $list_options = array("List Box No.2", "List Box No.3");
191 $list1->AddOptions($list_options);
192 // Select some of the options in list box as default options
193 $list1->SetSelectedOptions($list_options);
194 // Enable list box to have multi-select when editing.
195 $list1->GetField()->SetFlag(Field::e_multiselect, true);
196 $list1->SetFont(Font::Create($doc->GetSDFDoc(), Font::e_times_italic));
197 $list1->SetTextColor(new ColorPt(1.0, 0.0, 0.0), 3);
198 $list1->SetFontSize(28);
199 $list1->SetBackgroundColor(new ColorPt(1.0, 1.0, 1.0), 3);
200 $list1->RefreshAppearance();
201 $blank_page->AnnotPushBack($list1);
202
203 // RadioButton Widget Creation
204 // Create a radio button group and add three radio buttons in it.
205 $radio_group = RadioButtonGroup::Create($doc, "RadioGroup");
206 $radiobutton1 = $radio_group->Add(new Rect(140.0, 410.0, 190.0, 460.0));
207 $radiobutton1->SetBackgroundColor(new ColorPt(1.0, 1.0, 0.0), 3);
208 $radiobutton1->RefreshAppearance();
209 $radiobutton2 = $radio_group->Add(new Rect(310.0, 410.0, 360.0, 460.0));
210 $radiobutton2->SetBackgroundColor(new ColorPt(0.0, 1.0, 0.0), 3);
211 $radiobutton2->RefreshAppearance();
212 $radiobutton3 = $radio_group->Add(new Rect(480.0, 410.0, 530.0, 460.0));
213 // Enable the third radio button. By default the first one is selected
214 $radiobutton3->EnableButton();
215 $radiobutton3->SetBackgroundColor(new ColorPt(0.0, 1.0, 1.0), 3);
216 $radiobutton3->RefreshAppearance();
217 $radio_group->AddGroupButtonsToPage($blank_page);
218
219 // Custom push button annotation creation
220 $custom_pushbutton1 = PushButtonWidget::Create($doc, new Rect(260.0, 320.0, 360.0, 360.0));
221 // Set the annotation appearance.
222 $custom_pushbutton1->SetAppearance(CreateCustomButtonAppearance($doc, false), Annot::e_normal);
223 // Create 'SubmitForm' action. The action will be linked to the button.
224 $url = FileSpec::CreateURL($doc->GetSDFDoc(), "http://www.pdftron.com");
225 $button_action = Action::CreateSubmitForm($url);
226 // Associate the above action with 'Down' event in annotations action dictionary.
227 $annot_action = $custom_pushbutton1->GetSDFObj()->PutDict("AA");
228 $annot_action->Put("D", $button_action->GetSDFObj());
229 $blank_page->AnnotPushBack($custom_pushbutton1);
230
231 $doc->PagePushBack($blank_page); // Add the page as the last page in the document.
232
233 // If you are not satisfied with the look of default auto-generated appearance
234 // streams you can delete "AP" entry from the Widget annotation and set
235 // "NeedAppearances" flag in AcroForm dictionary:
236 // $doc->GetAcroForm()->PutBool("NeedAppearances", true);
237 // This will force the viewer application to auto-generate new appearance streams
238 // every time the document is opened.
239 //
240 // Alternatively you can generate custom annotation appearance using ElementWriter
241 // and then set the "AP" entry in the widget dictionary to the new appearance
242 // stream.
243 //
244 // Yet another option is to pre-populate field entries with dummy text. When
245 // you edit the field values using PDFNet the new field appearances will match
246 // the old ones.
247
248 $doc->RefreshFieldAppearances();
249
250 $doc->Save($output_path."forms_test1.pdf", 0);
251 echo "Done.\n";
252
253 //----------------------------------------------------------------------------------
254 // Example 2:
255 // Fill-in forms / Modify values of existing fields.
256 // Traverse all form fields in the document (and print out their names).
257 // Search for specific fields in the document.
258 //----------------------------------------------------------------------------------
259
260 $doc = new PDFDoc($output_path."forms_test1.pdf");
261 $doc->InitSecurityHandler();
262
263 $itr = $doc->GetFieldIterator();
264 $field_names = array();
265 for(; $itr->HasNext(); $itr->Next())
266 {
267 $cur_field_name = $itr->Current()->GetName();
268 // Add one to the count for this field name for later processing
269 if(isset($field_names [$cur_field_name])){
270 $field_names [$cur_field_name] += 1;
271 }
272 else{
273 $field_names [$cur_field_name] = 1;
274 }
275 echo nl2br("Field name: ".$itr->Current()->GetName()."\n");
276 echo nl2br("Field partial name: ".$itr->Current()->GetPartialName()."\n");
277
278 echo "Field type: ";
279 $type = $itr->Current()->GetType();
280 $str_val = $itr->Current()->GetValueAsString();
281
282 switch($type)
283 {
284 case Field::e_button:
285 echo nl2br("Button\n");
286 break;
287 case Field::e_radio:
288 echo nl2br("Radio button: Value = ".$str_val."\n");
289 break;
290 case Field::e_check:
291 $itr->Current()->SetValue(true);
292 echo nl2br("Check box: Value = ".$str_val."\n");
293 break;
294 case Field::e_text:
295 {
296 echo nl2br("Text\n");
297 // Edit all variable text in the document
298 $itr->Current()->SetValue("This is a new value. The old one was: ".$str_val);
299 }
300 break;
301 case Field::e_choice: echo nl2br("Choice\n"); break;
302 case Field::e_signature: echo nl2br("Signature\n"); break;
303 }
304
305 echo "------------------------------\n";
306 }
307
308 // Search for a specific field
309 $f = $doc->GetField("employee.name.first");
310 if ($f)
311 {
312 echo nl2br("Field search for ".$f->GetName()." was successful\n");
313 }
314 else
315 {
316 echo nl2br("Field search failed\n");
317 }
318
319 // Regenerate field appearances.
320 $doc->RefreshFieldAppearances();
321 $doc->Save(($output_path."forms_test_edit.pdf"), 0);
322 echo nl2br("Done.\n");
323
324 //----------------------------------------------------------------------------------
325 // Sample: Form templating
326 // Replicate pages and form data within a document. Then rename field names to make
327 // them unique.
328 //----------------------------------------------------------------------------------
329
330 // Sample: Copying the page with forms within the same document
331 $doc = new PDFDoc($output_path."forms_test1.pdf");
332 $doc->InitSecurityHandler();
333
334 $src_page = $doc->GetPage(1);
335 $doc->PagePushBack($src_page); // Append several copies of the first page
336 $doc->PagePushBack($src_page); // Note that forms are successfully copied
337 $doc->PagePushBack($src_page);
338 $doc->PagePushBack($src_page);
339
340 // Now we rename fields in order to make every field unique.
341 // You can use this technique for dynamic template filling where you have a 'master'
342 // form page that should be replicated, but with unique field names on every page.
343
344 foreach($field_names as $key => $val){
345 RenameAllFields($doc, $key, $val);
346 }
347
348 $doc->Save($output_path."forms_test1_cloned.pdf", 0);
349 echo nl2br("Done.\n");
350
351 //----------------------------------------------------------------------------------
352 // Sample:
353 // Flatten all form fields in a document.
354 // Note that this sample is intended to show that it is possible to flatten
355 // individual fields. PDFNet provides a utility function PDFDoc.FlattenAnnotations()
356 // that will automatically flatten all fields.
357 //----------------------------------------------------------------------------------
358 $doc = new PDFDoc($output_path."forms_test1.pdf");
359 $doc->InitSecurityHandler();
360
361 // Traverse all pages
362 if (false) {
363 $doc->FlattenAnnotations();
364 }
365 else // Manual flattening
366 {
367
368 for ($pitr = $doc->GetPageIterator(); $pitr->HasNext(); $pitr->Next())
369 {
370 $page = $pitr->Current();
371 for ($i = (int)($page->GetNumAnnots())-1; $i>=0; --$i)
372 {
373 $annot = $page->GetAnnot($i);
374 if ($annot->GetType() == Annot::e_Widget)
375 {
376 $annot->Flatten($page);
377 }
378 }
379 }
380 }
381
382
383 $doc->Save(($output_path."forms_test1_flattened.pdf"), 0);
384 PDFNet::Terminate();
385 echo nl2br("Done.\n");
386?>
1#---------------------------------------------------------------------------------------
2# Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
3# Consult LICENSE.txt regarding license information.
4#---------------------------------------------------------------------------------------
5
6import site
7site.addsitedir("../../../PDFNetC/Lib")
8import sys
9from PDFNetPython import *
10import math
11
12sys.path.append("../../LicenseKey/PYTHON")
13from LicenseKey import *
14
15# Relative path to the folder containing the test files.
16input_path = "../../TestFiles/"
17output_path = "../../TestFiles/Output/"
18
19#---------------------------------------------------------------------------------------
20# This sample illustrates basic PDFNet capabilities related to interactive
21# forms (also known as AcroForms).
22#---------------------------------------------------------------------------------------
23
24# field_nums has to be greater than 0.
25def RenameAllFields(doc, name, field_nums):
26 itr = doc.GetFieldIterator(name)
27 counter = 1
28 while itr.HasNext():
29 f = itr.Current()
30 radio_counter = (int)(math.ceil(counter/float(field_nums)))
31 f.Rename(name + "-" + str(radio_counter))
32 itr = doc.GetFieldIterator(name)
33 counter = counter + 1
34
35def CreateCustomButtonAppearance(doc, button_down):
36 # Create a button appearance stream ------------------------------------
37 build = ElementBuilder()
38 writer = ElementWriter()
39 writer.Begin(doc.GetSDFDoc())
40
41 # Draw background
42 element = build.CreateRect(0, 0, 101, 37)
43 element.SetPathFill(True)
44 element.SetPathStroke(False)
45 element.GetGState().SetFillColorSpace(ColorSpace.CreateDeviceGray())
46 element.GetGState().SetFillColor(ColorPt(0.75, 0, 0))
47 writer.WriteElement(element)
48
49 # Draw 'Submit' text
50 writer.WriteElement(build.CreateTextBegin())
51 text = "Submit"
52 element = build.CreateTextRun(text, Font.Create(doc.GetSDFDoc(), Font.e_helvetica_bold), 12)
53 element.GetGState().SetFillColor(ColorPt(0, 0, 0))
54
55 if button_down:
56 element.SetTextMatrix(1, 0, 0, 1, 33, 10)
57 else:
58 element.SetTextMatrix(1, 0, 0, 1, 30, 13)
59 writer.WriteElement(element)
60
61 writer.WritePlacedElement(build.CreateTextEnd())
62
63 stm = writer.End()
64
65 # Set the bounding box
66 stm.PutRect("BBox", 0, 0, 101, 37)
67 stm.PutName("Subtype","Form")
68 return stm
69
70
71
72
73def main():
74 PDFNet.Initialize(LicenseKey)
75
76 # The vector used to store the name and count of all fields.
77 # This is used later on to clone the fields
78 field_names = dict()
79
80 #----------------------------------------------------------------------------------
81 # Example 1: Programatically create new Form Fields and Widget Annotations.
82 #----------------------------------------------------------------------------------
83
84 doc = PDFDoc()
85
86 # Create a blank new page and Add some form fields.
87 blank_page = doc.PageCreate()
88
89 # Text Widget Creation
90 # Create an empty text widget with black text.
91 text1 = TextWidget.Create(doc, Rect(110, 700, 380, 730))
92 text1.SetText("Basic Text Field")
93 text1.RefreshAppearance()
94 blank_page.AnnotPushBack(text1)
95 # Create a vertical text widget with blue text and a yellow background.
96 text2 = TextWidget.Create(doc, Rect(50, 400, 90, 730))
97 text2.SetRotation(90)
98 # Set the text content.
99 text2.SetText(" ****Lucky Stars!****");
100 # Set the font type, text color, font size, border color and background color.
101 text2.SetFont(Font.Create(doc.GetSDFDoc(), Font.e_helvetica_oblique))
102 text2.SetFontSize(28)
103 text2.SetTextColor(ColorPt(0, 0, 1), 3)
104 text2.SetBorderColor(ColorPt(0, 0, 0), 3)
105 text2.SetBackgroundColor(ColorPt(1, 1, 0), 3)
106 text2.RefreshAppearance()
107 # Add the annotation to the page.
108 blank_page.AnnotPushBack(text2)
109 # Create two new text widget with Field names employee.name.first and employee.name.last
110 # This logic shows how these widgets can be created using either a field name string or
111 # a Field object
112 text3 = TextWidget.Create(doc, Rect(110, 660, 380, 690), "employee.name.first")
113 text3.SetText("Levi")
114 text3.SetFont(Font.Create(doc.GetSDFDoc(), Font.e_times_bold))
115 text3.RefreshAppearance()
116 blank_page.AnnotPushBack(text3)
117 emp_last_name = doc.FieldCreate("employee.name.last", Field.e_text, "Ackerman")
118 text4 = TextWidget.Create(doc, Rect(110, 620, 380, 650), emp_last_name)
119 text4.SetFont(Font.Create(doc.GetSDFDoc(), Font.e_times_bold))
120 text4.RefreshAppearance()
121 blank_page.AnnotPushBack(text4)
122
123 # Signature Widget Creation (unsigned)
124 signature1 = SignatureWidget.Create(doc, Rect(110, 560, 260, 610))
125 signature1.RefreshAppearance()
126 blank_page.AnnotPushBack(signature1)
127
128 # CheckBox Widget Creation
129 # Create a check box widget that is not checked.
130 check1 = CheckBoxWidget.Create(doc, Rect(140, 490, 170, 520))
131 check1.RefreshAppearance()
132 blank_page.AnnotPushBack(check1)
133 # Create a check box widget that is checked.
134 check2 = CheckBoxWidget.Create(doc, Rect(190, 490, 250, 540), "employee.name.check1")
135 check2.SetBackgroundColor(ColorPt(1, 1, 1), 3)
136 check2.SetBorderColor(ColorPt(0, 0, 0), 3)
137 # Check the widget (by default it is unchecked).
138 check2.SetChecked(True)
139 check2.RefreshAppearance()
140 blank_page.AnnotPushBack(check2)
141
142 # PushButton Widget Creation
143 pushbutton1 = PushButtonWidget.Create(doc, Rect(380, 490, 520, 540))
144 pushbutton1.SetTextColor(ColorPt(1, 1, 1), 3)
145 pushbutton1.SetFontSize(36)
146 pushbutton1.SetBackgroundColor(ColorPt(0, 0, 0), 3)
147 # Add a caption for the pushbutton.
148 pushbutton1.SetStaticCaptionText("PushButton")
149 pushbutton1.RefreshAppearance()
150 blank_page.AnnotPushBack(pushbutton1)
151
152 # ComboBox Widget Creation
153 combo1 = ComboBoxWidget.Create(doc, Rect(280, 560, 580, 610));
154 # Add options to the combobox widget.
155 combo1.AddOption("Combo Box No.1")
156 combo1.AddOption("Combo Box No.2")
157 combo1.AddOption("Combo Box No.3")
158 # Make one of the options in the combo box selected by default.
159 combo1.SetSelectedOption("Combo Box No.2")
160 combo1.SetTextColor(ColorPt(1, 0, 0), 3)
161 combo1.SetFontSize(28)
162 combo1.RefreshAppearance()
163 blank_page.AnnotPushBack(combo1)
164
165 # ListBox Widget Creation
166 list1 = ListBoxWidget.Create(doc, Rect(400, 620, 580, 730))
167 # Add one option to the listbox widget.
168 list1.AddOption("List Box No.1")
169 # Add multiple options to the listbox widget in a batch.
170 list_options = ["List Box No.2", "List Box No.3"]
171 list1.AddOptions(list_options)
172 # Select some of the options in list box as default options
173 list1.SetSelectedOptions(list_options)
174 # Enable list box to have multi-select when editing.
175 list1.GetField().SetFlag(Field.e_multiselect, True)
176 list1.SetFont(Font.Create(doc.GetSDFDoc(),Font.e_times_italic))
177 list1.SetTextColor(ColorPt(1, 0, 0), 3)
178 list1.SetFontSize(28)
179 list1.SetBackgroundColor(ColorPt(1, 1, 1), 3)
180 list1.RefreshAppearance()
181 blank_page.AnnotPushBack(list1)
182
183 # RadioButton Widget Creation
184 # Create a radio button group and Add three radio buttons in it.
185 radio_group = RadioButtonGroup.Create(doc, "RadioGroup")
186 radiobutton1 = radio_group.Add(Rect(140, 410, 190, 460))
187 radiobutton1.SetBackgroundColor(ColorPt(1, 1, 0), 3)
188 radiobutton1.RefreshAppearance()
189 radiobutton2 = radio_group.Add(Rect(310, 410, 360, 460))
190 radiobutton2.SetBackgroundColor(ColorPt(0, 1, 0), 3)
191 radiobutton2.RefreshAppearance()
192 radiobutton3 = radio_group.Add(Rect(480, 410, 530, 460))
193 # Enable the third radio button. By default the first one is selected
194 radiobutton3.EnableButton()
195 radiobutton3.SetBackgroundColor(ColorPt(0, 1, 1), 3)
196 radiobutton3.RefreshAppearance()
197 radio_group.AddGroupButtonsToPage(blank_page)
198
199 # Custom push button annotation creation
200 custom_pushbutton1 = PushButtonWidget.Create(doc, Rect(260, 320, 360, 360))
201 # Set the annotation appearance.
202 custom_pushbutton1.SetAppearance(CreateCustomButtonAppearance(doc, False), Annot.e_normal)
203 # Create 'SubmitForm' action. The action will be linked to the button.
204 url = FileSpec.CreateURL(doc.GetSDFDoc(), "http://www.pdftron.com")
205 button_action = Action.CreateSubmitForm(url)
206 # Associate the above action with 'Down' event in annotations action dictionary.
207 annot_action = custom_pushbutton1.GetSDFObj().PutDict("AA")
208 annot_action.Put("D", button_action.GetSDFObj())
209 blank_page.AnnotPushBack(custom_pushbutton1)
210
211 # Add the page as the last page in the document.
212 doc.PagePushBack(blank_page)
213
214 # If you are not satisfied with the look of default auto-generated appearance
215 # streams you can delete "AP" entry from the Widget annotation and set
216 # "NeedAppearances" flag in AcroForm dictionary:
217 # doc.GetAcroForm().PutBool("NeedAppearances", true);
218 # This will force the viewer application to auto-generate new appearance streams
219 # every time the document is opened.
220 #
221 # Alternatively you can generate custom annotation appearance using ElementWriter
222 # and then set the "AP" entry in the widget dictionary to the new appearance
223 # stream.
224 #
225 # Yet another option is to pre-populate field entries with dummy text. When
226 # you edit the field values using PDFNet the new field appearances will match
227 # the old ones.
228
229 #doc.GetAcroForm().PutBool("NeedAppearances", True)
230 doc.RefreshFieldAppearances()
231
232 doc.Save(output_path + "forms_test1.pdf", 0)
233 doc.Close()
234 print("Done.")
235
236 #----------------------------------------------------------------------------------
237 # Example 2:
238 # Fill-in forms / Modify values of existing fields.
239 # Traverse all form fields in the document (and sys.stdout.write(out their names).
240 # Search for specific fields in the document.
241 #----------------------------------------------------------------------------------
242
243 doc = PDFDoc(output_path + "forms_test1.pdf")
244 doc.InitSecurityHandler()
245
246 itr = doc.GetFieldIterator()
247 while itr.HasNext():
248
249 cur_field_name = itr.Current().GetName()
250 # Add one to the count for this field name for later processing
251 if sys.version_info.major >= 3:
252 field_names[cur_field_name] = field_names[cur_field_name] + 1 if cur_field_name in field_names else 1
253 else:
254 field_names[cur_field_name] = field_names[cur_field_name] + 1 if field_names.has_key(cur_field_name) else 1
255
256 print("Field name: " + itr.Current().GetName())
257 print("Field partial name: " + itr.Current().GetPartialName())
258
259 sys.stdout.write("Field type: ")
260 type = itr.Current().GetType()
261 str_val = itr.Current().GetValueAsString()
262 if type == Field.e_button:
263 sys.stdout.write("Button" + '\n')
264 elif type == Field.e_radio:
265 sys.stdout.write("Radio button: Value = " + str_val + '\n')
266 elif type == Field.e_check:
267 itr.Current().SetValue(True)
268 sys.stdout.write("Check box: Value = " + str_val + '\n')
269 elif type == Field.e_text:
270 sys.stdout.write("Text" + '\n')
271 # Edit all variable text in the document
272 if itr.Current().GetValue():
273 old_value = itr.Current().GetValueAsString();
274 itr.Current().SetValue("This is a new value. The old one was: " + old_value)
275 elif type == Field.e_choice:
276 sys.stdout.write("Choice" + '\n')
277 elif type == Field.e_signature:
278 sys.stdout.write("Signature" + '\n')
279 print("------------------------------")
280 itr.Next()
281 # Search for a specific field
282 f = doc.GetField("employee.name.first")
283 if f != None:
284 print("Field search for " + f.GetName() + " was successful")
285 else:
286 print("Field search failed")
287
288 # Regenerate field appearances.
289 doc.RefreshFieldAppearances()
290 doc.Save(output_path + "forms_test_edit.pdf", 0)
291 doc.Close()
292 print("Done.")
293
294 #----------------------------------------------------------------------------------
295 # Sample: Form templating
296 # Replicate pages and form data within a document. Then rename field names to make
297 # them unique.
298 #----------------------------------------------------------------------------------
299
300 # Sample: Copying the page with forms within the same document
301 doc = PDFDoc(output_path + "forms_test1.pdf")
302 doc.InitSecurityHandler()
303
304 src_page = doc.GetPage(1)
305 doc.PagePushBack(src_page) # Append several copies of the first page
306 doc.PagePushBack(src_page) # Note that forms are successfully copied
307 doc.PagePushBack(src_page)
308 doc.PagePushBack(src_page)
309
310 # Now we rename fields in order to make every field unique.
311 # You can use this technique for dynamic template filling where you have a 'master'
312 # form page that should be replicated, but with unique field names on every page.
313 for cur_field in field_names.keys():
314 RenameAllFields(doc, cur_field, field_names.get(cur_field))
315
316 doc.Save(output_path + "forms_test1_cloned.pdf", 0)
317 doc.Close()
318 print("Done.")
319
320 #----------------------------------------------------------------------------------
321 # Sample:
322 # Flatten all form fields in a document.
323 # Note that this sample is intended to show that it is possible to flatten
324 # individual fields. PDFNet provides a utility function PDFDoc.FlattenAnnotations()
325 # that will automatically flatten all fields.
326 #----------------------------------------------------------------------------------
327 doc = PDFDoc(output_path + "forms_test1.pdf")
328 doc.InitSecurityHandler()
329
330 # Traverse all pages
331 if False:
332 doc.FlattenAnnotations()
333 else: # Manual flattening
334 pitr = doc.GetPageIterator()
335 while pitr.HasNext():
336 page = pitr.Current()
337 i = page.GetNumAnnots() - 1
338 while i >= 0:
339 annot = page.GetAnnot(i)
340 if annot.GetType() == Annot.e_Widget:
341 annot.Flatten(page)
342 i = i - 1
343 pitr.Next()
344
345 doc.Save(output_path + "forms_test1_flattened.pdf", 0)
346 doc.Close()
347 PDFNet.Terminate()
348 print("Done.")
349
350if __name__ == '__main__':
351 main()
1#---------------------------------------------------------------------------------------
2# Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
3# Consult LICENSE.txt regarding license information.
4#---------------------------------------------------------------------------------------
5
6require '../../../PDFNetC/Lib/PDFNetRuby'
7include PDFNetRuby
8require '../../LicenseKey/RUBY/LicenseKey'
9
10$stdout.sync = true
11
12# Relative path to the folder containing the test files.
13input_path = "../../TestFiles/"
14output_path = "../../TestFiles/Output/"
15
16#---------------------------------------------------------------------------------------
17# This sample illustrates basic PDFNet capabilities related to interactive
18# forms (also known as AcroForms).
19#---------------------------------------------------------------------------------------
20
21# field_nums has to be greater than 0.
22def RenameAllFields(doc, name, field_nums = 1)
23 itr = doc.GetFieldIterator(name)
24 counter = 1
25 while itr.HasNext do
26 f = itr.Current
27 radio_counter = ((counter*1.0/field_nums).ceil).to_i
28 f.Rename(name + "-" + radio_counter.to_s)
29
30 itr = doc.GetFieldIterator(name)
31 counter = counter + 1
32 end
33end
34
35
36def CreateCustomButtonAppearance(doc, button_down)
37 # Create a button appearance stream ------------------------------------
38 build = ElementBuilder.new
39 writer = ElementWriter.new
40 writer.Begin(doc.GetSDFDoc)
41
42 # Draw background
43 element = build.CreateRect(0, 0, 101, 37)
44 element.SetPathFill(true)
45 element.SetPathStroke(false)
46 element.GetGState.SetFillColorSpace(ColorSpace.CreateDeviceGray)
47 element.GetGState.SetFillColor(ColorPt.new(0.75, 0, 0))
48 writer.WriteElement(element)
49
50 # Draw 'Submit' text
51 writer.WriteElement(build.CreateTextBegin)
52 text = "Submit"
53 element = build.CreateTextRun(text, Font.Create(doc.GetSDFDoc, Font::E_helvetica_bold), 12)
54 element.GetGState.SetFillColor(ColorPt.new(0, 0, 0))
55
56 if button_down
57 element.SetTextMatrix(1, 0, 0, 1, 33, 10)
58 else
59 element.SetTextMatrix(1, 0, 0, 1, 30, 13)
60 end
61 writer.WriteElement(element)
62
63 writer.WritePlacedElement(build.CreateTextEnd)
64
65 stm = writer.End
66
67 # Set the bounding box
68 stm.PutRect("BBox", 0, 0, 101, 37)
69 stm.PutName("Subtype","Form")
70 return stm
71end
72
73
74 PDFNet.Initialize(PDFTronLicense.Key)
75
76 #----------------------------------------------------------------------------------
77 # Example 1: Programatically create new Form Fields and Widget Annotations.
78 #----------------------------------------------------------------------------------
79
80 doc = PDFDoc.new
81
82 # Create a blank new page and Add some form fields.
83 blank_page = doc.PageCreate
84
85 # Text Widget Creation
86 # Create an empty text widget with black text.
87 text1 = TextWidget.Create(doc, Rect.new(110, 700, 380, 730))
88 text1.SetText("Basic Text Field")
89 text1.RefreshAppearance
90 blank_page.AnnotPushBack(text1)
91 # Create a vertical text widget with blue text and a yellow background.
92 text2 = TextWidget.Create(doc, Rect.new(50, 400, 90, 730))
93 text2.SetRotation(90)
94 # Set the text content.
95 text2.SetText(" ****Lucky Stars!****");
96 # Set the font type, text color, font size, border color and background color.
97 text2.SetFont(Font.Create(doc.GetSDFDoc, Font::E_helvetica_oblique))
98 text2.SetFontSize(28)
99 text2.SetTextColor(ColorPt.new(0, 0, 1), 3)
100 text2.SetBorderColor(ColorPt.new(0, 0, 0), 3)
101 text2.SetBackgroundColor(ColorPt.new(1, 1, 0), 3)
102 text2.RefreshAppearance
103 # Add the annotation to the page.
104 blank_page.AnnotPushBack(text2)
105 # Create two new text widget with Field names employee.name.first and employee.name.last
106 # This logic shows how these widgets can be created using either a field name string or
107 # a Field object
108 text3 = TextWidget.Create(doc, Rect.new(110, 660, 380, 690), "employee.name.first")
109 text3.SetText("Levi")
110 text3.SetFont(Font.Create(doc.GetSDFDoc, Font::E_times_bold))
111 text3.RefreshAppearance
112 blank_page.AnnotPushBack(text3)
113 emp_last_name = doc.FieldCreate("employee.name.last", Field::E_text, "Ackerman")
114 text4 = TextWidget.Create(doc, Rect.new(110, 620, 380, 650), emp_last_name)
115 text4.SetFont(Font.Create(doc.GetSDFDoc, Font::E_times_bold))
116 text4.RefreshAppearance
117 blank_page.AnnotPushBack(text4)
118
119 # Signature Widget Creation (unsigned)
120 signature1 = SignatureWidget.Create(doc, Rect.new(110, 560, 260, 610))
121 signature1.RefreshAppearance
122 blank_page.AnnotPushBack(signature1)
123
124 # CheckBox Widget Creation
125 # Create a check box widget that is not checked.
126 check1 = CheckBoxWidget.Create(doc, Rect.new(140, 490, 170, 520))
127 check1.RefreshAppearance
128 blank_page.AnnotPushBack(check1)
129 # Create a check box widget that is checked.
130 check2 = CheckBoxWidget.Create(doc, Rect.new(190, 490, 250, 540), "employee.name.check1")
131 check2.SetBackgroundColor(ColorPt.new(1, 1, 1), 3)
132 check2.SetBorderColor(ColorPt.new(0, 0, 0), 3)
133 # Check the widget (by default it is unchecked).
134 check2.SetChecked(true)
135 check2.RefreshAppearance
136 blank_page.AnnotPushBack(check2)
137
138 # PushButton Widget Creation
139 pushbutton1 = PushButtonWidget.Create(doc, Rect.new(380, 490, 520, 540))
140 pushbutton1.SetTextColor(ColorPt.new(1, 1, 1), 3)
141 pushbutton1.SetFontSize(36)
142 pushbutton1.SetBackgroundColor(ColorPt.new(0, 0, 0), 3)
143 # Add a caption for the pushbutton.
144 pushbutton1.SetStaticCaptionText("PushButton")
145 pushbutton1.RefreshAppearance
146 blank_page.AnnotPushBack(pushbutton1)
147
148 # ComboBox Widget Creation
149 combo1 = ComboBoxWidget.Create(doc, Rect.new(280, 560, 580, 610));
150 # Add options to the combobox widget.
151 combo1.AddOption("Combo Box No.1")
152 combo1.AddOption("Combo Box No.2")
153 combo1.AddOption("Combo Box No.3")
154 # Make one of the options in the combo box selected by default.
155 combo1.SetSelectedOption("Combo Box No.2")
156 combo1.SetTextColor(ColorPt.new(1, 0, 0), 3)
157 combo1.SetFontSize(28)
158 combo1.RefreshAppearance
159 blank_page.AnnotPushBack(combo1)
160
161 # ListBox Widget Creation
162 list1 = ListBoxWidget.Create(doc, Rect.new(400, 620, 580, 730))
163 # Add one option to the listbox widget.
164 list1.AddOption("List Box No.1")
165 # Add multiple options to the listbox widget in a batch.
166 list_options = ["List Box No.2", "List Box No.3"]
167 list1.AddOptions(list_options)
168 # Select some of the options in list box as default options
169 list1.SetSelectedOptions(list_options)
170 # Enable list box to have multi-select when editing.
171 list1.GetField().SetFlag(Field::E_multiselect, true)
172 list1.SetFont(Font.Create(doc.GetSDFDoc,Font::E_times_italic))
173 list1.SetTextColor(ColorPt.new(1, 0, 0), 3)
174 list1.SetFontSize(28)
175 list1.SetBackgroundColor(ColorPt.new(1, 1, 1), 3)
176 list1.RefreshAppearance
177 blank_page.AnnotPushBack(list1)
178
179 # RadioButton Widget Creation
180 # Create a radio button group and Add three radio buttons in it.
181 radio_group = RadioButtonGroup.Create(doc, "RadioGroup")
182 radiobutton1 = radio_group.Add(Rect.new(140, 410, 190, 460))
183 radiobutton1.SetBackgroundColor(ColorPt.new(1, 1, 0), 3)
184 radiobutton1.RefreshAppearance
185 radiobutton2 = radio_group.Add(Rect.new(310, 410, 360, 460))
186 radiobutton2.SetBackgroundColor(ColorPt.new(0, 1, 0), 3)
187 radiobutton2.RefreshAppearance
188 radiobutton3 = radio_group.Add(Rect.new(480, 410, 530, 460))
189 # Enable the third radio button. By default the first one is selected
190 radiobutton3.EnableButton
191 radiobutton3.SetBackgroundColor(ColorPt.new(0, 1, 1), 3)
192 radiobutton3.RefreshAppearance
193 radio_group.AddGroupButtonsToPage(blank_page)
194
195 # Custom push button annotation creation
196 custom_pushbutton1 = PushButtonWidget.Create(doc, Rect.new(260, 320, 360, 360))
197 # Set the annotation appearance.
198 custom_pushbutton1.SetAppearance(CreateCustomButtonAppearance(doc, false), Annot::E_normal)
199 # Create 'SubmitForm' action. The action will be linked to the button.
200 url = FileSpec.CreateURL(doc.GetSDFDoc, "http://www.pdftron.com")
201 button_action = Action.CreateSubmitForm(url)
202 # Associate the above action with 'Down' event in annotations action dictionary.
203 annot_action = custom_pushbutton1.GetSDFObj.PutDict("AA")
204 annot_action.Put("D", button_action.GetSDFObj)
205 blank_page.AnnotPushBack(custom_pushbutton1)
206
207
208 # Add the page as the last page in the document.
209 doc.PagePushBack(blank_page)
210
211 # If you are not satisfied with the look of default auto-generated appearance
212 # streams you can delete "AP" entry from the Widget annotation and set
213 # "NeedAppearances" flag in AcroForm dictionary:
214 # doc.GetAcroForm.PutBool("NeedAppearances", true);
215 # This will force the viewer application to auto-generate new appearance streams
216 # every time the document is opened.
217 #
218 # Alternatively you can generate custom annotation appearance using ElementWriter
219 # and then set the "AP" entry in the widget dictionary to the new appearance
220 # stream.
221 #
222 # Yet another option is to pre-populate field entries with dummy text. When
223 # you edit the field values using PDFNet the new field appearances will match
224 # the old ones.
225
226 #doc.GetAcroForm.PutBool("NeedAppearances", true)
227 doc.RefreshFieldAppearances
228
229 doc.Save(output_path + "forms_test1.pdf", 0)
230 doc.Close
231 puts "Done."
232
233 #----------------------------------------------------------------------------------
234 # Example 2:
235 # Fill-in forms / Modify values of existing fields.
236 # Traverse all form fields in the document (and puts out their names).
237 # Search for specific fields in the document.
238 #----------------------------------------------------------------------------------
239
240 doc = PDFDoc.new(output_path + "forms_test1.pdf")
241 doc.InitSecurityHandler
242
243 itr = doc.GetFieldIterator
244 field_names = Hash.new
245 while itr.HasNext do
246
247 cur_field_name = itr.Current.GetName
248 # Add one to the count for this field name for later processing
249 field_names[cur_field_name] = field_names.has_key?(cur_field_name) ? field_names[cur_field_name] + 1 : 1
250
251 puts "Field name: " + itr.Current.GetName
252 puts "Field partial name: " + itr.Current.GetPartialName
253
254 print "Field type: "
255 type = itr.Current.GetType
256 str_val = itr.Current.GetValueAsString
257 if type == Field::E_button
258 puts "Button"
259 elsif type == Field::E_radio
260 puts "Radio button: Value = " + str_val
261 elsif type == Field::E_check
262 itr.Current.SetValue(true)
263 puts "Check box: Value = " + str_val
264 elsif type == Field::E_text
265 puts "Text"
266 # Edit all variable text in the document
267 itr.Current.SetValue("This is a new value. The old one was: " + str_val)
268 elsif type == Field::E_choice
269 puts "Choice"
270 elsif type == Field::E_signature
271 puts "Signature"
272 end
273 puts "------------------------------"
274 itr.Next
275 end
276
277 # Search for a specific field
278 f = doc.GetField("employee.name.first")
279 if !f.nil?
280 puts "Field search for " + f.GetName + " was successful"
281 else
282 puts "Field search failed"
283 end
284
285 # Regenerate field appearances.
286 doc.RefreshFieldAppearances
287 doc.Save(output_path + "forms_test_edit.pdf", 0)
288 doc.Close
289 puts "Done."
290
291 #----------------------------------------------------------------------------------
292 # Sample: Form templating
293 # Replicate pages and form data within a document. Then rename field names to make
294 # them unique.
295 #----------------------------------------------------------------------------------
296
297 # Sample: Copying the page with forms within the same document
298 doc = PDFDoc.new(output_path + "forms_test1.pdf")
299 doc.InitSecurityHandler
300
301 src_page = doc.GetPage(1)
302 doc.PagePushBack(src_page) # Append several copies of the first page
303 doc.PagePushBack(src_page) # Note that forms are successfully copied
304 doc.PagePushBack(src_page)
305 doc.PagePushBack(src_page)
306
307 # Now we rename fields in order to make every field unique.
308 # You can use this technique for dynamic template filling where you have a 'master'
309 # form page that should be replicated, but with unique field names on every page.
310 field_names.each do | key, val |
311 RenameAllFields(doc, key, val)
312 end
313 doc.Save(output_path + "forms_test1_cloned.pdf", 0)
314 doc.Close
315 puts "Done."
316
317 #----------------------------------------------------------------------------------
318 # Sample:
319 # Flatten all form fields in a document.
320 # Note that this sample is intended to show that it is possible to flatten
321 # individual fields. PDFNet provides a utility function PDFDoc.FlattenAnnotations
322 # that will automatically flatten all fields.
323 #----------------------------------------------------------------------------------
324 doc = PDFDoc.new(output_path + "forms_test1.pdf")
325 doc.InitSecurityHandler
326
327 # Traverse all pages
328 if false
329 doc.FlattenAnnotations
330 else # Manual flattening
331 pitr = doc.GetPageIterator
332 while pitr.HasNext do
333 page = pitr.Current
334 i = page.GetNumAnnots - 1
335 while i >= 0
336 annot = page.GetAnnot(i)
337 if annot.GetType == Annot::E_Widget
338 annot.Flatten(page)
339 end
340 i = i - 1
341 end
342 pitr.Next
343 end
344 end
345
346 doc.Save(output_path + "forms_test1_flattened.pdf", 0)
347 doc.Close
348 PDFNet.Terminate
349 puts "Done."
1'---------------------------------------------------------------------------------------
2' Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3' Consult legal.txt regarding legal and license information.
4'---------------------------------------------------------------------------------------
5
6Imports System
7Imports System.Collections.Generic
8Imports pdftron
9Imports pdftron.Common
10Imports pdftron.SDF
11Imports pdftron.PDF
12Imports pdftron.PDF.Annots
13
14'---------------------------------------------------------------------------------------
15' This sample illustrates basic PDFNet capabilities related to interactive
16' forms (also known as AcroForms).
17'---------------------------------------------------------------------------------------
18Module InteractiveFormsTestVB
19 Dim pdfNetLoader As PDFNetLoader
20 Sub New()
21 pdfNetLoader = pdftron.PDFNetLoader.Instance()
22 End Sub
23
24 Sub Main()
25
26 PDFNet.Initialize(PDFTronLicense.Key)
27
28 ' Relative path to the folder containing test files.
29 ' Dim input_path As String = "../../../../TestFiles/"
30 Dim output_path As String = "../../../../TestFiles/Output/"
31
32 ' The vector used to store the name And count of all fields.
33 ' This Is used later on to clone the fields
34 Dim field_names As Dictionary(Of String, Integer) = New Dictionary(Of String, Integer)()
35
36 Try
37 '----------------------------------------------------------------------------------
38 ' Example 1: Programatically create new Form Fields and Widget Annotations.
39 '----------------------------------------------------------------------------------
40 Using doc As PDFDoc = New PDFDoc
41 ' Create a blank page and some new fields (aka "AcroForms").
42 Dim blank_page As Page = doc.PageCreate()
43
44 ' Text Widget Creation
45 ' Create an empty text widget with black text.
46 Dim text1 As TextWidget = TextWidget.Create(doc, New Rect(110, 700, 380, 730))
47 text1.SetText("Basic Text Field")
48 text1.RefreshAppearance()
49 blank_page.AnnotPushBack(text1)
50 ' Create a vertical text widget with blue text And a yellow background.
51 Dim text2 As TextWidget = TextWidget.Create(doc, New Rect(50, 400, 90, 730))
52 text2.SetRotation(90)
53 ' Set the text content.
54 text2.SetText(" ****Lucky Stars!****")
55 ' Set the font type, text color, font size, border color And background color.
56 text2.SetFont(Font.Create(doc, Font.StandardType1Font.e_helvetica_oblique))
57 text2.SetFontSize(28)
58 text2.SetTextColor(New ColorPt(0, 0, 1), 3)
59 text2.SetBorderColor(New ColorPt(0, 0, 0), 3)
60 text2.SetBackgroundColor(New ColorPt(1, 1, 0), 3)
61 text2.RefreshAppearance()
62 ' Add the annotation to the page.
63 blank_page.AnnotPushBack(text2)
64 ' Create two New text widget with Field names employee.name.first And employee.name.last
65 ' This logic shows how these widgets can be created using either a field name string Or
66 ' a Field object
67 Dim text3 As TextWidget = TextWidget.Create(doc, New Rect(110, 660, 380, 690), "employee.name.first")
68 text3.SetText("Levi")
69 text3.SetFont(Font.Create(doc, Font.StandardType1Font.e_times_bold))
70 text3.RefreshAppearance()
71 blank_page.AnnotPushBack(text3)
72 Dim emp_last_name As Field = doc.FieldCreate("employee.name.last", Field.Type.e_text, "Ackerman")
73 Dim text4 As TextWidget = TextWidget.Create(doc, New Rect(110, 620, 380, 650), emp_last_name)
74 text4.SetFont(Font.Create(doc, Font.StandardType1Font.e_times_bold))
75 text4.RefreshAppearance()
76 blank_page.AnnotPushBack(text4)
77
78 ' Signature Widget Creation (unsigned)
79 Dim signature1 As SignatureWidget = SignatureWidget.Create(doc, New Rect(110, 560, 260, 610))
80 signature1.RefreshAppearance()
81 blank_page.AnnotPushBack(signature1)
82
83 ' CheckBox Widget Creation
84 ' Create a check box widget that Is Not checked.
85 Dim check1 As CheckBoxWidget = CheckBoxWidget.Create(doc, New Rect(140, 490, 170, 520))
86 check1.RefreshAppearance()
87 blank_page.AnnotPushBack(check1)
88 ' Create a check box widget that Is checked.
89 Dim check2 As CheckBoxWidget = CheckBoxWidget.Create(doc, New Rect(190, 490, 250, 540), "employee.name.check1")
90 check2.SetBackgroundColor(New ColorPt(1, 1, 1), 3)
91 check2.SetBorderColor(New ColorPt(0, 0, 0), 3)
92 ' Check the widget (by default it Is unchecked).
93 check2.SetChecked(True)
94 check2.RefreshAppearance()
95 blank_page.AnnotPushBack(check2)
96
97 ' PushButton Widget Creation
98 Dim pushbutton1 As PushButtonWidget = PushButtonWidget.Create(doc, New Rect(380, 490, 520, 540))
99 pushbutton1.SetTextColor(New ColorPt(1, 1, 1), 3)
100 pushbutton1.SetFontSize(36)
101 pushbutton1.SetBackgroundColor(New ColorPt(0, 0, 0), 3)
102 ' Add a caption for the pushbutton.
103 pushbutton1.SetStaticCaptionText("PushButton")
104 pushbutton1.RefreshAppearance()
105 blank_page.AnnotPushBack(pushbutton1)
106
107 ' ComboBox Widget Creation
108 Dim combo1 As ComboBoxWidget = ComboBoxWidget.Create(doc, New Rect(280, 560, 580, 610))
109 ' Add options to the combobox widget.
110 combo1.AddOption("Combo Box No.1")
111 combo1.AddOption("Combo Box No.2")
112 combo1.AddOption("Combo Box No.3")
113 ' Make one of the options in the combo box selected by default.
114 combo1.SetSelectedOption("Combo Box No.2")
115 combo1.SetTextColor(New ColorPt(1, 0, 0), 3)
116 combo1.SetFontSize(28)
117 combo1.RefreshAppearance()
118 blank_page.AnnotPushBack(combo1)
119
120 ' ListBox Widget Creation
121 Dim list1 As ListBoxWidget = ListBoxWidget.Create(doc, New Rect(400, 620, 580, 730))
122 ' Add one option to the listbox widget.
123 list1.AddOption("List Box No.1")
124 ' Add multiple options to the listbox widget in a batch.
125 Dim list_options As String() = New String(1) {"List Box No.2", "List Box No.3"}
126 list1.AddOptions(list_options)
127 ' Select some of the options in list box as default options.
128 list1.SetSelectedOptions(list_options)
129 ' Enable list box to have multi-select when editing.
130 list1.GetField().SetFlag(Field.Flag.e_multiselect, True)
131 list1.SetFont(Font.Create(doc, Font.StandardType1Font.e_times_italic))
132 list1.SetTextColor(New ColorPt(1, 0, 0), 3)
133 list1.SetFontSize(28)
134 list1.SetBackgroundColor(New ColorPt(1, 1, 1), 3)
135 list1.RefreshAppearance()
136 blank_page.AnnotPushBack(list1)
137
138 ' RadioButton Widget Creation
139 ' Create a radio button group And add three radio buttons in it.
140 Dim radio_group As RadioButtonGroup = RadioButtonGroup.Create(doc, "RadioGroup")
141 Dim radiobutton1 As RadioButtonWidget = radio_group.Add(New Rect(140, 410, 190, 460))
142 radiobutton1.SetBackgroundColor(New ColorPt(1, 1, 0), 3)
143 radiobutton1.RefreshAppearance()
144 Dim radiobutton2 As RadioButtonWidget = radio_group.Add(New Rect(310, 410, 360, 460))
145 radiobutton2.SetBackgroundColor(New ColorPt(0, 1, 0), 3)
146 radiobutton2.RefreshAppearance()
147 Dim radiobutton3 As RadioButtonWidget = radio_group.Add(New Rect(480, 410, 530, 460))
148 ' Enable the third radio button. By default the first one is selected.
149 radiobutton3.EnableButton()
150 radiobutton3.SetBackgroundColor(New ColorPt(0, 1, 1), 3)
151 radiobutton3.RefreshAppearance()
152 radio_group.AddGroupButtonsToPage(blank_page)
153
154 ' Custom push button annotation creation
155 Dim custom_pushbutton1 As PushButtonWidget = PushButtonWidget.Create(doc, New Rect(260, 320, 360, 360))
156 ' Set the annotation appearance.
157 custom_pushbutton1.SetAppearance(CreateCustomButtonAppearance(doc, False), Annot.AnnotationState.e_normal)
158 ' Create 'SubmitForm' action. The action will be linked to the button.
159 Dim url As FileSpec = FileSpec.CreateURL(doc, "http://www.pdftron.com")
160 Dim button_action As pdftron.PDF.Action = pdftron.PDF.Action.CreateSubmitForm(url)
161 ' Associate the above action with 'Down' event in annotations action dictionary.
162 Dim annot_action As Obj = custom_pushbutton1.GetSDFObj().PutDict("AA")
163 annot_action.Put("D", button_action.GetSDFObj())
164 blank_page.AnnotPushBack(custom_pushbutton1)
165
166 ' Add the page as the last page in the document.
167 doc.PagePushBack(blank_page)
168
169 ' If you are not satisfied with the look of default auto-generated appearance
170 ' streams you can delete "AP" entry from the Widget annotation and set
171 ' "NeedAppearances" flag in AcroForm dictionary:
172 ' doc.GetAcroForm().PutBool("NeedAppearances", true)
173 '
174 ' This will force the viewer application to auto-generate new appearance streams
175 ' every time the document is opened.
176 '
177 ' Alternatively you can generate custom annotation appearance using ElementWriter
178 ' and then set the "AP" entry in the widget dictionary to the new appearance
179 ' stream.
180 '
181 ' Yet another option is to pre-populate field entries with dummy text. When
182 ' you edit the field values using PDFNet the new field appearances will match
183 ' the old ones.
184 doc.RefreshFieldAppearances()
185
186 doc.Save(output_path + "forms_test1.pdf", 0)
187 End Using
188 Console.WriteLine("Done.")
189
190 '----------------------------------------------------------------------------------
191 ' Example 2:
192 ' Fill-in forms / Modify values of existing fields.
193 ' Traverse all form fields in the document (and print out their names).
194 ' Search for specific fields in the document.
195 '----------------------------------------------------------------------------------
196 Using doc As PDFDoc = New PDFDoc(output_path & "forms_test1.pdf")
197 doc.InitSecurityHandler()
198 Dim itr As FieldIterator
199 itr = doc.GetFieldIterator()
200
201 While itr.HasNext()
202 Dim field As Field = itr.Current()
203 Dim cur_field_name As String = field.GetName()
204 ' Add one to the count for this field name for later processing
205 field_names(cur_field_name) = (If(field_names.ContainsKey(cur_field_name), field_names(cur_field_name) + 1, 1))
206 Console.WriteLine("Field name: {0}", field.GetName())
207 Console.WriteLine("Field partial name: {0}", field.GetPartialName())
208 Dim str_val As String = field.GetValueAsString()
209 Console.Write("Field type: ")
210 Dim type As Field.Type = field.[GetType]()
211
212 Select Case type
213 Case Field.Type.e_button
214 Console.WriteLine("Button")
215 Case Field.Type.e_radio
216 Console.WriteLine("Radio button: Value = " & str_val)
217 Case Field.Type.e_check
218 field.SetValue(True)
219 Console.WriteLine("Check box: Value = " & str_val)
220 Case Field.Type.e_text
221 Console.WriteLine("Text")
222 Dim old_value As String = "none"
223 If field.GetValue() IsNot Nothing Then old_value = field.GetValue().GetAsPDFText()
224 ' Edit all variable text in the document
225 field.SetValue("This is a new value. The old one was: " & old_value)
226 Case Field.Type.e_choice
227 Console.WriteLine("Choice")
228 Case Field.Type.e_signature
229 Console.WriteLine("Signature")
230 End Select
231
232 Console.WriteLine("------------------------------")
233 itr.[Next]()
234 End While
235
236 ' Search for a specific field
237 Dim fld As Field = doc.GetField("employee.name.first")
238
239 If fld IsNot Nothing Then
240 Console.WriteLine("Field search for {0} was successful", fld.GetName())
241 Else
242 Console.WriteLine("Field search failed.")
243 End If
244
245 ' Regenerate field appearances.
246 doc.RefreshFieldAppearances()
247 doc.Save(output_path & "forms_test_edit.pdf", 0)
248 ' output PDF doc
249 Console.WriteLine("Done.")
250 End Using
251
252 Catch e As PDFNetException
253 Console.WriteLine(e.Message)
254 End Try
255 '----------------------------------------------------------------------------------
256 ' Sample: Form templating
257 ' Replicate pages and form data within a document. Then rename field names to make
258 ' them unique.
259 '----------------------------------------------------------------------------------
260 Try
261 ' Sample: Copying the page with forms within the same document
262 Using doc As PDFDoc = New PDFDoc(output_path & "forms_test1.pdf")
263 doc.InitSecurityHandler()
264 Dim src_page As Page = doc.GetPage(1)
265 doc.PagePushBack(src_page) ' Append several copies of the first page
266 doc.PagePushBack(src_page) ' Note that forms are successfully copied
267 doc.PagePushBack(src_page)
268 doc.PagePushBack(src_page)
269
270 ' Now we rename fields in order to make every field unique.
271 ' You can use this technique for dynamic template filling where you have a 'master'
272 ' form page that should be replicated, but with unique field names on every page.
273 For Each cur_field As KeyValuePair(Of String, Integer) In field_names
274 RenameAllFields(doc, cur_field.Key, cur_field.Value)
275 Next
276
277 doc.Save(output_path & "forms_test1_cloned.pdf", 0)
278 ' output PDF doc
279 Console.WriteLine("Done.")
280 End Using
281
282 Catch e As PDFNetException
283 Console.WriteLine(e.Message)
284 End Try
285
286 '----------------------------------------------------------------------------------
287 ' Sample:
288 ' Flatten all form fields in a document.
289 ' Note that this sample is intended to show that it is possible to flatten
290 ' individual fields. PDFNet provides a utility function PDFDoc.FlattenAnnotations()
291 ' that will automatically flatten all fields.
292 '----------------------------------------------------------------------------------
293 Try
294
295 Using doc As PDFDoc = New PDFDoc(output_path & "forms_test1.pdf")
296 doc.InitSecurityHandler()
297
298 ' Traverse all pages
299 Dim auto As Boolean = True
300
301 If auto Then
302 doc.FlattenAnnotations()
303 Else ' Manual flattening
304 Dim pitr As PageIterator = doc.GetPageIterator()
305
306 While pitr.HasNext()
307 Dim page As Page = pitr.Current()
308
309 For i As Integer = page.GetNumAnnots() - 1 To 0
310 Dim annot As Annot = page.GetAnnot(i)
311
312 If annot.[GetType]() = Annot.Type.e_Widget Then
313 annot.Flatten(page)
314 End If
315 Next
316
317 pitr.[Next]()
318 End While
319 End If
320
321 doc.Save(output_path & "forms_test1_flattened.pdf", 0)
322 ' output PDF doc
323 Console.WriteLine("Done.")
324 End Using
325
326 Catch e As PDFNetException
327 Console.WriteLine(e.Message)
328 End Try
329 PDFNet.Terminate()
330 End Sub
331
332 ' field_nums has to be greater than 0.
333 Sub RenameAllFields(ByVal doc As PDFDoc, ByVal name As String, ByVal Optional field_nums As Integer = 1)
334 Dim fld As Field = doc.GetField(name)
335 Dim counter As Integer = 1
336
337 While fld IsNot Nothing
338 Dim field_new_name As String = name
339 Dim update_count As Integer = System.Convert.ToInt32(Math.Ceiling(counter / CDbl(field_nums)))
340 fld.Rename(name & "-" & update_count.ToString())
341 fld = doc.GetField(name)
342 counter += 1
343 End While
344 End Sub
345
346 Function CreateCustomButtonAppearance(ByRef doc As PDFDoc, ByVal button_down As Boolean) As Obj
347 ' Create a button appearance stream ------------------------------------
348 Dim builder As ElementBuilder = New ElementBuilder
349 Dim writer As ElementWriter = New ElementWriter
350
351 writer.Begin(doc.GetSDFDoc())
352
353 ' Draw background
354 Dim element As Element = builder.CreateRect(0, 0, 101, 37)
355 element.SetPathFill(True)
356 element.SetPathStroke(False)
357 element.GetGState().SetFillColorSpace(ColorSpace.CreateDeviceGray())
358 element.GetGState().SetFillColor(New ColorPt(0.75, 0, 0))
359 writer.WriteElement(element)
360
361 ' Draw 'Submit' text
362 writer.WriteElement(builder.CreateTextBegin())
363
364 element = builder.CreateTextRun("Submit", Font.Create(doc, Font.StandardType1Font.e_helvetica_bold), 12)
365 element.GetGState().SetFillColor(New ColorPt(0, 0, 0))
366
367 If (button_down) Then
368 element.SetTextMatrix(1, 0, 0, 1, 33, 10)
369 Else
370 element.SetTextMatrix(1, 0, 0, 1, 30, 13)
371 End If
372
373 writer.WriteElement(element)
374 writer.WriteElement(builder.CreateTextEnd())
375
376 Dim stm As Obj = writer.End()
377
378 ' Calling Dispose() on ElementReader/Writer/Builder can result in increased performance and lower memory consumption.
379 writer.Dispose()
380 builder.Dispose()
381
382 ' Set the bounding box
383 stm.PutRect("BBox", 0, 0, 101, 37)
384 stm.PutName("Subtype", "Form")
385 Return stm
386 End Function
387
388End Module
Did you find this helpful?
Trial setup questions?
Ask experts on DiscordNeed other help?
Contact SupportPricing or product questions?
Contact Sales