Pdf iText 7需要跳过阅读页眉元素
我正在使用EventHandler为我的pdf创建页眉。标题的内容在添加到画布之前添加到表中。作为508法规遵从性的一部分,我需要排除标题内容被大声读出。我该怎么做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
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);