2014-10-27 2 views
2

Я добавляю водяные знаки на существующий PDF, используя класс iText PdfStamper. И я хочу, чтобы эти водяные знаки были включены или выключены, поэтому я использую класс PdfLayer.
Но я также хочу, чтобы эти водяные знаки всегда были видны при печати файла: тогда я использую функцию PdfLayer.setPrint(). Это последний шаг, который, к сожалению, не работает должным образом.Как сделать PdfLayer.SetPrint работать с PdfStamper?

Вот мой код:

PdfReader reader = new PdfReader("C:/Temp/input.pdf"); 
PdfStamper stamp = new PdfStamper(reader, new FileOutputStream("C:/Temp/output.pdf")); 
PdfWriter writer = stamp.getWriter(); 
PdfLayer layer = new PdfLayer("Watermarks", writer); 
layer.setOn(true); 
layer.setPrint("Watermarks", true); 
BaseFont bf = BaseFont.createFont(); 
PdfContentByte cb = stamp.getOverContent(1); 
cb.beginText(); 
cb.setFontAndSize(bf, 18); 
cb.beginLayer(layer); 
cb.showTextAligned(Element.ALIGN_LEFT, "Watermark line 1", 50, 55, 0); 
cb.showTextAligned(Element.ALIGN_LEFT, "Watermark line 2", 50, 40, 0); 
cb.endLayer(); 
cb.endText(); 
stamp.close(); 
reader.close(); 

Когда я проверяю свойства слоя из Adobe Reader (версия 10), я вижу, что «Начальное состояние: Print» свойство остается в «Отпечатки Когда Visible» в то время как он должен «Всегда печатать».

Я также попытался создать слои на новом документе PDF и там работает setPrint().

Что я делаю неправильно?

ответ

0

У меня такая же проблема. В качестве обходного пути вы можете использовать new Document и getImportedPage вместо pdfStamper. К сожалению, вы теряете гиперссылку, потому что все страницы преобразуются в изображения. Я пытался использовать PdfCopy, но я воспроизвел ту же проблему. Меня действительно интересует решение, позволяющее добавить водяной знак без изменения исходного файла. Раствор для деградированного образца:

 PdfReader pdfReaderS = new PdfReader(filepathS); 
    Document document = new Document(pdfReaderS.getPageSizeWithRotation(1)); 
    PdfWriter pdfWriterD = PdfWriter.getInstance(document, new FileOutputStream(filepathD)); 
    document.open(); 
    PdfContentByte pdfContentByteD = pdfWriterD.getDirectContent(); 

    BaseFont baseFont = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED); 

    int n = pdfReaderS.getNumberOfPages(); 

    PdfLayer pdfLayer = new PdfLayer("Watermark", pdfWriterD); 
    pdfLayer.setPrint("Print", true); 
    pdfLayer.setView(visibleScreen); 

    for (int i = 1; i <= n; i++) {     
     Rectangle pageSizeS =pdfReaderS.getPageSizeWithRotation(i); 
     float pageWidth = pageSizeS.getWidth()/2; 
     float pageheight = pageSizeS.getHeight()/2; 
     float degree = (float)(Math.toDegrees(Math.atan(pageSizeS.getHeight()/pageSizeS.getWidth()))); 

     document.setPageSize(pageSizeS); 
     document.newPage(); 
     PdfImportedPage pdfImportedPage = pdfWriterD.getImportedPage(pdfReaderS, i); 
     int rotation = pdfReaderS.getPageRotation(i); //This value can be 0, 90, 180 or 270. 

     if (rotation == 0) 
      pdfContentByteD.addTemplate(page, 1, 0, 0, 1, 0, 0); 
     else if (rotation == 90) 
      pdfContentByteD.addTemplate(page, 0, -1, 1, 0, 0, pageSizeS.getHeight()); 
     else if (rotation == 180) 
      pdfContentByteD.addTemplate(page, -1, 0, 0, -1, pageSizeS.getHeight(), pageSizeS.getWidth()); 
     else if (rotation == 270) 
      pdfContentByteD.addTemplate(page, 0, 1, -1, 0, pageSizeS.getWidth(), 0);   

     pdfContentByteD.beginLayer(pdfLayer); 
     pdfContentByteD.beginText(); 
     pdfContentByteD.setFontAndSize(baseFont, policeSize); 
     pdfContentByteD.setColorFill(col); 
     pdfContentByteD.showTextAligned(PdfContentByte.ALIGN_CENTER, text, pageWidth, pageheight, degree); 
     pdfContentByteD.endText(); 
     pdfContentByteD.endLayer(); 
    } 
    document.close(); 
    pdfReaderS.close(); 
+1

Этого решения достаточно для меня, спасибо. Во всяком случае, мне пришлось немного адаптировать ваш код для вращения: 'if (r == 0) content.addTemplate (страница, 1, 0, 0, 1, 0, 0); else if (r == 90) \t content.addTemplate (страница, 0, -1, 1, 0, 0, pageSizeS.getHeight()); else if (r == 180) content.addTemplate (страница, -1, 0, 0, -1, pageSizeS.getHeight(), pageSizeS.getWidth()); else if (r == 270) content.addTemplate (страница, 0, 1, -1, 0, pageSizeS.getWidth(), 0); ' –

1

У меня такая же проблема. Мой код хочет добавить изображение как водяной знак на каждую страницу оригинального pdf. И водяной знак можно просматривать только, а не печатать. Я использую PdfStamper и PdfLayer.setPrint() тоже. Но это не сработало. Я прочитал исходный источник java и нашел способ заставить его работать. Вот код:

PdfWriter writer = stamp.getWriter(); 
PdfLayer layer = new PdfLayer("Watermarks", writer); 
layer.setOn(true); 
layer.setOnPanel(false); 
layer.setPrint("watermark", false); 
writer.addToBody(layer.getPdfObject(), layer.getRef()); 

Это называют addToBody после setPrint. Это хорошо работает.

+0

Я использую iText 5. Я не знаю, является ли это ошибкой. Я читаю iText 7 java source, я думаю, что это не проблема для setPrint, работающего в itext 7. – ttqq

Смежные вопросы