How to rename a PDF form field when the field name

2019-07-30 15:58发布

问题:

I use iTextSharp to rename PDF form field. The old field names and the new replacement names are entered in a text box (comma separated). My code then loops through each line, grabs the old field name, looks for the field in the PDF and renames it to the new field. Finally, a new PDF is created from the old PDF, and all of the fields in the new PDF will have the new names.

My problem is that I can't seem to rename the PDF fields which contain a period in the field name (e.g. First.Name). Is there a way to rename such PDF fields using iTextSharp? I looked everywhere and couldn't find a clear answers or code examples.

Here is the code I'm using so far:

//source PDF file
string src = PDFFile.Text;

//destination PDF file
string dest = @"Renamed_" + DateTime.Now.ToString("yyyymmddhhss") + ".pdf";

//open source PDF
PdfReader reader = new PdfReader(src);

using (FileStream fs = new FileStream(dest, FileMode.Create))
{
PdfStamper stamper = new PdfStamper(reader, fs);
AcroFields fields = stamper.AcroFields;

//read each line from the txtOldAndNewFieldNames text box
//each line contains <old field name>,<new field name>
//the two values are then put in an array
//finally, the PDF field with <old field name> is renamed to <new field name>

foreach (string line in txtOldAndNewFieldNames.Lines)
{

    string[] namePair = new string[2];
    namePair = line.Split(',');

    try
    {
        fields.RenameField(namePair[0], namePair[1]);
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}
stamper.Close();
reader.Close();
}

回答1:

This is described in the iText(Sharp) source code:

/**
 * Renames a field. Only the last part of the name can be renamed. For example,
 * if the original field is "ab.cd.ef" only the "ef" part can be renamed.
 * @param oldName the old field name
 * @param newName the new field name
 * @return <CODE>true</CODE> if the renaming was successful, <CODE>false</CODE>
 * otherwise
 */    
virtual public bool RenameField(String oldName, String newName)

Thus, using this method you can rename First.Name to First.NameOrEmpty or something like that but not to EmptyOrFirst.Name.

The background is that form fields in PDFs are not merely arranged as a list of objects with the full name but instead as a tree in which the full name of a node is the concatenation of the partial names of its ancestors and the node itself separated by dots.

Thus, changing anything but the part after the last dot (or changing that part but introducing a new dot) actually means moving the field in the tree to a different parent node which might or might not have to be created in the process.

The RenameField method, on the other hand, only supports changing the local name of the final field tree element itself.

And this is sensible. Form fields can inherit a number of properties from their parent. So if you rename a field, do you want the result field to inherit from the new parent instead? Or shall all inherited properties be explicitly added to the node? Or only those differing from the respective new inherited information? Or do you have yet another idea?