我需要在iText7中创建符合PDF / UA标准的文档。最重要的要求是标记所有内容。启用标记时(通过调用PdfDocument.SetTagged()
方法),添加到文档中的大多数元素都会获得正确的标记。
问题在于标记表头单元格。根据ISO 32000-1:2008,表格标题单元格必须标记为TH,表格数据单元格必须标记为TD( 14.8.4.2.4。表格元素,表337)。
iText允许使用Table.AddHeaderCell()
和Table.AddCell()
方法区分标题单元格和常规单元格。此机制为行组正确创建THead和TBody标记。不幸的是,细胞本身总是标记为TD。
以下是生成表格的示例代码:
//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(社区版)
答案 0 :(得分:4)
编辑:在pdfHTML的背景下错误地给出了初步答案,而不是正确的iText7。
被标记为TD的TH标签是当前实现的副作用,其以与TD相同的方式处理TH。
适用于iText7
在将标题单元格添加到表格之前,将标题单元格的角色设置为TH:
cell.setRole(PdfName.TH);
对于pdfHTML
虽然可以在转换后访问元素并将其添加到文档之前,但您需要遍历iText元素的树以查找和识别表及其标题 - 单元格。使用CustomTagWorker覆盖标记的转换行为更容易。以下代码取自the accessibility example。有关自定义标记工作者的入门读物,请查看configuration blog-post。
首先创建一个继承自TdTagWorker
的自定义标记工具,但在返回元素结果之前覆盖该角色:
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();
答案 1 :(得分:1)
请注意,iText 7.1对此进行了更改。您不再可以直接调用setRole()函数,而必须通过Accessibility Properties。此外,可访问性属性中的setRole()函数仅接受一个字符串。所以现在是:
cell.getAccessibilityProperties().setRole(PdfName.TH.toString());