iText 7 PDF 辅助功能:“表格标题单元格没有关联的子单元格"; [英] iText 7 PDF accessibility: "Table header cell has no associated subcells"

查看:29
本文介绍了iText 7 PDF 辅助功能:“表格标题单元格没有关联的子单元格";的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 iText 7 将 HTML 转换为 PDF.我需要 PDF 是可访问的(508 符合适当的标签等),但是,无论我在表格上放置什么标记,可访问性检查器都会给出相同的错误:表格标题单元格没有关联的子单元格".我试过设置范围、标题等......似乎没有任何效果.这是其中一个表的示例,但所有表都有相同的问题:

I am converting HTML to a PDF using iText 7. I need the PDF to be accessible (508 compliant with appropriate tags, etc), but, no matter what markup I put on a table, accessibility checkers give the same error: "Table header cell has no associated subcells". I've tried setting scope, headers, etc... nothing seems to work. Here is an example of one of the tables but all of them have the same issue:

 <table class="problems" summary="Patient's diagnosed problems and associated ICD codes.">
        <thead>
            <tr>
                <th scope="col" id="problem-header">
                    Problem
                </th>
                <th scope="col" id="icd-code-header">
                    Code
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
              <td headers="problem-header">Some Problem</td>
              <td headers="icd-code-header">Some ICD Code</td>
            </tr>
        </tbody>
    </table>

任何帮助将不胜感激.非常感谢.

Any help would be appreciated. Thank you so much.

我忘了提及,我使用的是 iText 7 的 .NET 版本.

I forgot to mention, I am using the .NET version of iText 7.

编辑 2:这是将 HTML 转换为 PDF 的代码:

EDIT 2: Here is the code that converts the HTML to PDF:

public class AccessiblePdfService : IAccessiblePdfService
{
    private static readonly string[] FontPaths = ConfigurationManager.AppSettings["FontPaths"].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

    public void createPdf(string html, string dest, PdfTypes type = PdfTypes.RefDoc) //string resources
    {

        FileStream outputStream = new FileStream(dest, FileMode.Create, FileAccess.Write);

        WriterProperties writerProperties = new WriterProperties();

        //Add metadata
        writerProperties.AddXmpMetadata();

        PdfWriter pdfWriter = new PdfWriter(outputStream, writerProperties);

        PdfDocument pdfDoc = new PdfDocument(pdfWriter);
        pdfDoc.GetCatalog().SetLang(new PdfString("en-US"));
        //Set the document to be tagged
        pdfDoc.SetTagged();
        pdfDoc.GetCatalog().SetViewerPreferences(new PdfViewerPreferences().SetDisplayDocTitle(true));

        //Set meta tags
        PdfDocumentInfo pdfMetaData = pdfDoc.GetDocumentInfo();
        pdfMetaData.SetAuthor("SOME STRING");
        pdfMetaData.AddCreationDate();
        pdfMetaData.GetProducer();
        pdfMetaData.SetCreator("SOME STRING");


        switch (type)
        {
            case PdfTypes.RefDoc:
                pdfMetaData.SetKeywords("SOME STRING");
                pdfMetaData.SetSubject("SOME STRING");
                break;
            case PdfTypes.PatientRoi:
                pdfMetaData.SetKeywords("SOME STRING");
                pdfMetaData.SetSubject("SOME STRING");
                break;
            case PdfTypes.RoiAdmin:
                pdfMetaData.SetKeywords("SOME STRING");
                pdfMetaData.SetSubject("SOME STRING");
                break;
            default:
                break;
        }
        //Title is derived from html

        // pdf conversion
        ConverterProperties props = new ConverterProperties();
        FontProvider fp = new FontProvider();
        fp.AddStandardPdfFonts();
        foreach (var path in FontPaths)
        {
            fp.AddFont(path);
        }            

        props.SetFontProvider(fp);

        DefaultTagWorkerFactory tagWorkerFactory = new AccessibilityTagWorkerFactory();
        props.SetTagWorkerFactory(tagWorkerFactory);

        HtmlConverter.ConvertToPdf(html, pdfDoc, props);
        pdfDoc.Close();

    }
}

编辑 3:这是 AccessibilityTagWorkerFactory(请记住,我想要充当表的表未标有make-table-div"类,并且不应受到此类中的自定义的影响:

EDIT 3: Here is the AccessibilityTagWorkerFactory (keep in mind, the tables that I want to act like tables are not marked with the class, "make-table-div" and there shouldn't be affected by the customizations in this class:

public class AccessibilityTagWorkerFactory : DefaultTagWorkerFactory
{
public override ITagWorker GetCustomTagWorker(IElementNode tag, ProcessorContext context)
    {
        bool hasClass = false;
        foreach (var attribute in tag.GetAttributes())
        {
            if (attribute.GetKey() == "class")
            {
                hasClass = true;
            }
        }
        if (hasClass && tag.GetAttribute(AttributeConstants.CLASS).Contains("make-h1"))
        {
            return new HRoleSpanTagWorker(tag, context, StandardRoles.H1);
        }
        if (hasClass && tag.GetAttribute(AttributeConstants.CLASS).Contains("make-h2"))
        {
            return new HRoleSpanTagWorker(tag, context, StandardRoles.H2);
        }
        if (hasClass && tag.GetAttribute(AttributeConstants.CLASS).Contains("make-table-div"))
        {
            return new DivRoleTableTagWorker(tag, context);
        }
        return base.GetCustomTagWorker(tag, context);
    }
}

推荐答案

在与 iText 团队的 Jon Reilly 合作后,这是对我有用的最终解决方案(不需要列 ID 和相关标题...只是范围)

After working with Jon Reilly on the iText team, this was the final solution that worked for me (column IDs and associated headers aren't needed... just Scope)

public class ThWithScopeTagWorker : ThTagWorker
{
    public ThWithScopeTagWorker(IElementNode element, ProcessorContext context) : base(element, context)
    {
    }

    public override void ProcessEnd(IElementNode element, ProcessorContext context)
    {
        base.ProcessEnd(element, context);
        IPropertyContainer elementResult = base.GetElementResult();
        if (elementResult is IAccessibleElement)
        {
            ((IAccessibleElement)elementResult).GetAccessibilityProperties().SetRole(StandardRoles.TH);

            //Can use this in the future in case we have th elements with different scope than "col"
            string htmlScope = element.GetAttribute("scope"); //This is the scope="XXX" in your HTML

            AccessibilityProperties properties = ((IAccessibleElement)elementResult).GetAccessibilityProperties();
            //Could add "Row" if needed based on htmlScope string above. 
            //For my purposes, all th elements were scope="col"
            properties.AddAttributes(new PdfStructureAttributes("Table").AddEnumAttribute("Scope", "Column"));
        }
    }

}

还有这个:

public class AccessibilityTagWorkerFactory : DefaultTagWorkerFactory
{
    public override ITagWorker GetCustomTagWorker(IElementNode tag, ProcessorContext context)
    {    
         //...        
        if (tag.Name() == "th")
        {
            return new ThWithScopeTagWorker(tag, context);
        }
        return base.GetCustomTagWorker(tag, context);
    }
}

这篇关于iText 7 PDF 辅助功能:“表格标题单元格没有关联的子单元格";的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆