Pdf iText 7需要跳过阅读页眉元素

Pdf iText 7需要跳过阅读页眉元素,pdf,header,itext7,screen-readers,section508,Pdf,Header,Itext7,Screen Readers,Section508,我正在使用EventHandler为我的pdf创建页眉。标题的内容在添加到画布之前添加到表中。作为508法规遵从性的一部分,我需要排除标题内容被大声读出。我该怎么做 public class TEirHeaderEventHandler : IEventHandler { public void HandleEvent(Event e) { PdfDocumentEvent docEvent = (PdfDocumentEvent)e; PdfD

我正在使用EventHandler为我的pdf创建页眉。标题的内容在添加到画布之前添加到表中。作为508法规遵从性的一部分,我需要排除标题内容被大声读出。我该怎么做

public class TEirHeaderEventHandler : IEventHandler 
{
    public void HandleEvent(Event e)
    {
        PdfDocumentEvent docEvent = (PdfDocumentEvent)e;
        PdfDocument pdf = docEvent.GetDocument();
        PdfPage page = docEvent.GetPage();

        PdfCanvas headerPdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdf);
        Rectangle headerRect = new Rectangle(60, 725, 495, 96);
        Canvas headerCanvas = new Canvas(headerPdfCanvas, pdf, headerRect);

        //creating content for header
        CreateHeaderContent(headerCanvas);
        headerCanvas.Close();
    }

    private void CreateHeaderContent(Canvas canvas)
    {
        //Create header content
        Table table = new Table(UnitValue.CreatePercentArray(new float[] { 60, 25, 15 } ));
        table.SetWidth(UnitValue.CreatePercentValue(100));

        Cell cell1 = new Cell().Add(new Paragraph("Establishment Inspection Report").SetBold().SetTextAlignment(TextAlignment.LEFT));
        cell1.SetBorder(Border.NO_BORDER);
        table.AddCell(cell1);

        Cell cell2 = new Cell().Add(new Paragraph("FEI Number:").SetBold().SetTextAlignment(TextAlignment.RIGHT));
        cell2.SetBorder(Border.NO_BORDER);
        table.AddCell(cell2);

        Cell cell3 = new Cell().Add(new Paragraph(_feiNum).SetBold().SetTextAlignment(TextAlignment.RIGHT));
        cell3.SetBorder(Border.NO_BORDER);
        table.AddCell(cell3);

        canvas.Add(table);
    }
}

public static void CreatePdf()
{
    using (MemoryStream writeStream = new MemoryStream())
    using (FileStream inputHtmlStream = File.OpenRead(inputHtmlFile))
    {
        PdfDocument pdf = new PdfDocument(new PdfWriter(writeStream));
        pdf.SetTagged();

        iTextDocument document = new iTextDocument(pdf);           

        TEirHeaderEventHandler teirEvent = new TEirHeaderEventHandler();
        pdf.AddEventHandler(PdfDocumentEvent.START_PAGE, teirEvent);


        //Convert html to pdf
        HtmlConverter.ConvertToDocument(inputHtmlStream, pdf, properties);

        document.Close();

        byte[] bytes = TEirReorderingPages(writeStream, numOfPages);

        File.WriteAllBytes(outputPdfFile, bytes);
    }
}

请注意,我已将文档设置为标记。但当我打开文件时,仍然会看到“读取未标记的文档”屏幕。但是,当我激活“大声朗读”功能时,所有内容都会被读取,包括标题。如有任何意见或建议,将不胜感激。提前感谢您的帮助。

页眉和页脚通常是分页工件,应按以下方式进行标记:

table.getAccessibilityProperties().setRole(StandardRoles.ARTIFACT);
这将从读取中排除该表。请注意,您可以将实现
IAccessibleElement
接口的任何元素标记为工件。

General Alexey Subach建议的方法通常是正确的。您将内容标记为工件,以将其与真实内容区分开来

这将标记内容流中的内容,并将元素从结构树中排除

你的案子 然而,您的具体案例更为微妙

对于标记良好的PDF文档,正确的读取方法是处理结构树,这是一种数据结构,表示文档(语义)元素(如段落、表格和列表)的逻辑读取顺序

由于您创建标题内容的方式,它不会自动标记:从
PdfCanvas
实例创建的
Canvas
实例默认禁用了
自动标记。因此,标题中的表没有标记在内容流中,也没有包含在结构树中。使用上面在General中描述的方法将其明确标记为工件,不会产生显著的差异,因为它不在结构树中

如果通过添加
headerCanvas.enableautototaging(page)
来启用
autotaging
,您将注意到该表确实显示在结构树中

如果随后添加
table.getAccessibilityProperties().setRole(StandardRoles.ARTIFACT)
,该表将再次从结构树中排除

总结:查看结构树,您的原始代码与常规方法之间没有区别

Adobe阅读顺序/辅助功能设置 根据您的描述,我认为您正在使用Adobe Acrobat或Reader来实现“大声朗读”功能。在
首选项>阅读>阅读顺序选项
下,您可以为“大声朗读”功能配置处理内容的方式:

发件人:

  • 从文档推断阅读顺序(推荐):使用高级结构推断布局分析方法解释未标记文档的阅读顺序
  • 从左到右、从上到下的阅读顺序:根据文本在页面上的位置传递文本,从左到右再从上到下阅读。此方法比从文档推断阅读顺序更快。这种方法只分析文本;表单字段将被忽略,表不会被识别为表单字段
  • 覆盖标记文档中的阅读顺序:使用阅读首选项中指定的阅读顺序,而不是文档的标记结构指定的阅读顺序。仅当在标记不良的PDF中遇到问题时,才使用此首选项
在我的测试中,我能让Adobe Reader大声读出用原始代码创建的标题内容的唯一方法是,当我选择从左到右、从上到下的阅读顺序,并启用覆盖标记文档中的阅读顺序时。在这种情况下,它基本上忽略了标记,只处理页面上每个位置的内容

禁用覆盖标记文档中的读取顺序时,对于原始代码和显式工件,不会读取标题内容

结论 尽管总是这样标记工件是一个好主意,这样就可以将它们与真实内容正确区分开来,但在这种情况下,我相信您所经历的行为更多地与应用程序配置相关,而不是与文件结构相关

element.getAccessibilityProperties().setRole(StandardRoles.ARTIFACT);