use strict; use warnings; use feature 'say'; use CAM::PDF; sub _n { CAM::PDF::Node-> new( @_ )} sub _p { CAM::PDF-> parseAny( \$_[ 0 ])} my $doc = CAM::PDF-> new( 'test.pdf' ) or die; # let's create a ListBox dictionary; its reference to be # added to 2 arrays my $forms_node = $doc-> getRootDict-> { AcroForm } or die; my $forms_dict = $doc-> getValue( $forms_node ); my $fields_ary = $doc-> getValue( $forms_dict-> { Fields }); my $page_annots_node = $doc-> getPage( 1 )-> { Annots } or die; my $page_annots_ary = $doc-> getValue( $page_annots_node ); # it's funny how we code, below, half in Perl, half in kind of # DSL, i.e. write PDF syntax directly and make CAM::PDF to # parse it into whatever it thinks appropriate. Said "PDF # syntax" is not too difficult and actually quite fun. my $ref = _n( reference => $doc-> appendObject( undef, _n( # "1", below, is for "hidden"; # because of that, Rect is any, and Appearance is not even # dealt with here. # "Ch" is "choice field", "list box" object => _p( q(<< /Type /Annot /Subtype /Widget /F /1 /Rect [ 0 0 1 1 ] /FT /Ch /Opt [ (My sneaky item #1) (Item I'm very proud of) (Hidden item nobody will find) ] /T (MyTopSecretListBox) >>)) ), 0 )); push @$fields_ary, $ref; push @$page_annots_ary, $ref; $doc-> cleanoutput( 'new.pdf' ); # let's re-open the modified PDF and test it # by using buit-in CAM::PDF facilities to assign value # to the added form field $doc = CAM::PDF-> new( 'new.pdf' ); say for $doc-> getFormFieldList; $doc-> fillFormFields( MyTopSecretListBox => << 'END_OF_IT' Hidden item nobody will find But we are not limited to our silly list, if value is set programmatically END_OF_IT ); $doc-> cleanoutput( 'new2.pdf' ); #### $ perl acroform.pl Text Box 1 MyTopSecretListBox $ pdftk test.pdf dump_data_fields --- FieldType: Text FieldName: Text Box 1 FieldFlags: 0 FieldValue: FieldJustification: Left $ pdftk new.pdf dump_data_fields --- FieldType: Text FieldName: Text Box 1 FieldFlags: 0 FieldValue: FieldJustification: Left --- FieldType: Choice FieldName: MyTopSecretListBox FieldFlags: 0 FieldJustification: Left FieldStateOption: Hidden item nobody will find FieldStateOption: Item I'm very proud of FieldStateOption: My sneaky item #1 $ pdftk new2.pdf dump_data_fields --- FieldType: Text FieldName: Text Box 1 FieldFlags: 0 FieldValue: FieldJustification: Left --- FieldType: Choice FieldName: MyTopSecretListBox FieldFlags: 0 FieldValue: Hidden item nobody will find But we are not limited to our silly list, if value is set programmatically#10; FieldJustification: Left FieldStateOption: Hidden item nobody will find FieldStateOption: Item I'm very proud of FieldStateOption: My sneaky item #1