我为包含文具的不可打印背景图层的打印创建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[]{};
    }
}

困惑 . 那我接下来尝试了什么?

  • 删除代码以添加图层 - 保留压模部分结果:图层仍然存在 .

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

代码:

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(或其他某种方式)中添加另一个不可打印的图层,同时保留所有现有图层层?

非常感谢!

EDIT

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

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来源:-(