如何使用PdfBox生成分层的pdf文件?

时间:2014-12-22 12:54:42

标签: java pdf layer pdfbox

我在使用PdfBox生成分层pdf页面时遇到问题。我在这里看过几篇关于这个主题的帖子,但是他们专注于将页面从另一个pdf导入目标文档。

我的情况有点不同(至少我是这么认为:))。 我创建了一个类MapImage,其中包含纸张大小(以像素为单位)和一个BufferedImages列表,我想将其添加到单个pdf页面。

以下是我尝试过的代码:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
PDDocument document = new PDDocument();
for (MapImage image : images) {
    PDPage page = new PDPage(new PDRectangle(image.getPaperWidth(), image.getPaperHeight()));
    page.setResources(new PDResources(new COSDictionary()));
    document.addPage(page);

    LayerUtility layerUtility = new LayerUtility(document);
    int i=1;
    for(BufferedImage layer : image.getLayers()) {
        PDJpeg img = new PDJpeg(document, layer);                        
        layerUtility.appendFormAsLayer(page, new PDXObjectForm(img.getCOSStream()), new AffineTransform(), "Layer " + i++);
    }
}
document.save(baos);
document.close();

不幸的是,生成的PDF已损坏。 我管理创建一个只有一个图像的页面(没有图层),但不幸的是我不知道如何做到这一点。

有没有人遇到过这样的问题?

1 个答案:

答案 0 :(得分:3)

好的,我解决了。 这是做我想要的方法。也许这对某人有用:)

public static PDOptionalContentGroup appendImageAsLayer(PDDocument document, PDPage targetPage, BufferedImage image, String layerName) throws IOException {
    PDDocumentCatalog catalog = document.getDocumentCatalog();
    PDOptionalContentProperties ocprops = catalog.getOCProperties();
    if (ocprops == null) {
        ocprops = new PDOptionalContentProperties();
        catalog.setOCProperties(ocprops);
    }
    if (ocprops.hasGroup(layerName)) {
        throw new IllegalArgumentException("Optional group (layer) already exists: " + layerName);
    }

    PDOptionalContentGroup layer = new PDOptionalContentGroup(layerName);
    ocprops.addGroup(layer);

    PDResources resources = targetPage.findResources();
    if(resources == null ) {
        resources = new PDResources(new COSDictionary());
        targetPage.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);
    PDJpeg img = new PDJpeg(document, image);

    PDPageContentStream contentStream = new PDPageContentStream(document, targetPage, true, false);
    contentStream.beginMarkedContentSequence(COSName.OC, resourceName);
    contentStream.drawImage(img, 0, 0);
    contentStream.endMarkedContentSequence();
    contentStream.close();

    return layer;
}