如何在 iText7 中将 table header 单元格标记为 TH 而不是 TD?
How to tag table header cells as TH instead of TD in iText7?
我需要在 iText7 中创建一个 PDF/UA 兼容文档。最重要的要求是标记所有内容。启用标记后(通过调用 PdfDocument.SetTagged()
方法)添加到文档的大多数元素都会获得正确的标记。
问题在于 table header 单元格的标记。根据 ISO 32000-1:2008,table header 单元格必须标记为 TH,table 数据单元格必须标记为 TD (14.8.4.2.4。 Table 元素, Table 337).
iText 允许使用 Table.AddHeaderCell()
和 Table.AddCell()
方法区分 header 单元格和常规单元格。此机制正确地为行组创建 THead 和 TBody 标记。不幸的是,细胞本身总是被标记为 TD。
这里是生成 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();
这是我们得到的标记结构的示例:
<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"
当使用AddHeaderCell()
方法时,是否可以让iText生成TH标签?
我正在使用 iText 7.0.0 for .NET(社区版)
编辑:最初的答案是在 pdfHTML 的上下文中错误给出的,而不是 iText7 本身。
被标记为 TD 的 TH 标签是当前实现的 side-effect,它以与 TD 相同的方式对待 TH。
对于 iText7
在将 header-cells 添加到 table 之前将 header-cells 的角色设置为 TH:
cell.setRole(PdfName.TH);
对于 pdfHTML
虽然可以在转换后和将它们添加到文档之前访问元素,但您需要遍历 iText 元素树以查找和识别 table 及其 header -细胞。使用 CustomTagWorker 覆盖标签的转换行为更容易。以下代码摘自the accessibility example. For a primer on custom tagworkers, have a look at the configuration blog-post.
首先创建一个继承自 TdTagWorker
的自定义 tagworker,但在返回 element-result 之前覆盖该角色:
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();
}
}
创建一个 CustomTagWorkerFactory
将此 TagWorker
映射到 TH
-标签
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;
}
}
并设置 ConvertorProperties 以使用此自定义工厂:
ConverterProperties props = new ConverterProperties();
DefaultTagWorkerFactory tagWorkerFactory = new AccessibilityTagWorkerFactory();
props.setTagWorkerFactory(tagWorkerFactory);
HtmlConverter.convertToPdf(new FileInputStream(src), pdfDoc, props);
pdfDoc.close();
请注意,iText 7.1 已经改变了这一点。您不能再直接调用 setRole() 函数,您必须通过辅助功能属性。此外,辅助功能属性中的 setRole() 函数仅接受字符串。所以现在,它将是:
cell.getAccessibilityProperties().setRole(PdfName.TH.toString());
我需要在 iText7 中创建一个 PDF/UA 兼容文档。最重要的要求是标记所有内容。启用标记后(通过调用 PdfDocument.SetTagged()
方法)添加到文档的大多数元素都会获得正确的标记。
问题在于 table header 单元格的标记。根据 ISO 32000-1:2008,table header 单元格必须标记为 TH,table 数据单元格必须标记为 TD (14.8.4.2.4。 Table 元素, Table 337).
iText 允许使用 Table.AddHeaderCell()
和 Table.AddCell()
方法区分 header 单元格和常规单元格。此机制正确地为行组创建 THead 和 TBody 标记。不幸的是,细胞本身总是被标记为 TD。
这里是生成 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();
这是我们得到的标记结构的示例:
<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"
当使用AddHeaderCell()
方法时,是否可以让iText生成TH标签?
我正在使用 iText 7.0.0 for .NET(社区版)
编辑:最初的答案是在 pdfHTML 的上下文中错误给出的,而不是 iText7 本身。
被标记为 TD 的 TH 标签是当前实现的 side-effect,它以与 TD 相同的方式对待 TH。
对于 iText7
在将 header-cells 添加到 table 之前将 header-cells 的角色设置为 TH:
cell.setRole(PdfName.TH);
对于 pdfHTML
虽然可以在转换后和将它们添加到文档之前访问元素,但您需要遍历 iText 元素树以查找和识别 table 及其 header -细胞。使用 CustomTagWorker 覆盖标签的转换行为更容易。以下代码摘自the accessibility example. For a primer on custom tagworkers, have a look at the configuration blog-post.
首先创建一个继承自 TdTagWorker
的自定义 tagworker,但在返回 element-result 之前覆盖该角色:
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();
}
}
创建一个 CustomTagWorkerFactory
将此 TagWorker
映射到 TH
-标签
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;
}
}
并设置 ConvertorProperties 以使用此自定义工厂:
ConverterProperties props = new ConverterProperties();
DefaultTagWorkerFactory tagWorkerFactory = new AccessibilityTagWorkerFactory();
props.setTagWorkerFactory(tagWorkerFactory);
HtmlConverter.convertToPdf(new FileInputStream(src), pdfDoc, props);
pdfDoc.close();
请注意,iText 7.1 已经改变了这一点。您不能再直接调用 setRole() 函数,您必须通过辅助功能属性。此外,辅助功能属性中的 setRole() 函数仅接受字符串。所以现在,它将是:
cell.getAccessibilityProperties().setRole(PdfName.TH.toString());