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

时间:2017-04-07 10:00:11

标签: pdf pdfbox layer

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

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);
}

1 个答案:

答案 0 :(得分:1)

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

在对您的问题的评论中"How to get resource names for optional content group in a pdf?" Tilman Hausherr建议使用PDFBox类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中。