2015-09-22 2 views
1

Je travaille sur du code qui concatène des fichiers PDF en utilisant iTextSharp. J'ai un problème avec a particular PDF qui contient quelques champs en lecture seule et un champ qui est modifiable (je crois qu'ils sont AcroFields). Dans le fichier de sortie, tous les champs sont modifiables.iTextSharp PdfCopy rend les champs en lecture seule modifiables

Voici le code que j'utilise (je l'ai simplifié pour lire un seul PDF):

public static void Concat(string outputFilePath, string inputFilePath) 
{ 
    using (var document = new Document()) 
    { 
     using (var fileStream = new FileStream(outputFilePath, FileMode.Create, FileAccess.ReadWrite)) 
     using (var copier = new PdfCopy(document, fileStream)) 
     { 
      copier.SetMergeFields(); 
      document.Open(); 

      var reader = new PdfReader(inputFilePath); 
      copier.AddDocument(reader); 
      copier.AddJavaScript(reader.JavaScript); 

      copier.Close(); 
     } 
     document.Close(); 
    } 
} 

Toutes les idées sur la façon de préserver les attributs des champs?

Répondre

3

Il semble que iText et Adobe Reader interprètent différemment la structure du champ de formulaire. Par exemple. regardez ce champ parent avec un enfant:

PageDataCollection1[0].txtCity

(Object 24 est référencé à partir du AcroForm dictionnaire Les champs tableau objet 130 est référencé à partir du page dictionnaire Annots de tableau..)

Nous avons donc deux objets de champ nommés PageDataCollection1[0].txtCity, les objets 24 et 130, l'annotation du widget étant fusionnée dans ce dernier.

iText considère l'objet champ terminal (objet 130) soit complètement chargé, en utilisant son Ff valeur 0 qui, entre autres choses des moyens pas en lecture seule.

Adobe Reader, d'autre part, estime l'objet champ terminal (objet 130) seulement d'être partiellement en charge, en utilisant la valeur DA mais pas son Ff valeur. Au lieu de cela, le parent Ff valeur 1 est utilisé ce qui signifie entre autres lecture seule.

Lors de la copie des pages de document, les hiérarchies sont aplaties pour rendre visibles les différentes interprétations.


Ad hoc Je dirais que le comportement d'iText est correct ici.

Le comportement d'Adobe Reader peut être justifié par cette section de la spécification ISO 32000-1:

Il est possible pour les différents dictionnaires sur le terrain pour avoir le même nom de domaine complet si elles sont les descendants d'un ancêtre commun avec ce nom et n'ont pas de noms de champs partiels (T entrées). De tels dictionnaires de champ sont des représentations différentes du même champ sous-jacent; ils ne devraient différer que par les propriétés qui spécifient leur apparence visuelle. En particulier, les dictionnaires de champ avec le même nom de champ complet doivent avoir le même type de champ (FT), la valeur (V) et la valeur par défaut (DV).

(section 12.7.3.2 les noms de champs)

Peut-être que Adobe Reader essaie de faire respecter que les différentes représentations du même domaine ne diffèrent que dans les propriétés qui spécifient leur aspect visuel, en ignorant d'autres propriétés dans les champs descendants sans noms de champs partiels.

Comme il n'y a aucune représentation différente du champ, cependant, cette mesure n'est pas nécessaire ici.


Il y a une autre interprétation de la structure de l'objet ici, @rhens proposé

Il n'y a pas 2 champs avec le même nom: objet 24 est le dictionnaire de champ, objet 130 est le widget annotation.

IMO cette interprétation ne correspond pas à la spécification PDF, même si elle explique le comportement d'Adobe Reader.

Alors en effet le enfants tableau d'un champ de formulaire peut contenir soit des champs enfants ou des widgets, l'objet 130 à mon avis, doit être considéré comme un domaine (qui a son propre widget de fusionné en lui-même) au lieu d'un Pour vérifier si un objet de dictionnaire enfant est un champ enfant ou simplement un widget, il ne suffit pas de trouver des entrées spécifiques au widget dans l'enfant: ces entrées peuvent également être dans un champ enfant qui a son seul widget fusionné en lui-même. Ainsi, il faut plutôt vérifier les entrées spécifiques au champ dans l'enfant.

En l'espèce l'enfant objet 130 ne ont des entrées spécifiques sur le terrain (avant tout le type de champ FT mais aussi les drapeaux sur le terrain Ff) et, par conséquent, devrait être considéré comme un enfant champ .


Tout a été dit, il est en effet possible que Adobe ne considère que l'objet d'un simple widget de (qui, comme mentionné ci-dessus, expliquerait le comportement). Cette interprétation ne serait pas inspirée par la spécification, cependant, comme expliqué ci-dessus. Mais il pourrait être inspiré par une quantité non négligeable de documents de la nature qui ont par erreur des entrées spécifiques au champ dans leurs widgets simples et nécessitent que cette interprétation soit affichée comme prévu.

+0

Merci pour l'analyse détaillée! Est-il possible de dire à iText de préférer la valeur du parent pour/Ff? Ou peut-être existe-t-il un moyen d'inspecter cette valeur et de la définir manuellement champ par champ. Ou devrais-je plutôt essayer une autre bibliothèque PDF? – bgh

+0

* Est-il possible de dire à iText de préférer la valeur du parent pour/Ff? * - Autant que je sache: Non. - * Ou peut-être existe-t-il un moyen d'inspecter cette valeur manuellement par champ. Comme iText vous permet de manipuler des fichiers PDF à un niveau bas, ce n'est pas un problème. - * Ou devrais-je plutôt essayer une autre bibliothèque PDF? * - Après tout cela dépend de vous. – mkl

+0

@mkl Vous êtes sur la bonne voie avec votre analyse, mais je pense qu'iText est mauvais ici. Il n'y a pas 2 champs avec le même nom: l'objet 24 est le dictionnaire de champ, l'objet 130 est l'annotation de widget.La spécification PDF ne définit pas l'entrée Ff pour les annotations. C'est seulement défini pour les dictionnaires de domaine. Il est donc logique qu'Adobe Reader utilise la valeur du parent. Je vais modifier votre réponse pour refléter cela. – rhens