2017-09-01 5 views
0

Je dois créer un document compatible PDF/UA dans iText7. L'exigence la plus importante est le marquage de tout le contenu. Lorsque le marquage est activé (en appelant la méthode PdfDocument.SetTagged()), la plupart des éléments ajoutés au document obtiennent des étiquettes correctes.Comment étiqueter des cellules d'en-tête de tableau comme TH au lieu de TD dans iText7?

Le problème est lié au marquage des cellules d'en-tête de table. Selon la norme ISO 32000-1: 2008, les cellules d'en-tête de tableau doivent être marquées TH et les cellules de données de table doivent être marquées comme TD (14.8.4.2.4, éléments de table, tableau 337). IText permet de distinguer entre les cellules d'en-tête et les cellules normales en utilisant les méthodes Table.AddHeaderCell() et Table.AddCell(). Ce mécanisme crée correctement des balises THead et TBody pour les groupes de lignes. Malheureusement, les cellules elles-mêmes sont toujours marquées comme TD.

Voici un exemple de code pour générer une table:

//var pdfDoc = new PdfDocument(...) 

pdfDoc.SetTagged(); 

var doc = new Document(pdfDoc); 

var table = new Table(2); 
table.AddHeaderCell("Header 0"); 
table.AddHeaderCell("Header 1"); 
table.AddCell("Data 0"); 
table.AddCell("Data 1"); 

doc.Add(table); 
doc.Close(); 

Voici un exemple de la structure de marquage que nous obtenons:

<Table> 
    <THead> 
     <TR> 
      <TD>    //must be TH! 
       <P> 
        "Header 0" 
      <TD> 
       <P> 
        "Header 1" 
    <TBody> 
     <TR> 
      <TD>    //TD is correct here 
       <P> 
        "Data 0" 
      <TD> 
       <P> 
        "Data 1" 

Est-il possible d'avoir iText générer des balises TH lorsque AddHeaderCell() méthode est utilisé?

J'utilise iText 7.0.0 pour .NET (édition communautaire)

+0

Je veux juste confirmer que la version 7.0.4.(le plus récent à ce moment) montre le même comportement –

Répondre

4

EDIT: réponse initiale a été en mistakingly donnée dans le cadre de pdfHTML et non iText7 appropriée. Les étiquettes TH étiquetées comme TD sont un effet secondaire de l'implémentation actuelle qui traite un TH de la même manière qu'un TD.

Pour iText7

Définir le rôle des cellules d'en-tête à TH avant de les ajouter à la table:

cell.setRole(PdfName.TH); 

Pour pdfHTML

Bien qu'il soit possible d'accéder au éléments après la conversion et avant de les ajouter au document, vous devrez traverser l'arbre de l'élément iText pour trouver et identifier les tables et leurs cellules en-tête. Il est plus facile d'écraser le comportement de conversion des balises avec un CustomTagWorker. Le code suivant provient de the accessibility example. Pour un aperçu sur tagworkers personnalisés, jetez un oeil à la configuration blog-post.

Commencez par créer un tagworker personnalisé qui hérite d'un TdTagWorker, mais remplace le bon rôle avant de retourner le résultat de l'élément:

public class TableHeaderTagWorker extends TdTagWorker { 
    public TableHeaderTagWorker(IElementNode element, ProcessorContext context) { 
     super(element, context); 
    } 

    @Override 
    public IPropertyContainer getElementResult() { 
     Cell cell =(Cell) super.getElementResult(); 
     cell.setRole(PdfName.TH); 
     return super.getElementResult(); 
    } 
} 

Créer une CustomTagWorkerFactory qui associe ce TagWorker au TH -tag

public class AccessibilityTagWorkerFactory extends DefaultTagWorkerFactory { 

    @Override 
    public ITagWorker getCustomTagWorker(IElementNode tag, ProcessorContext context) { 
     //This can probably replaced with a regex or string pattern 
     if(tag.name().equals("h1")){ 
      return new HeaderTagWorker(tag, context,1); 
     } 
     if(tag.name().equals("h2")){ 
      return new HeaderTagWorker(tag, context,2); 
     } 
     if(tag.name().equals("h3")){ 
      return new HeaderTagWorker(tag, context,3); 
     } 
     if(tag.name().equals("h4")){ 
      return new HeaderTagWorker(tag, context,4); 
     } 
     if(tag.name().equals("h5")){ 
      return new HeaderTagWorker(tag, context,5); 
     } 
     if(tag.name().equals("h6")){ 
      return new HeaderTagWorker(tag, context,6); 
     } 

     if(tag.name().equals("th")){ 
      return new TableHeaderTagWorker(tag,context); 
     } 

     return null; 
    } 
} 

Et définir le ConvertorProperties pour utiliser cette fabrique personnalisée:

ConverterProperties props = new ConverterProperties(); 
DefaultTagWorkerFactory tagWorkerFactory = new AccessibilityTagWorkerFactory(); 
props.setTagWorkerFactory(tagWorkerFactory); 
HtmlConverter.convertToPdf(new FileInputStream(src), pdfDoc, props); 
pdfDoc.close(); 
+0

En outre, ce comportement sera corrigé dans une version ultérieure de pdfHTML, donc ce ne sera plus nécessaire –

+0

Merci pour la réponse détaillée! Veuillez noter que j'essaye de construire les données de document directement en utilisant des méthodes comme 'Table.AddHeaderCell()' et ainsi de suite, pas en convertissant un document HTML en PDF. De plus, j'utilise l'édition Community en ce moment, qui n'inclut pas pdfHTML. Est-ce que vous impliquez que pour faire un balisage correct du PDF généré, je dois convertir mes données en HTML et y appliquer pdfHTML? –

+0

Pouvez-vous s'il vous plaît commenter comment pdfHTML est lié à la question? –