iText 7 PDF 可访问性:“表格标题单元格没有关联的子单元格”
Posted
技术标签:
【中文标题】iText 7 PDF 可访问性:“表格标题单元格没有关联的子单元格”【英文标题】:iText 7 PDF accessibility: "Table header cell has no associated subcells" 【发布时间】:2018-07-24 02:17:40 【问题描述】:我正在使用 iText 7 将 html 转换为 PDF。我需要 PDF 可访问(508 符合适当的标签等),但是,无论我在表格上放置什么标记,可访问性检查器都会给出相同的错误: “表格标题单元格没有关联的子单元格”。我试过设置范围、标题等......似乎没有任何效果。这是其中一个表的示例,但它们都有相同的问题:
<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>
任何帮助将不胜感激。非常感谢。
编辑:我忘了提,我使用的是 .NET 版本的 iText 7。
编辑 2:这是将 HTML 转换为 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”类标记,并且不应该受到此类自定义的影响:
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);
【问题讨论】:
AcessibilityTagWorkerFactory 是否来自this example?我不确定您使用哪个合规检查器来查看错误,但如果使用TableHeaderTagWorker
(上面使用的类中的链接)而不是默认的 ThTagWorker
,Acrobat 的合规检查器 simplay 会显示“标题”失败。跨度>
嗨@JonReilly,感谢您的回复。我用 AccessibilityTagWorkerFactory 编辑了这个问题。简短的回答是它是根据该示例建模的,但它没有使用 TH 标签进行任何自定义工作。如果默认使用 ThTagWorker,那么我应该没有问题,对吧?我正在使用 PAC 3 来检查可访问性:access-for-all.ch/en/pdf-lab/pdf-accessibility-checker-pac.html,但我使用了具有相同结果的其他测试,包括我自己在 Acrobat Pro 中检查标签。 TH 标签没有 ID,TD 标签不与 TH ID 关联。
【参考方案1】:
在与 iText 团队的 Jon Reilly 合作后,这是对我有用的最终解决方案(不需要列 ID 和关联的标题......只需 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);
【讨论】:
如脱机所述,pdfHtml (2.0.2) 的下一版本将支持 PDF/UA 标准要求的以上是关于iText 7 PDF 可访问性:“表格标题单元格没有关联的子单元格”的主要内容,如果未能解决你的问题,请参考以下文章
使用 iText 7 和 C# 在可访问的 pdf 中将标题添加为 H1
使用 iTextSharp 添加水印文本时,PAC 工具中出现 iText 7 警告