来自HTML的iText 7可访问的PDF:当使用display:table时,如何避免表标记; [英] iText 7 accessible PDFs from HTML: how do I avoid table tag when using display: table;

查看:648
本文介绍了来自HTML的iText 7可访问的PDF:当使用display:table时,如何避免表标记;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个将视图转换为PDF的ASP.NET MVC项目。以前使用Rotavia,但新的客户要求是PDF可访问/ 508兼容。出于布局目的,以前的开发人员有一个完整的标题部分(徽标,标题,免责声明等)作为没有元素的表(只是td)。我需要将它们转换为div,但看起来保持不变。所以,我所做的是使它们成为div,然后使用CSS属性,display:table,display:table-row-group,display:table-row,display:table-cell。它看起来几乎完全相同。

I am working on an ASP.NET MVC project which converts a view to a PDF. Previously, Rotavia was used, but then a new client requirement is that the PDF be accessible/508-compliant. For layout purposes, the previous developer had a whole header section (logo, title, disclaimer, etc) as a table without th elements (just td). I needed to convert them to divs but keep the look the same. So, what I did was made them divs and then used the CSS properties, display: table, display: table-row-group, display: table-row, and display: table-cell where appropriate. It ended up looking pretty much exactly the same.

问题是,即使它们现在是div,使用iText DefaultTagWorkerFactory如下:

The issue is, even though they are now divs, using iText DefaultTagWorkerFactory like this:

ConverterProperties props = new ConverterProperties();
FontProvider fp = new FontProvider();
fp.AddStandardPdfFonts();
props.SetFontProvider(fp);
var tagWorkerFactory = new DefaultTagWorkerFactory();
props.SetTagWorkerFactory(tagWorkerFactory);
HtmlConverter.ConvertToPdf(html, pdfDoc, props);

它仍将Div标签转换为table,tr和td标签。显然,在div上使用display:table的整个目的是避免使用表但获得相同的布局效果。

It still converts the Div tags to table, tr, and td tags. Obviously, the whole purpose of using display: table on a div is to avoid using a table but get the same layout effect.

为什么iText会实现这种行为并且有什么方法吗?如果没有,任何人都可以提供任何精确的CSS等效显示:table,display:table-row-group,display:table-row,display:table-cell,因为看起来iText只看到属性,display:table并使用table-tag。我在自定义标记工作者工厂中尝试了以下操作,通过向我的div添加一个类来继承DefaultTagWorkerFactory,make-div,如下所示:

Why does iText implement this behavior and is there any way around it? If not, can anyone provide any precise CSS equivalents of display: table, display: table-row-group, display: table-row, and display: table-cell because it appears that iText just sees the property, "display: table" and uses the table-tag. I have tried the following in a custom tag worker factory that inherits the DefaultTagWorkerFactory by adding a class to my divs, "make-div", like this:

public class AccessibilityTagWorkerFactory : DefaultTagWorkerFactory
    {
        public override ITagWorker GetCustomTagWorker(IElementNode tag, ProcessorContext context)
        {
            var attributes = tag.GetAttributes();
            var cssClass = attributes.GetAttribute("class");
            if (!string.IsNullOrWhiteSpace(cssClass) && cssClass.Contains("make-div"))
            {
                return new DivTagWorker(tag, context);
            }
            return null;
        }
    }

然而,它会引发一个异常,例如无法隐式转换DivTagWorker to DisplayTableRowTagWorker。

However, it throws an exception like "Cannot implicitly convert DivTagWorker to DisplayTableRowTagWorker".

我的智慧结束了所有这一切。任何帮助,将不胜感激。谢谢。

I'm at my wits end with all of this. Any help would be appreciated. Thank you.

推荐答案

您似乎已经替换了标签工作者 display:table-row 元素,但 display:table 没有这样做。当然我无法确定,因为您没有共享样本HTML文件来重现该问题。

You seem to have substituted a tag worker for display: table-row element, but did not do so for display: table. Of course I cannot tell for sure because you haven't shared a sample HTML file to reproduce the issue.

在任何情况下,替换标签工作者的方法不是最好的。它只会丢弃由自定义 display CSS属性引起的布局调整,而您的目标是保存布局,但只需更改标记。

In any case, the approach of substituting tag workers is not the best here. It would just drop layout adjustments caused by custom display CSS property, whereas your goal is to save layout but just change the tagging.

要保存布局并更改标记,不应更改已创建的标记工作程序,而应为单元设置正确的角色由于这些标记工作者而创建的布局元素。

To save layout and change the tagging you should not change the tag worker that is created, but rather set correct roles for Table and Cell layout elements that are created as result of those tag workers.

相应的重载标记工作者可能如下所示:

The corresponding overloaded tag worker might look like following:

private static class DivRoleDisplayTableTagWorker extends DisplayTableTagWorker {
    public DivRoleDisplayTableTagWorker(IElementNode element, ProcessorContext context) {
        super(element, context);
    }

    @Override
    public void processEnd(IElementNode element, ProcessorContext context) {
        super.processEnd(element, context);
        if (getElementResult() instanceof Table) {
            Table table = (Table) getElementResult();
            table.getAccessibilityProperties().setRole(StandardRoles.DIV);
            for (int i = 0; i < table.getNumberOfRows(); i++) {
                for (int j = 0; j < table.getNumberOfColumns(); j++) {
                    Cell cell = table.getCell(i, j);
                    if (cell != null) {
                        cell.getAccessibilityProperties().setRole(StandardRoles.DIV);
                    }
                }
            }
        }
    }
}

您需要做的就是用替换标签工作者 div display:table 与您的自定义标记工作者。根据您的文档,您可能会使用不同的条件,但对于简单的情况,自定义标记工作者工厂将如下所示:

All you need to do is substitute tag worker for div with display: table with your custom tag worker. Depending on your document you might use different conditions, but for a simple case the custom tag worker factory would look like this:

ITagWorkerFactory customFactory = new DefaultTagWorkerFactory() {
    @Override
    public ITagWorker getCustomTagWorker(IElementNode tag, ProcessorContext context) {
        if (CssConstants.TABLE.equals(tag.getStyles().get(CssConstants.DISPLAY)) && TagConstants.DIV.equals(tag.name())) {
            return new DivRoleDisplayTableTagWorker(tag, context);
        }
        return super.getCustomTagWorker(tag, context);
    }
};

现在您的表格及其单元格将被标记为div。

Now your table and its cells would be tagged as divs.

这篇关于来自HTML的iText 7可访问的PDF:当使用display:table时,如何避免表标记;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆