droidnoob
droidnoob

Reputation: 335

Using iText to add user input to PDF form

Hey so I am trying to use iText to get Strings added by the user and then add them to a fillable PDF which i imported into the app. However, my app does not recognize the pre-described strings I am adding. I will just add some snippets of the code so anyone can tell me whats wrong. Sorry if it may sound like a weak question, but this is my first time using iText.

This is my MainActivity.java

public class Main extends Activity {
EditText editText,editText2,editText3,editText4,editText5,editText6,editText7,editText8,editText9,editText10;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);
    final Customer newCustomer=new Customer();
    try {
        reader=new PdfReader(getResources().openRawResource(R.raw.pgform));
    } catch (IOException e) {
        e.printStackTrace();
    }



    findViewsById();

    savebutton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Customer newCustomer=new Customer();
            //newCustomer.one(editText.getText().toString());
            //newCustomer.two(editText2.getText().toString());
            OutputStream output=null;
            try {
                reader=new PdfReader(getResources().openRawResource(R.raw.pvgform));
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                PdfStamper stamper=new PdfStamper(reader,output);
                AcroFields acroFields=stamper.getAcroFields();
                acroFields.setField("fullnameorinitials",one);
                acroFields.setField("agedob",two);
            } catch (DocumentException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    });



}
private void findViewsById(){ 
    editText=(EditText)findViewById(R.id.editText);
    editText2=(EditText)findViewById(R.id.editText2);
    editText3=(EditText)findViewById(R.id.editText3);
    editText4=(EditText)findViewById(R.id.editText4);
    editText5=(EditText)findViewById(R.id.editText5);
    editText6=(EditText)findViewById(R.id.editText6);
    editText7=(EditText)findViewById(R.id.editText7);
    editText8=(EditText)findViewById(R.id.editText8);
    editText9=(EditText)findViewById(R.id.editText9);
    editText10=(EditText)findViewById(R.id.editText10);
}


public class Customer{
    String one=editText.getText().toString();
    String two=editText2.getText().toString();
    String three=editText3.getText().toString();
    String four=editText4.getText().toString();
    String five=editText5.getText().toString();
    String six=editText6.getText().toString();
    String seven=editText7.getText().toString();
    String eight=editText8.getText().toString();
    String nine=editText9.getText().toString();
    String ten=editText10.getText().toString();

}


}

The line of code that seems to have issues are when I try to set the fields in the PDF with each editText in my app.

acroFields.setField("fullnameorinitials",one);

The error is on the string value (one). Please any kind of reproductive help is appreciated!

Upvotes: 0

Views: 882

Answers (1)

mkl
mkl

Reputation: 95898

There are two issues in the code, one concerning variable scopes preventing compilation and one concerning iText API use preventing proper result PDFs.

Variable scopes

Variables must be declared and visible in the scope in which they are used. This was not the case for one and two in the onClick implementation in the anonymous inner class based on View.OnClickListener constructed in Main.onCreate:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    [...]
    savebutton.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            [...]
            try
            {
                PdfStamper stamper=new PdfStamper(reader,output);
                AcroFields acroFields=stamper.getAcroFields();
                acroFields.setField("fullnameorinitials",one);
                acroFields.setField("agedob",two);
            }
            [...]
        }
    });
}

This code can use all static Main variables, all non-static member variables of the Main instance at hand, all final variables declared in onCreate before the instantiation of the OnClickListener, all static variables of the anonymous class and all non-static ones of the instance at hands, and all variables in onClick before the use of one and two.

The only variables one and two declaration is in the other inner class, Customer.

Assuming the values those Customer class members would have been initialized with, to be the desired data in onClick, the compilation failure can be fixed like this:

            [...]
            try
            {
                PdfStamper stamper=new PdfStamper(reader,output);
                AcroFields acroFields=stamper.getAcroFields();
                acroFields.setField("fullnameorinitials", editText.getText().toString());
                acroFields.setField("agedob", editText2.getText().toString());
            }
            [...]

(You can of course slip in a Customer bean for separation of concerns, but in that case please use sensible, member names independent from view fields, e.g. fullName instead of one.)

Now the code can be compiled but it still does not necessarily produce the correct result. Thus:

iText API use

In the code above, PdfStamper is instantiated, then some fields are set with it, then nothing... The iText API contract, on the other hand, expects PdfStamper instances to be closed after use: During close the PDF output is finalized.

Thus:

            [...]
            try
            {
                PdfStamper stamper=new PdfStamper(reader,output);
                AcroFields acroFields=stamper.getAcroFields();
                acroFields.setField("fullnameorinitials", editText.getText().toString());
                acroFields.setField("agedob", editText2.getText().toString());
                stamper.close();
            }
            [...]

Furthermore iText PdfStamper expects some target to write to, In the original code the target is initialized from the second parameter of the PdfStamper constructor used:

                PdfStamper stamper=new PdfStamper(reader,output);

Unfortunately, output has been initialized with null which iText will not like. Thus, please also supply a proper target OutputStream.

Upvotes: 2

Related Questions