2010-11-26 36 views
1

J'ai un document PDF qui contient plusieurs centaines de champs. Tous les noms de champs ont des périodes en eux, comme « page1.line1.something »Problème avec itextsharp

Je veux supprimer ces périodes et les remplacer par soit un trait de soulignement ou (mieux) rien du tout

Il semble un bogue dans les bibliothèques iTextSharp où la méthode renamefield ne fonctionne pas si le terrain a une période, de sorte que le suivant ne fonctionne pas (retourne toujours faux)

Dim formfields As AcroFields = stamper.AcroFields 
Dim renametest As Boolean 
renametest = formfields.RenameField("page1.line1.something", "page1_line1_something") 

Si le champ ne dispose pas d'une période en elle, ça fonctionne bien.

Est-ce que quelqu'un est tombé sur ceci et y at-il une solution de contournement?

Répondre

1

Est-ce un formulaire AcroForm ou un formulaire LiveCycle Designer (xfa)?

S'il s'agit de XFA (ce qui est probablement donné les noms des champs), iText ne peut pas vous aider. Il ne peut obtenir/définir des valeurs de champ que lorsque vous travaillez avec XFA.

D'accord, un AcroForm. Plutôt que de suivre la route utilisée dans votre source, je vous suggère de manipuler directement les dictionnaires de champs existants et la liste de champs acroForm.

Je suis originaire de Java en matière de iText, de sorte que vous aurez à faire une traduction, mais va ici:

A) Supprimer le tableau de champ du AcroForm. Laissez l'ordre de calcul seul s'il est présent (/ CO). Je pense. B) Joindre tous les champs de «niveau supérieur» à une nouvelle matrice FIELDS.

PdfArray newFldArray = new PdfArray(); 
acroDict.put(newFldArray, PdfName.FIELDS); 

// you could wipe this between pages to speed things up a bit 
Set<PdfIndirectReference> radioFieldsAdded = new HashSet<PdfIndirectReference>(); 

int numPages = reader.getNumberOfPages(); 
for (int curPg = 1; curPg <= numPages; ++curPg) { 
    PdfDictionary curPageDict = reader.getPageN(curPg); 
    PdfArray annotArray = curPageDict.getAsArray(PdfName.ANNOTS); 
    if (annotArray == null) 
    continue; 

    for (int annotIdx = 0; annotIdx < annotArray.size(); ++annotIdx) { 
    PdfIndirectReference fieldReference = (PdfIndirectReference) annotArray.getAsIndirect(annotIdx); 
    PdfDictionary field = (PdfDictionary)PdfReader.getObject(fieldReference); 

    // if it's a radio button 
    if ((PdfFormField.FF_RADIO & field.getAsNumber(PdfName.FF).intValue()) != 0) { 
     fieldReference = field.get(pdfName.PARENT); 
     field = field.getAsDict(PdfName.PARENT); // looks up indirect reference for you. 

     // only add each radio field once. 
     if (radioFieldsAdded.contains(fieldReference)) { 
     continue; 
     } else { 
     radioFieldsAdded.add(fieldReference); 
     } 
    } 

    field.remove(PdfName.PARENT); 

    // you'll need to assemble the original field name manually and replace the bits 
    // you don't like. Parent.T + '.' child.T + '.' + ... 
    String newFieldName = SomeFunction(field); 
    field.put(PdfName.T, new PdfString(newFieldName)); 

    // add the reference, not the dictionary 
    newFldArray.add(fieldReference) 
    } 
} 

C) Nettoyer

reader.removeUnusedObjects(); 

Inconvénient:
plus de travail.

Avantages:
Conserve tous les types de champs, attributs, apparences et ne modifie pas le fichier dans son ensemble. Moins CPU & mémoire. Votre code actuel ignore le script de champ, tous les drapeaux de champ (en lecture seule, cachés, requis, texte multiligne, etc.), listes/combos, boutons radio, et un bon nombre d'autres bric-à-brac.

+0

Ce n'est pas un formulaire XFA –

+0

merci pour l'aide, désolé pour réponse tardive –

1

Si vous utilisez des points dans votre nom de zone, seule la dernière partie peut être renommée, par ex. dans page1.line1.something seul "quelque chose" peut être renommé. En effet, le « page1 » et « ligne1 » sont traités par Adobe en tant que parents à « quelque chose » champ

je devais supprimer cette hiérarchie et le remplacer par une structure aplatie

Je l'ai fait par

  1. créer un objet pdfdictionary pour chaque champ
  2. lire les annotations que je avais besoin pour chaque champ dans un tableau
  3. suppression de la hiérarchie sur le terrain dans mon (pdfstamper) Document
  4. la création d'un nouvel ensemble de champs de données de mon tableau

J'ai créé quelques sample code pour cela si vous voulez voir comment je l'ai fait.