1

I am trying to automatize the modification of an pdf template according to some data computing (using Java)

I have no experience with pdf modification and I am being trying to use itext7 to do this.

I have been reading how to add text to a pdf and even here I saw how to field Acrosfield if they exist using a "key"

Nevertheless, I didn't made the pdf template I am using (which is modifiable) so I don't know if the fields with you can manually fill are made with Acrosfields or another tecnology and I don'w know what are the keys or each field If they have one...

I saw this question; where it is says how to get all the fields and their values but when I try the code that appear in the only answer I get;

main.java:[40,0] error: illegal start of type
main.java:[40,19] error: ')' expected
main.java:[40,30] error: <identifier> expected
3 errors 

In this part:

for (String fldName : fldNames) {
    System.out.println( fldName + ": " + fields.getField( fldName ) );
}

After try a bit, I have been finding more information but I can't find a way to get these "keys" if it's possible...

------- EDIT -------

I've made this code in order to make a copy of my pdf-template which have the name of the Acrosfield's key in each field:

package novgenrs;


import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Set;
public class MakePDF {

public static void MakePDF(String[] args) throws IOException, DocumentException{


PdfReader reader = new PdfReader("template.pdf");

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("result.pdf"));

//AcroFields form = stamper.getAcroFields();

AcroFields fields = reader.getAcroFields();

AcroFields wrt = stamper.getAcroFields(); 

Set<String> fldNames = fields.getFields().keySet();

for (String fldName : fldNames) {
  wrt.setField(fldName, fldName) ; 
}

stamper.close();
reader.close(); 

}


}

NOTE: this only work with itext5. For some reason when I tried to do this with itext7 I couldn't made it work so I tried to do it with itext5 and it worked!

Community
  • 1
  • 1
grg121
  • 35
  • 1
  • 5
  • That loop looks OK if `fields` is of type `AcroFields` and fldNames is a string collection. You may need to post your code before that loop – Matthew Diana Sep 24 '16 at 16:00
  • :/ I've found why that error... I had wrote the code as part of the principal class and not as a method so the compiler couldn't understand the for loop. I used to code on C++ and I didn't know that !!! – grg121 Sep 24 '16 at 17:30

1 Answers1

3

If you want a full answer to your question, you will have to provide the PDF so that we can inspect it, but these are already some answers that will get you in the right direction.

When you refer to How to fill out a pdf file programmatically? (AcroForm technology), you refer to the iText 7 version of How to fill out a pdf file programmatically? (AcroForm technology) which is the answer to the same question, but for developers who use iText 5. As you can see, there's a big difference between iText 5 and iText 7.

However, when you refer to How do I get all the fields and value from a PDF file using iText? you get an answer that is to be used with iText 5 only. If you are using iText 7, that code won't work because it's iText 5 code.

The code you need can be found here: How to get specific types from AcroFields? Like PushButtonField, RadioCheckField, etc

PdfReader reader = new PdfReader(src);
PdfDocument pdfDoc = new PdfDocument(reader);
// Get the fields from the reader (read-only!!!)
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
// Loop over the fields and get info about them
Set<String> fields = form.getFormFields().keySet();
for (String key : fields) {
    writer.print(key + ": ");
    PdfName type = form.getField(key).getFormType();
    if (0 == PdfName.Btn.compareTo(type)) {
        if(((PdfButtonFormField)form.getField(key)).isPushButton()){
            writer.println("Pushbutton");
        } else {
            if(((PdfButtonFormField)form.getField(key)).isRadio()){
                writer.println("Radiobutton");                   
            }else {
                writer.println("Checkbox");
            }
        }
    } else if (0 == PdfName.Ch.compareTo(type)) {
        writer.println("Choicebox");
    } else if (0 == PdfName.Sig.compareTo(type)) {
        writer.println("Signature");
    } else if (0 == PdfName.Tx.compareTo(type)) {
        writer.println("Text");
    }else {
        writer.println("?");
    }
}

This code will loop over all the fields, and write the key to the System.out, as well as the type of field that corresponds with that key. You can also use RUPS to inspect your PDF.

You mention:

main.java:[40,0] error: illegal start of type
main.java:[40,19] error: ')' expected
main.java:[40,30] error: <identifier> expected

It isn't clear to me if this is a compiler error or a run-time error.

  • If it's a compiler error, you are simply missing a ) somewhere, in which case your problem is totally unrelated to iText (which is what I suspect: you just have a very simple programming error).
  • If it's a run-time error, there is something wrong with your PDF. In PDF, a string is delimited by parentheses. Maybe a bracket is missing somewhere in your PDF (but I doubt that: you'd get a different type of error).

In short: try a good IDE, and that IDE will tell give you an indication of where a parenthesis is missing. If you don't find that location immediately, clean up your code by adding indentation and spaces. That should make it clear where you forget a ).

Graham
  • 7,431
  • 18
  • 59
  • 84
Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • I used to code without IDE on C++ but, as this project have parts on Java and I will learn it on this quarter of the code I decided to do it on Java so I'm using Netbeans.. The error was that I had wrote the code as part of the main class and not as a method so the compiler couldn't understand what I meant with the for loop!! – grg121 Sep 24 '16 at 17:33
  • Ok, I have try your code and I get no output although the template is writable.. maybe it don't use Acrosfield... I am going to try RUPS to inspect the template. Also I will edit my first post and add the template. – grg121 Sep 24 '16 at 17:36
  • If the form has form fields (that you see in Adobe Reader), but no AcroForm fields, then the form could be an XFA form. In that case, your PDF isn't a *traditional* PDF, but the PDF is merely a wrapper for XML in the XML Forms Architecture (XFA) format. – Bruno Lowagie Sep 25 '16 at 01:24