如何修改 pdf 中的现有图层(可选内容组)?

How do I make modifications to existing layer(Optional Content Group) in pdf?

我正在实现允许用户以 pdf 格式绘制图形的功能。我想在一个图层中绘制所有图形,可以通过 user.I 使图层可见或不可见 我能够在 pdf 中创建一个新图层。我也能够检索 layer.But,我无法对图层 (PDOptionalContentGroup) 进行修改。我尝试将 PDOptionalContentGroup 转换为 PDPage,然后对 PDPPage 进行所需的更改。我还保存了 PDDocument.It 只创建了另一个与前一个同名的图层,但更改不是 there.Here 是我使用的代码:

PDFont font = PDType1Font.HELVETICA;
PDDocument doc = PDDocument.load(src);
PDOptionalContentProperties ocprops = doc.getDocumentCatalog().getOCProperties();
foreach (string groupName in ocprops.getGroupNames())
{
    PDOptionalContentGroup group = ocprops.getGroup(groupName);
    COSBase cosbase = group.getCOSObject();
    PDPage groupPage = new PDPage((COSDictionary)cosbase);
    PDPageContentStream cs = new PDPageContentStream(doc, groupPage, true, false);
    cs.beginText();
    cs.setFont(font, 12);
    cs.moveTextPositionByAmount(150, 200);
    cs.drawString("Testing added to group:" + groupName);
    cs.endText();
    cs.close();
    doc.save(src);
}

(在评论中,OP 表示他只能使用 1.8.x 版本的 PDFBox。因此,这里的代码是 1.8'ish,针对 PDFBox 1.8.12 进行了测试Java.)

在对您的问题的评论中"How to get resource names for optional content group in a pdf?" Tilman Hausherr 建议使用 PDFBox class LayerUtility 作为自己解决方案的模板。

因此,作为如何添加到现有 OCG 的示例,此辅助方法(基于 LayerUtility.appendFormAsLayer)展示了如何将文本添加到现有或新的 OCG。适应它来添加你想添加的内容应该很简单...

void addTextToLayer(PDDocument document, int pageNumber, String layerName, float x, float y, String text) throws IOException
{
    PDDocumentCatalog catalog = document.getDocumentCatalog();
    PDOptionalContentProperties ocprops = catalog.getOCProperties();
    if (ocprops == null)
    {
        ocprops = new PDOptionalContentProperties();
        catalog.setOCProperties(ocprops);
    }
    PDOptionalContentGroup layer = null;
    if (ocprops.hasGroup(layerName))
    {
        layer = ocprops.getGroup(layerName);
    }
    else
    {
        layer = new PDOptionalContentGroup(layerName);
        ocprops.addGroup(layer);
    }

    PDPage page = (PDPage) document.getDocumentCatalog().getAllPages().get(pageNumber);

    PDResources resources = page.findResources();
    if (resources == null)
    {
        resources = new PDResources();
        page.setResources(resources);
    }
    PDPropertyList props = resources.getProperties();
    if (props == null)
    {
        props = new PDPropertyList();
        resources.setProperties(props);
    }

    //Find first free resource name with the pattern "MC<index>"
    int index = 0;
    PDOptionalContentGroup ocg;
    COSName resourceName;
    do
    {
        resourceName = COSName.getPDFName("MC" + index);
        ocg = props.getOptionalContentGroup(resourceName);
        index++;
    } while (ocg != null);
    //Put mapping for our new layer/OCG
    props.putMapping(resourceName, layer);

    PDFont font = PDType1Font.HELVETICA;

    PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true, true);
    contentStream.beginMarkedContentSequence(COSName.OC, resourceName);
    contentStream.beginText();
    contentStream.setFont(font, 12);
    contentStream.moveTextPositionByAmount(x, y);
    contentStream.drawString(text);
    contentStream.endText();
    contentStream.endMarkedContentSequence();

    contentStream.close();
}

(AddContentToOCG 辅助方法 addTextToLayer)

你可以这样使用它

PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);

addTextToLayer(document, 0, "MyLayer", 30, 600, "Text in new layer 'MyLayer'");
addTextToLayer(document, 0, "MyOtherLayer", 230, 550, "Text in new layer 'MyOtherLayer'");
addTextToLayer(document, 0, "MyLayer", 30, 500, "Text in existing layer 'MyLayer'");
addTextToLayer(document, 0, "MyOtherLayer", 230, 450, "Text in existing layer 'MyOtherLayer'");

document.save(new File(RESULT_FOLDER, "TextInOCGs.pdf"));
document.close();

(AddContentToOCG测试方法testAddContentToNewOrExistingOCG)

向现有或尚不存在的 OCG 添加文本。