如何使用PDFBox在带标签的PDF中添加注释标签

问题描述 投票:0回答:1
java pdf pdfbox
1个回答
0
投票

这是我的第一次尝试。我没有 PAC 工具(或者我找不到它),所以我需要知道出了什么问题(如果有)。我已将注释放在数组的末尾

Root/StructTreeRoot/K/[0]/K/[0]/K/[0]/K
,在另一个文件中,它是数组中的第一项。 (COSArray 显然没有“插入”)

PDStructureTreeRoot structureTreeRoot = doc.getDocumentCatalog().getStructureTreeRoot();
PDPage page = doc.getPage(0);
PDAnnotation annotation = page.getAnnotations().get(0);

COSArray aDocument = (COSArray) structureTreeRoot.getK();
COSDictionary oDocument = (COSDictionary) aDocument.getObject(0);
COSArray aPart = oDocument.getCOSArray(COSName.K);
COSDictionary oPart = (COSDictionary) aPart.getObject(0);
COSArray aSect = oPart.getCOSArray(COSName.K);
COSDictionary oSect = (COSDictionary) aSect.getObject(0);
COSArray aP = oSect.getCOSArray(COSName.K);

COSDictionary anDict = new COSDictionary(); // PDStructureElement
anDict.setItem(COSName.S, COSName.ANNOT);
anDict.setItem(COSName.P, aSect.get(0)); // assign aP but as ref
PDObjectReference objRef = new PDObjectReference();
anDict.setItem(COSName.K, objRef);
objRef.setReferencedObject(page.getAnnotations().get(0));
objRef.getCOSObject().setItem(COSName.P, anDict); //TODO check if needed in PDObjectReference API?
objRef.getCOSObject().setItem(COSName.PG, page); //TODO check if needed in PDObjectReference API?
aP.add(anDict);

int parentTreeNextKey = structureTreeRoot.getParentTreeNextKey(); // -1, ignored here

PDNumberTreeNode parentTree = structureTreeRoot.getParentTree();
Map<Integer, COSObjectable> numberTreeAsMap = getNumberTreeAsMap(parentTree);
Set<Integer> keySet = numberTreeAsMap.keySet();
int maximum = keySet.stream().reduce(Integer::max).get();
annotation.setStructParent(maximum + 1);
structureTreeRoot.setParentTreeNextKey(maximum + 2);
numberTreeAsMap.put(maximum + 1, anDict);
parentTree = new PDNumberTreeNode(PDParentTreeValue.class);
parentTree.setNumbers(numberTreeAsMap);
structureTreeRoot.setParentTree(parentTree);

getNumberTreeAsMap 是 PDFMergerUtility 中的一个便捷方法

static Map<Integer, COSObjectable> getNumberTreeAsMap(PDNumberTreeNode tree)
        throws IOException
{
    if (tree == null)
    {
        return new LinkedHashMap<>();
    }
    Map<Integer, COSObjectable> numbers = tree.getNumbers();
    if (numbers == null)
    {
        numbers = new LinkedHashMap<>();
    }
    else
    {
        // must copy because the map is read only
        numbers = new LinkedHashMap<>(numbers);
    }
    List<PDNumberTreeNode> kids = tree.getKids();
    if (kids != null)
    {
        for (PDNumberTreeNode kid : kids)
        {
            numbers.putAll(getNumberTreeAsMap(kid));
        }
    }
    return numbers;
}
© www.soinside.com 2019 - 2024. All rights reserved.