返回

连续结构元素在阅读顺序面板合并为单一元素怎么办?

java

解决连续结构元素在阅读顺序面板中合并为单个元素的问题

简介

PDF 文档的阅读顺序至关重要,因为它决定了用户如何阅读和理解其内容。在某些情况下,连续的结构元素(例如段落)在 Adobe Acrobat Reader 的阅读顺序面板中可能会作为一个元素显示,而不是按预期分开。本文将探讨导致此问题的原因并提供详细的解决方案。

问题分析

当 PDFTextStripper 类提取文本时,它会将其存储在 TextPositionsInfo 列表中。在将文本添加到内容流时,代码会逐个字符地绘制文本。虽然这对于单个元素(如标题)是有效的,但它会导致连续元素(如段落)合并为一个。

解决方案

要解决此问题,需要对代码进行以下修改:

  1. 识别连续元素:
    在遍历 TextPositionsInfo 列表时,检查相邻元素的结构元素类型是否相同。如果相同,则将它们标记为连续元素。

  2. 对连续元素进行分组:
    对于每个连续元素组,将它们分组到一个单独的 PDStructureElement 中。此元素将作为连续元素的父元素,并将其添加到阅读顺序树中。

  3. 设置正确的内容流:
    对于每个连续元素组,开始一个标记的内容流。这将确保连续元素在阅读顺序面板中作为单独的元素显示。

代码修改

private PDStructureElement addTextCharByChar(List<TextPositionsInfo> textinfoList, String elementType, PDPage currentPage,
    PDStructureElement Parent) throws IOException {
    PDResources res = currentPage.getResources();
    PDStructureElement currParent = null;
    currentContentStream.beginText(); 

    // 识别连续元素
    List<List<TextPositionsInfo>> continuousElementGroups = new ArrayList<>();
    List<TextPositionsInfo> currentGroup = new ArrayList<>();
    for (TextPositionsInfo textInfo : textinfoList) {
        if (currentGroup.isEmpty() || currentGroup.get(0).elementType.equals(textInfo.elementType)) {
            currentGroup.add(textInfo);
        } else {
            continuousElementGroups.add(currentGroup);
            currentGroup = new ArrayList<>();
            currentGroup.add(textInfo);
        }
    }
    continuousElementGroups.add(currentGroup);

    // 对连续元素进行分组
    for (List<TextPositionsInfo> group : continuousElementGroups) {
        PDStructureElement groupParent = addStructEleToStructEleTree(elementType, Parent, currentPage, COSName.of(elementType));
        for (TextPositionsInfo textInfo : group) {
            PDFont font = getFonts(res, textInfo.fontName);
            if (font != null) {
                currentContentStream.setFont(font, 1);
                Matrix _tm = textInfo.textMatrix;
                currentContentStream.setTextMatrix(_tm);
                currentContentStream.showText(textInfo.unicode);
            }
        }
    }
    currentContentStream.endText();
    return currParent;
}

结论

通过对代码进行这些修改,连续的结构元素(如段落)可以正确地识别并显示在阅读顺序面板中。这对于确保 PDF 文档的无障碍性和易读性至关重要。

常见问题解答

  1. 为什么连续元素在阅读顺序面板中会合并为一个元素?
    因为默认情况下,文本提取器会逐个字符地绘制文本,而不会考虑结构元素的类型。

  2. 如何识别连续的结构元素?
    通过检查相邻元素的结构元素类型是否相同来识别连续元素。

  3. 如何将连续元素分组?
    将连续元素分组到一个单独的 PDStructureElement 中,该元素作为连续元素的父元素。

  4. 如何设置正确的内容流?
    对于每个连续元素组,开始一个标记的内容流,以确保连续元素在阅读顺序面板中作为单独的元素显示。

  5. 这些修改会影响其他结构元素的处理吗?
    这些修改不会影响其他结构元素的处理,因为它们专门针对连续的结构元素。