使用PdfStamper向包含图层的PDF添加图层会使现有图层变平

时间:2017-05-24 13:58:32

标签: java pdf itext

我为包含文具的不可打印背景图层的打印创建PDF文件,因此它在打印和屏幕上看起来相同。

enter image description here

找到示例here

现在,一旦准备好的PDF被批准打印,我想添加一个包含存档/批准数据的条形码 - 再次作为未打印的图层。

但是一旦我这样做,所有现有的图层都消失了,只剩下添加的图层,导致突然打印出不可打印的背景图层。

请参阅here了解我的(失败的)结果

这是我的addBarcode方法:

public static byte[] addBarcode_OriginalIdea(byte[] src, String barcodeText, String layerName, boolean printable) {
    try (ByteArrayOutputStream bo = new ByteArrayOutputStream()) {
        PdfReader reader = new PdfReader(src);                      
        PdfStamper stamper = new PdfStamper(reader, bo);
        //Add an additional layer to Page 1
        PdfContentByte over = stamper.getOverContent(1);
        Barcode128 barcode = new Barcode128();
        barcode.setCode(barcodeText);
        barcode.setBarHeight(10f);                     
        Image img = barcode.createImageWithBarcode(over, Color.decode("#0c1754"), Color.decode("#0c1754"));
        img.setRotationDegrees(-90f);            
        img.setAbsolutePosition(reader.getPageSize(1).getRight()-img.getHeight()-5,  5);
        PdfLayer barcodeLayer = new PdfLayer(layerName, stamper.getWriter());
        barcodeLayer.setOnPanel(true);
        barcodeLayer.setPrint("Print", printable);
        over.beginLayer(barcodeLayer);
        over.addImage(img);
        over.endLayer();
        //End add layer
        stamper.close();
        bo.close();
        return bo.toByteArray();
    } catch (Exception e) {
        e.printStackTrace();
        return new byte[]{};
    }
}

混淆。那我接下来尝试了什么?

  1. 删除添加图层的代码 - 保留压模部分 结果:图层仍在那里。

  2. 在添加新图层之前和之后打印图层: 结果:我可以看到添加了新图层,但PdfStamper在关闭期间抛出了异常。

  3. 代码:

    public static byte[] addBarcode_showLayersBeforeAfter(byte[] src, String barcodeText, String layerName, boolean printable) {
        try (ByteArrayOutputStream bo = new ByteArrayOutputStream()) {
            PdfReader reader = new PdfReader(src);                      
            PdfStamper stamper = new PdfStamper(reader, bo);
            //List all layers contained in document before
            Map map = stamper.getPdfLayers();
            for(Object me: map.keySet()) {
                System.out.println("Layer before: " + me);
            }                       
    
            //Add an additional layer to Page 1
            PdfContentByte over = stamper.getOverContent(1);
            Barcode128 barcode = new Barcode128();
            barcode.setCode(barcodeText);
            barcode.setBarHeight(10f);                     
            Image img = barcode.createImageWithBarcode(over, Color.decode("#0c1754"), Color.decode("#0c1754"));
            img.setRotationDegrees(-90f);            
            img.setAbsolutePosition(reader.getPageSize(1).getRight()-img.getHeight()-5,  5);
            PdfLayer barcodeLayer = new PdfLayer(layerName, stamper.getWriter());
            barcodeLayer.setOnPanel(true);
            barcodeLayer.setPrint("Print", printable);
            over.beginLayer(barcodeLayer);
            over.addImage(img);
            over.endLayer();            
            //End add layer
    
            //List all layers contained in document before
            Map map2 = stamper.getPdfLayers();
            for(Object me: map2.keySet()) {
                System.out.println("Layer after: " + me);
            }
            reader.close();
            stamper.close(); // <-- this now throws an Exception!
            bo.close();
            return bo.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
            return new byte[]{};
        }
    }
    

    这会产生此输出:

    Layer before: Footer-2
    Layer before: Template-Page-0
    Layer before: Template-Page-2
    Layer before: Template-Page-1
    Layer before: Footer-0
    Layer before: Footer-1
    Layer after: Footer-2
    Layer after: Template-Page-0
    Layer after: StackLayer
    Layer after: Template-Page-2
    Layer after: Template-Page-1
    Layer after: Footer-0
    Layer after: Footer-1
    java.lang.NullPointerException
        at com.lowagie.text.pdf.PdfWriter.fillOCProperties(Unknown Source)
        at com.lowagie.text.pdf.PdfStamperImp.close(Unknown Source)
        at com.lowagie.text.pdf.PdfStamper.close(Unknown Source)
        at BarcodeLayer.addBarcode_showLayersBeforeAfter(BarcodeLayer.java:119)
        at BarcodeLayer.main(BarcodeLayer.java:44)  
    

    我真的非常讨厌在这一点上重新创建整个PDF +条形码只是为了让图层笔直,是否有人知道如何在PdfStamper(或其他一些)中添加另一个不可打印的图层方式)同时保留所有现有的图层?

    非常感谢你!

    修改

    随着Bruno的建议转向第5版,它变得更加奇怪。现在我可以看到正在添加到PDF的图层。现在背景保持未打印状态(如所需),但添加的条形码图层始终打印。我在添加条形码后使用此代码分析图层:

            Map map2 = stamper.getPdfLayers();
            for(Object me: map2.keySet()) {
                System.out.println("Layer after: " + me );
                PdfDictionary dict2 = ((PdfLayer)map2.get(me)).getAsDict(PdfName.USAGE);
                if(dict2 != null) {
                    PdfDictionary dict = dict2.getAsDict(PdfName.PRINT);
                    System.out.println("Subtype" + dict.getAsName(PdfName.SUBTYPE));
                    System.out.println("Printable: " + dict.getAsName(PdfName.PRINTSTATE));
                }
            }
    

    导致添加的层:

    Printable: /OFF
    Layer after: StackLayer
    Subtype/Print
    

    但仍然 - 在点击打印预览时,图层仍然存在。现在我使用刚刚创建的pdf并列出了图层 - 而Print-Attribute已经消失了:

    Layer before: StackLayer
    Layer before: Template-Page-2
    

    所以无论发生什么事情似乎都会在关闭PdfStamper时发生 - 比如没有正确更新PdfLayers等。我想我接下来要查看itext源代码: - (

0 个答案:

没有答案