我为包含文具的不可打印背景图层的打印创建PDF文件,因此它在打印和屏幕上看起来相同 .
找到的示例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来源:-(