Java 将包含PdfStamper图层的图层添加到PDF会展平现有图层
我为打印创建了PDF文件,其中包含一个不可打印的信纸背景层,所以它在打印和屏幕上看起来都一样 要找到的示例 现在,一旦准备好的PDF被批准打印,我想添加一个包含存档/批准数据的条形码-同样作为一个未打印的层 但一旦我这样做了,所有现有的图层都消失了,只剩下添加的图层,导致无法打印的背景图层突然被打印出来 有关我的(失败)结果,请参阅 以下是我的addBarcode方法:Java 将包含PdfStamper图层的图层添加到PDF会展平现有图层,java,pdf,itext,Java,Pdf,Itext,我为打印创建了PDF文件,其中包含一个不可打印的信纸背景层,所以它在打印和屏幕上看起来都一样 要找到的示例 现在,一旦准备好的PDF被批准打印,我想添加一个包含存档/批准数据的条形码-同样作为一个未打印的层 但一旦我这样做了,所有现有的图层都消失了,只剩下添加的图层,导致无法打印的背景图层突然被打印出来 有关我的(失败)结果,请参阅 以下是我的addBarcode方法: public static byte[] addBarcode_OriginalIdea(byte[] src, Strin
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[]{};
}
}
困惑。那么接下来我尝试了什么
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[]{};
}
}
我真的,真的很讨厌在这一点上重新创建整个PDF+条形码,只是为了把图层弄清楚,有人知道如何在PdfStamper(或其他方式)中添加另一个不可打印的图层,同时保留所有现有图层吗
非常感谢你
编辑
在布鲁诺的建议下,移动到itext版本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并列出了图层-打印属性消失了:
Layer before: StackLayer
Layer before: Template-Page-2
因此,无论发生什么,似乎都是在关闭PdfStamper时发生的,比如没有正确更新PdfLayers之类。我想接下来我必须研究itext source:-(很抱歉,我要研究您的问题,因为我知道我可以解决这个问题(几年前我为一位客户解决了一个类似的问题),但后来我在你的堆栈跟踪中注意到了我的名字。这意味着你使用的iText版本至少可以追溯到2009年。如果你想避免挫折(你自己的挫折和我的一样),请升级和。你好,布鲁诺谢谢你的建议-可以,重新测试。好的,我可能无法立即回答后续问题。我摔断了胳膊,只能用一只手打字。我下周不应该工作(但很难按照医生的指示)。好了,布鲁诺!改为iTest 5.5.11(我工作的公司有许可证)解决了异常,但没有解决stamper中添加的条形码层始终被打印。@BrunoLowagie:我觉得这是itext pdfstamper中的一个缺陷-如果PDF中存在要打印的层,则某些OCG属性(如打印信息)似乎不会被合并。为了解决我的问题,我将条形码移到了PageEvent中,并将其添加到文档的第一页,即使这需要重新生成整个pdf。
Layer before: StackLayer
Layer before: Template-Page-2