【问题标题】:How to avoid to tag the empty <TR<TD> cells to PDF using Itext 5如何避免使用 Itext 5 将空的 <TR<TD> 单元格标记为 PDF
【发布时间】:2020-04-05 12:16:32
【问题描述】:

我使用 i text 5 从 html 生成 PDF 作为输入。 作为 PDF 可访问性的一部分,添加 pdfwriter.settagged()

但是这里所有的空标签和非空标签都被标记了。请你帮助如何避免标记非空的html标签

【问题讨论】:

    标签: itext tagging xmlworker


    【解决方案1】:

    我想绕过它的一种方法是通过输出 PDF 文档上的 StructTree,并尝试找到您正在寻找的标签,没有任何孩子,并将其从父级中删除。我不再使用 iText 5,因为它已被弃用(仅发布了安全修复程序),但使用 iText 7,您可以执行以下操作:

    private void removeEmptyTag() throws IOException {
        final PdfDocument pdfDoc = new PdfDocument(new PdfReader(ORIG),
                new PdfWriter(DEST));
        PdfDictionary catalog = pdfDoc.getCatalog().getPdfObject();
        // Gets the root dictionary
        PdfDictionary structTreeRoot = catalog.getAsDictionary(PdfName.StructTreeRoot);
        manipulate(structTreeRoot);
    
        pdfDoc.close();
    }
    
    public boolean manipulate(PdfDictionary element) {
    
        if (element == null)
            return false;
    
        if (PdfName.TD.equals(element.get(PdfName.S))) {
            if (!element.containsKey(PdfName.K)) {
                return true;
            }
        }
    
        PdfArray kids = element.getAsArray(PdfName.K);
        if (kids == null) return false;
        for (int i = 0; i < kids.size(); i++) {
            if (manipulate(kids.getAsDictionary(i))) {
                kids.remove(i);
            }
        }
    
        return false;
    }
    

    这不是最优雅的事情,但我使用pdfHTML 创建了一个 HTML 文件,其中我有一个空的 td

    <tr>
        <th>Firstname</th>
        <th>Lastname</th>
        <th>Age</th>
    </tr>
    <tr>
        <td>Jill</td>
        <td>Smith</td>
        <td></td>
    </tr>
    <tr>
        <td>Eve</td>
        <td>Jackson</td>
        <td>94</td>
    </tr>
    

    然后我使用代码来检查它并删除空标签(或者更确切地说,没有子标签的标签)。也许有一个直接使用 xmlWorker 的解决方案(我假设这是您用来创建 HTML 文档的方法),或者是我建议的更好的后处理替代方案。

    【讨论】:

    • 在将 html 转换为 PDF 时有什么方法可以避免出现空标签。我可以看到您的代码在 pdf 生成后可以工作。
    • 我在 Itext 7 中尝试了上述解决方案,但它在 PDF 报告中显示混乱的数据
    • 能否提供PDF文件?
    • 如何附加PDF文件,我没有任何附加选项
    【解决方案2】:

    你可以直接用pdfHTML来做(基本上是iText 7中HTML到PDF转换的解决方案)。

    ConverterProperties props = new ConverterProperties();
    props.setTagWorkerFactory(new DefaultTagWorkerFactory() {
                    @Override
                    public ITagWorker getCustomTagWorker(
                            IElementNode tag, ProcessorContext context) {
                        if (tag.name().equals(TagConstants.TD)) {
                            if (!tag.childNodes().isEmpty()) {
                                return new TdTagWorker(tag, context);
                            } else {
                                return new SpanTagWorker(tag, context);
                            }
                        }
    
    
                        return null;
                    }
                });
    
    
    PdfDocument doc = new PdfDocument(new PdfWriter(DEST));
    doc.setTagged();
    
    HtmlConverter.convertToPdf(new FileInputStream(ORIG), doc, props);
    

    在上面的代码中,您可以使用setTagWorkerFactory 为您的标签设置自定义行为,如the documentation 中所述。在这种特定情况下,我只是将空的 TD 标签更改为 Span 元素,从而实现所需的行为(多余的 TD 标签消失)。

    (老实说,这依赖于 TR 工作人员无法解析 SPAN 标签,所以它只是跳船。如果我想出一个更优雅的解决方案,我会更新答案)

    【讨论】:

    • 您显然也可以使用 xmlWorker (raw.githubusercontent.com/itext/i5js-sandbox/master/src/main/…) 进行自定义处理,因此 iText 5 可能也可以。
    • 感谢您的宝贵回复。如何使用 Itext 5 实现相同的目标。
    • 我很抱歉@NagaSureshBabuP,但我不知道,但根据链接,有一个 setTagFactory(),所以您可以在通过特定标签时更改行为。你有理由不只使用 iText 7 + pdfHTML 吗?
    • 仍然尝试上述解决方案,NVDA 也读取空白空间(空 TD)(例如:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    • 2017-02-18
    • 2013-06-14
    • 2022-12-05
    • 2018-07-13
    相关资源
    最近更新 更多