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
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
Post a Comment