Sample Obj-C code for using Apryse SDK to programmatically merge forms data with the PDF in order to fill forms, or to extract form field data from the PDF. Apryse SDK has full support for Forms Data Format (FDF). Learn more about our iOS 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
6#import <OBJC/PDFNetOBJC.h>
7#import <Foundation/Foundation.h>
8
9//---------------------------------------------------------------------------------------
10// PDFNet includes a full support for FDF (Forms Data Format) and capability to merge/extract
11// forms data (FDF) with/from PDF. This sample illustrates basic FDF merge/extract functionality
12// available in PDFNet.
13//---------------------------------------------------------------------------------------
14int main(int argc, char *argv[])
15{
16 @autoreleasepool {
17 int ret = 0;
18 [PTPDFNet Initialize: 0];
19
20 // Example 1)
21 // Iterate over all form fields in the document. Display all field names.
22 @try
23 {
24 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/form1.pdf"];
25 [doc InitSecurityHandler];
26
27 PTFieldIterator * itr;
28 for(itr = [doc GetFieldIterator]; [itr HasNext]; [itr Next])
29 {
30 NSLog(@"Field name: %@", [[itr Current] GetName]);
31 NSLog(@"Field partial name: %@", [[itr Current] GetPartialName]);
32
33 //NSLog(@"Field type: ");
34 int type = [[itr Current] GetType];
35 switch(type)
36 {
37 case e_ptbutton: NSLog(@"Field type: Button"); NSLog(@"------------------------------");break;
38 case e_ptcheck: NSLog(@"Field type: Check"); NSLog(@"------------------------------");break;
39 case e_ptradio: NSLog(@"Field type: Radio"); NSLog(@"------------------------------");break;
40 case e_pttext: NSLog(@"Field type: Text"); NSLog(@"------------------------------");break;
41 case e_ptchoice: NSLog(@"Field type: Choice"); NSLog(@"------------------------------");break;
42 case e_ptsignature: NSLog(@"Field type: Signature"); NSLog(@"------------------------------");break;
43 case e_ptf_null: NSLog(@"Field type: Null"); NSLog(@"------------------------------");break;
44 default: NSLog(@"Field type: ------------------------------");
45
46 }
47
48 //NSLog(@"------------------------------");
49 }
50
51 NSLog(@"Done.");
52 }
53 @catch(NSException *e)
54 {
55 NSLog(@"%@", e.reason);
56 ret = 1;
57 }
58
59 // Example 2) Import XFDF into FDF, then merge data from FDF into PDF
60 @try
61 {
62 // XFDF to FDF
63 // form fields
64 NSLog(@"Import form field data from XFDF to FDF.");
65
66 PTFDFDoc *fdf_doc1 = [PTFDFDoc CreateFromXFDF: @"../../TestFiles/form1_data.xfdf"];
67 [fdf_doc1 SaveFDFDocToFile: @"../../TestFiles/Output/form1_data.fdf"];
68
69 // annotations
70 NSLog(@"Import annotations from XFDF to FDF.");
71
72 PTFDFDoc *fdf_doc2 = [PTFDFDoc CreateFromXFDF: @"../../TestFiles/form1_annots.xfdf"];
73 [fdf_doc2 SaveFDFDocToFile: @"../../TestFiles/Output/form1_annots.fdf"];
74
75 // FDF to PDF
76 // form fields
77 NSLog(@"Merge form field data from FDF.");
78
79 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/form1.pdf"];
80 [doc InitSecurityHandler];
81 [doc FDFMerge: fdf_doc1];
82
83 // Refreshing missing appearances is not required here, but is recommended to make them
84 // visible in PDF viewers with incomplete annotation viewing support. (such as Chrome)
85 [doc RefreshAnnotAppearances: NULL];
86
87 [doc SaveToFile: @"../../TestFiles/Output/form1_filled.pdf" flags: e_ptlinearized];
88
89 // annotations
90 NSLog(@"Merge annotations from FDF.");
91
92 [doc FDFMerge: fdf_doc2];
93 // Refreshing missing appearances is not required here, but is recommended to make them
94 // visible in PDF viewers with incomplete annotation viewing support. (such as Chrome)
95 [doc RefreshAnnotAppearances: NULL];
96 [doc SaveToFile: @"../../TestFiles/Output/form1_filled_with_annots.pdf" flags: e_ptlinearized];
97 NSLog(@"Done.");
98 }
99 @catch(NSException *e)
100 {
101 NSLog(@"%@", e.reason);
102 ret = 1;
103 }
104
105 // Example 3) Extract data from PDF to FDF, then export FDF as XFDF
106 @try
107 {
108 // PDF to FDF
109 PTPDFDoc *in_doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/Output/form1_filled_with_annots.pdf"];
110 [in_doc InitSecurityHandler];
111
112 // form fields only
113 NSLog(@"Extract form fields data to FDF.");
114
115 PTFDFDoc *doc_fields = [in_doc FDFExtract: e_ptforms_only];
116 [doc_fields SetPDFFileName: @"../form1_filled_with_annots.pdf"];
117 [doc_fields SaveFDFDocToFile: @"../../TestFiles/Output/form1_filled_data.fdf"];
118
119 // annotations only
120 NSLog(@"Extract annotations to FDF.");
121
122 PTFDFDoc *doc_annots = [in_doc FDFExtract: e_ptannots_only];
123 [doc_annots SetPDFFileName: @"../form1_filled_with_annots.pdf"];
124 [doc_annots SaveFDFDocToFile: @"../../TestFiles/Output/form1_filled_annot.fdf"];
125
126 // both form fields and annotations
127 NSLog(@"Extract both form fields and annotations to FDF.");
128
129 PTFDFDoc *doc_both = [in_doc FDFExtract: e_ptboth];
130 [doc_both SetPDFFileName: @"../form1_filled_with_annots.pdf"];
131 [doc_both SaveFDFDocToFile: @"../../TestFiles/Output/form1_filled_both.fdf"];
132
133 // FDF to XFDF
134 // form fields
135 NSLog(@"Export form field data from FDF to XFDF.");
136
137 [doc_fields SaveAsXFDF: @"../../TestFiles/Output/form1_filled_data.xfdf"];
138
139 // annotations
140 NSLog(@"Export annotations from FDF to XFDF.");
141
142 [doc_annots SaveAsXFDF: @"../../TestFiles/Output/form1_filled_annot.xfdf"];
143
144 // both form fields and annotations
145 NSLog(@"Export both form fields and annotations from FDF to XFDF.");
146
147 [doc_both SaveAsXFDF: @"../../TestFiles/Output/form1_filled_both.xfdf"];
148
149 NSLog(@"Done.");
150 }
151 @catch(NSException *e)
152 {
153 NSLog(@"%@", e.reason);
154 ret = 1;
155 }
156
157 // Example 4) Merge/Extract XFDF into/from PDF
158 @try
159 {
160 // Merge XFDF from string
161 PTPDFDoc *in_doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/numbered.pdf"];
162 [in_doc InitSecurityHandler];
163
164 NSLog(@"Merge XFDF string into PDF.");
165 NSString *str = @"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><xfdf xmlns=\"http://ns.adobe.com/xfdf\" xml:space=\"preserve\"><square subject=\"Rectangle\" page=\"0\" name=\"cf4d2e58-e9c5-2a58-5b4d-9b4b1a330e45\" title=\"user\" creationdate=\"D:20120827112326-07'00'\" date=\"D:20120827112326-07'00'\" rect=\"227.7814207650273,597.6174863387978,437.07103825136608,705.0491803278688\" color=\"#000000\" interior-color=\"#FFFF00\" flags=\"print\" width=\"1\"><popup flags=\"print,nozoom,norotate\" open=\"no\" page=\"0\" rect=\"0,792,0,792\" /></square></xfdf>";
166
167 PTFDFDoc *fdoc = [PTFDFDoc CreateFromXFDF: str];
168 [in_doc FDFMerge: fdoc];
169 [in_doc SaveToFile: @"../../TestFiles/Output/numbered_modified.pdf" flags: e_ptlinearized];
170
171 NSLog(@"Merge complete.");
172
173 // Extract XFDF as string
174 NSLog(@"Extract XFDF as a string.");
175 PTFDFDoc *fdoc_new = [in_doc FDFExtract: e_ptboth];
176 NSString *XFDF_str = [fdoc_new SaveAsXFDFToString];
177 NSLog(@"Extracted XFDF: ");
178 NSLog(@"%@", XFDF_str);
179 NSLog(@"Extract complete.");
180 }
181 @catch(NSException *e)
182 {
183 NSLog(@"%@", e.reason);
184 ret = 1;
185 }
186
187 // Example 5) Read FDF files directly
188 @try
189 {
190 PTFDFDoc *doc = [[PTFDFDoc alloc] initWithFilepath: @"../../TestFiles/Output/form1_filled_data.fdf"];
191
192 PTFDFFieldIterator *itr;
193 for(itr = [doc GetFieldIterator]; [itr HasNext]; [itr Next])
194 {
195 NSLog(@"Field name: %@", [[itr Current] GetName]);
196 NSLog(@"Field partial name: %@", [[itr Current] GetPartialName]);
197
198 NSLog(@"------------------------------");
199 }
200
201 NSLog(@"Done.");
202 }
203 @catch(NSException *e)
204 {
205 NSLog(@"%@", e.reason);
206 ret = 1;
207 }
208
209 // Example 6) Direct generation of FDF.
210 @try
211 {
212 PTFDFDoc *doc = [[PTFDFDoc alloc] init];
213 // Create new fields (i.e. key/value pairs).
214 [doc FieldCreateWithString: @"Company" type: e_pttext field_value: @"PDFTron Systems"];
215 [doc FieldCreateWithString: @"First Name" type: e_pttext field_value: @"John"];
216 [doc FieldCreateWithString: @"Last Name" type: e_pttext field_value: @"Doe"];
217 // ...
218
219 // [doc SetPdfFileName: @"mydoc.pdf"];
220
221 [doc SaveFDFDocToFile: @"../../TestFiles/Output/sample_output.fdf"];
222 NSLog(@"Done. Results saved in sample_output.fdf");
223 }
224 @catch(NSException *e)
225 {
226 NSLog(@"%@", e.reason);
227 ret = 1;
228 }
229 [PTPDFNet Terminate: 0];
230 return ret;
231 }
232}
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2019 by PDFTron Systems Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6import PDFNet
7import Foundation
8
9//---------------------------------------------------------------------------------------
10// PDFNet includes a full support for FDF (Forms Data Format) and capability to merge/extract
11// forms data (FDF) with/from PDF. This sample illustrates basic FDF merge/extract functionality
12// available in PDFNet.
13//---------------------------------------------------------------------------------------
14func runFDFTest() -> Int {
15 return autoreleasepool{
16 var ret: Int = 0
17
18
19 // Example 1)
20 // Iterate over all form fields in the document. Display all field names
21 do {
22 try PTPDFNet.catchException {
23 let doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "form1", ofType: "pdf"))
24 doc.initSecurityHandler()
25
26 let itr: PTFieldIterator = doc.getFieldIterator()
27 while (itr.hasNext()) {
28 print("Field name: \(itr.current().getName()!)")
29 print("Field partial name: \(itr.current().getPartialName()!)")
30
31 print("Field type: ")
32 let type: PTFieldType = itr.current().getType()
33 switch type {
34 case e_ptbutton:
35 print("Button")
36 case e_pttext:
37 print("Text")
38 case e_ptchoice:
39 print("Choice")
40 case e_ptsignature:
41 print("Signature")
42 default:
43 break
44 }
45
46 print("------------------------------")
47 itr.next()
48 }
49
50 print("Done")
51 }
52 } catch let e as NSError {
53 print("\(e)")
54 ret = 1
55 }
56
57 // Example 2)
58 // Import XFDF into FDF, then merge data from FDF into PDF
59 do {
60 try PTPDFNet.catchException {
61 // XFDF to FDF
62 // form fields
63 print("Import form field data from XFDF to FDF.")
64
65 let fdf_doc1: PTFDFDoc = PTFDFDoc.create(fromXFDF: Bundle.main.path(forResource: "form1_data", ofType: "xfdf"))
66 fdf_doc1.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_data.fdf").path)
67
68 // annotations
69 print("Import annotations from XFDF to FDF.")
70
71 let fdf_doc2: PTFDFDoc = PTFDFDoc.create(fromXFDF: Bundle.main.path(forResource: "form1_annots", ofType: "xfdf"))
72 fdf_doc2.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_annots.fdf").path)
73
74 // FDF to PDF
75 // form fields
76 print("Merge form field data from FDF.")
77
78 let doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "form1", ofType: "pdf"))
79 doc.initSecurityHandler()
80 doc.fdfMerge(fdf_doc1)
81
82 // To use PDFNet form field appearance generation instead of relying on
83 // Acrobat, uncomment the following two lines:
84 //doc.refreshFieldAppearances()
85 //doc.getAcroForm().putBool("NeedAppearances", value: false)
86
87 doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled.pdf").path, flags: e_ptlinearized.rawValue)
88
89 print("Merge annotations from FDF.")
90
91 doc.fdfMerge(fdf_doc2)
92 doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_with_annots.pdf").path, flags: e_ptlinearized.rawValue)
93 print("Done.")
94 }
95 } catch let e as NSError {
96 print("\(e)")
97 ret = 1
98 }
99
100 // Example 3) Extract data from PDF to FDF, then export FDF as XFDF
101 do {
102 try PTPDFNet.catchException {
103 // PDF to FDF
104 let in_doc: PTPDFDoc = PTPDFDoc(filepath: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_with_annots.pdf").path)
105 in_doc.initSecurityHandler()
106
107 // form fields only
108 print("Extract form fields data to FDF.")
109
110 let doc_fields: PTFDFDoc = in_doc.fdfExtract(e_ptforms_only)
111 doc_fields.setPDFFileName("../form1_filled_with_annots.pdf")
112 doc_fields.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_data.fdf").path)
113
114 // annotations only
115 print("Extract annotations to FDF.")
116
117 let doc_annots: PTFDFDoc = in_doc.fdfExtract(e_ptannots_only)
118 doc_annots.setPDFFileName("../form1_filled_with_annots.pdf")
119 doc_annots.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_annot.fdf").path)
120
121 // both form fields and annotations
122 print("Extract both form fields and annotations to FDF.")
123
124 let doc_both: PTFDFDoc = in_doc.fdfExtract(e_ptboth)
125 doc_both.setPDFFileName("../form1_filled_with_annots.pdf")
126 doc_both.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_both.fdf").path)
127
128 // FDF to XFDF
129 // form fields
130 print("Export form field data from FDF to XFDF.")
131
132 doc_fields.save(asXFDF: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_data.xfdf").path)
133
134 // annotations
135 print("Export annotations from FDF to XFDF.")
136
137 doc_annots.save(asXFDF: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_annot.xfdf").path)
138
139 // both form fields and annotations
140 print("Export both form fields and annotations from FDF to XFDF.")
141
142 doc_both.save(asXFDF: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_both.xfdf").path)
143
144 print("Done.")
145 }
146 } catch let e as NSError {
147 print("\(e)")
148 ret = 1
149 }
150
151 // Example 4) Merge/Extract XFDF into/from PDF
152 do {
153 try PTPDFNet.catchException {
154 // Merge XFDF from string
155 let in_doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "numbered", ofType: "pdf"))
156 in_doc.initSecurityHandler()
157
158 print("Merge XFDF string into PDF.")
159 let str = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><xfdf xmlns=\"http://ns.adobe.com/xfdf\" xml:space=\"preserve\"><square subject=\"Rectangle\" page=\"0\" name=\"cf4d2e58-e9c5-2a58-5b4d-9b4b1a330e45\" title=\"user\" creationdate=\"D:20120827112326-07'00'\" date=\"D:20120827112326-07'00'\" rect=\"227.7814207650273,597.6174863387978,437.07103825136608,705.0491803278688\" color=\"#000000\" interior-color=\"#FFFF00\" flags=\"print\" width=\"1\"><popup flags=\"print,nozoom,norotate\" open=\"no\" page=\"0\" rect=\"0,792,0,792\" /></square></xfdf>"
160
161 let fdoc = PTFDFDoc.create(fromXFDF: str)
162 in_doc.fdfMerge(fdoc)
163 in_doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("numbered_modified.pdf").path, flags: e_ptlinearized.rawValue)
164
165 print("Merge complete.")
166
167 // Extract XFDF as string
168 print("Extract XFDF as a string.")
169 let fdoc_new: PTFDFDoc = in_doc.fdfExtract(e_ptboth)
170 let XFDF_str: String = fdoc_new.saveAsXFDFToString()
171 print("Extracted XFDF: ")
172 print("\(XFDF_str)")
173 print("Extract complete.")
174 }
175 } catch let e as NSError {
176 print("\(e)")
177 ret = 1
178 }
179
180 // Example 5) Read FDF files directly
181 do {
182 try PTPDFNet.catchException {
183 let doc: PTFDFDoc = PTFDFDoc(filepath: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("form1_filled_data.fdf").path)
184
185 let itr: PTFDFFieldIterator = doc.getFieldIterator()
186 while itr.hasNext() {
187 print("Field name: \(itr.current().getName()!)")
188 print("Field partial name: \(itr.current().getPartialName()!)")
189
190 print("------------------------------")
191 itr.next()
192 }
193
194 print("Done.")
195 }
196 } catch let e as NSError {
197 print("\(e)")
198 ret = 1
199 }
200
201 // Example 6) Direct generation of FDF.
202 do {
203 try PTPDFNet.catchException {
204 let doc: PTFDFDoc = PTFDFDoc()
205 // Create new fields (i.e. key/value pairs).
206 doc.fieldCreate(with: "Company", type: e_pttext, field_value: "PDFTron Systems")
207 doc.fieldCreate(with: "First Name", type: e_pttext, field_value: "John")
208 doc.fieldCreate(with: "Last Name", type: e_pttext, field_value: "Doe")
209 // ...
210
211 //doc.setPDFFileName("mydoc.pdf")
212
213 doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("sample_output.fdf").path)
214 print("Done.")
215 }
216 } catch let e as NSError {
217 print("\(e)")
218 ret = 1
219 }
220
221 return ret
222 }
223}
Did you find this helpful?
Trial setup questions?
Ask experts on DiscordNeed other help?
Contact SupportPricing or product questions?
Contact Sales