我为包含文具的不可打印背景图层的打印创建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(或其他一些)中添加另一个不可打印的图层方式)同时保留所有现有的图层?
非常感谢你!
修改
随着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源代码: - (