java - How to rename only the first found duplicate acrofield in pdf? -


on pdf have duplicate field named text1. want rename first found acrofield name text1 foobar. other field name text1 should unchanged new form contains fields text1 , foobar.

i using itext library , there rename function method rename fields name text1 foobar.

if wants test pdf, here link.

public class renamefield {     public static final string src = "c:\\test_duplicate_field2.pdf";     public static final string dest = "c:\\test_duplicate_field_mod.pdf";      public static void main(string[] args)         throws documentexception, ioexception     {         file file = new file(dest);         file.getparentfile().mkdirs();         new renamefield().manipulatepdf(src, dest);     }      public void manipulatepdf(string src, string dest)         throws documentexception, ioexception     {         pdfreader reader = new pdfreader(src);         pdfstamper stamper = new pdfstamper(reader, new fileoutputstream(dest));         acrofields form = stamper.getacrofields();         form.renamefield("text1", "foobar");         stamper.close();         reader.close();         reader = new pdfreader(dest);         form = reader.getacrofields();         map<string, acrofields.item> fields = form.getfields();         (string name : fields.keyset()) {             system.out.println(name);         }     } } 

another approach iterate through acrofield.items. if there item has more 1 values dictionaries (in case field exists more 1 time) change done.

for (map.entry<string, acrofields.item> entry: fieldmap.entryset()) {     // extract values field     string fieldkey = entry.getkey();      acrofields.item item = entry.getvalue();     pdfdictionary dict;      int numberofduplicates = item.values.size();      if (numberofduplicates > 1) {         (int = 0; < numberofduplicates; i++) {             if (i == 0) {                 log.info("first field wont changed");             } else {                 log.info("renaming field " + fieldkey + " round " + );                 item.getmerged(i).put(pdfname.t, new pdfstring(fieldkey + "_" + ));                 item.getvalue(i).put(pdfname.t, new pdfstring(fieldkey + "_" + i));                                      form.regeneratefield(fieldkey);              }         }     } } 

but leads same result above approach renamefield function itext, both field names changed. during debugging see 2 value dictionarys of item have same object-id when change value dictionary[0] value change in dictionary[1] well

enter image description here

on pdf have duplicate field named text1

as bruno explained in comment wrong. pdf has single field named "text1":

34 0 obj <</da(/helv 12 tf 0 g)/ft/tx/kids[28 0 r 29 0 r]/t(text1)>> endobj 

this single field has 2 kids

28 0 obj <</f 4/mk<<>>/p 3 0 r/parent 34 0 r/rect[70.305 698.209 220.305 720.209]/subtype/widget/type/annot>> endobj 29 0 obj <</da(/helv 12 tf 0 g)/f 4/mk<<>>/p 3 0 r/parent 34 0 r/rect[240.02 697.453 390.02 719.453]/subtype/widget/type/annot>> endobj  

these kids mere widget annotations, they not fields in own right.

thus, request

sample code how rename 1 of 2 widgets annotations instead of field

does not make sense: there not 1 of 2 rename fields named , there 1 field.

what have create new field named "foobar" (copying attributes of original field except kids , t) , move 1 of text1 kids foobar.

example code focusing on use case:

pdfreader reader = new pdfreader(resource);  pdfdictionary form = reader.getcatalog().getasdict(pdfname.acroform); pdfarray fields = form.getasarray(pdfname.fields); (pdfobject object: fields) {     pdfdictionary field = (pdfdictionary) pdfreader.getpdfobject(object);     if ("text1".equals(field.getasstring(pdfname.t).tostring()))     {         pdfdictionary newfield = new pdfdictionary();         prindirectreference newfieldref = reader.addpdfobject(newfield);         fields.add(newfieldref);         newfield.putall(field);         newfield.put(pdfname.t, new pdfstring("foobar"));         pdfarray newkids = new pdfarray();         newfield.put(pdfname.kids, newkids);         pdfarray kids = field.getasarray(pdfname.kids);         pdfobject widget = kids.remove(0);         newkids.add(widget);         pdfdictionary widgetdict = (pdfdictionary) pdfreader.getpdfobject(widget);         widgetdict.put(pdfname.parent, newfieldref);         break;     } }  pdfstamper stamper = new pdfstamper(reader, result); stamper.close(); 

(samefieldtwice.java method testwidgettofield)

obviously generically usable solution there still.


Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -