Вопрос по java, itext – iText: Как вставить фоновое изображение в тот же документ, чтобы получить ответ

4

Я создаю PDF и пишу поток в ответ. Прежде чем писать в потоке, я хочу добавить фоновое изображение в качестве водяного знака на всех страницах, чтобы документ PDF, промытый через ответ, был последним с водяным знаком.

Привет, это мой пример кода. Любая помощь будет очень ценной

private static String generatePDF(HttpServletRequest request, HttpServletResponse   response, String fileName) throws Exception
{
    Document document = null;
    PdfWriter writer = null;
    FileOutputStream fos = null;
    try
    {
       fos = new FileOutputStream(fileName);
       Document document = new Document(PageSize.A4);
       writer = PdfWriter.getInstance(document, fos);
       document.open();

       /**
        * Adding tables and cells and other stuff required
        **/

       return pdfFileName;
  } catch (Exception e) {
       FileUtil.deleteFile(fileName);
       throw e
  } finally {
    if (document != null) {
        document.close();
    }
    fos.flush();
  }
}

Теперь я хотел бы добавить фоновое изображение с помощью приведенного ниже кода и записать выходной PDF в тот же поток

PdfReader sourcePDFReader = null;
try
{
   sourcePDFReader = new PdfReader(sourcePdfFileName);
   int noOfPages = sourcePDFReader.getNumberOfPages();
   PdfStamper stamp = new PdfStamper(sourcePDFReader, new FileOutputStream(destPdfFileName));
   int i = 0;
   Image templateImage = Image.getInstance(templateImageFile);
   templateImage.setAbsolutePosition(0, 0);
   PdfContentByte tempalteBytes;
   while (i < noOfPages) {
       i++;
       tempalteBytes = stamp.getUnderContent(i);
       tempalteBytes.addImage(templateImage);
   }
   stamp.close();
   return destPdfFileName;
} catch (Exception ex) {
   LOGGER.log(Level.INFO, "Error when applying tempalte image as watermark");
} finally {
     if (sourcePDFReader != null) {
         sourcePDFReader.close();
     }
}
@ Subratnayak. Я решил это с помощью второго варианта Бруно. Пожалуйста, посмотрите на мой ответ ниже. John
@ Джон, я столкнулся с той же проблемой, можешь ли ты мне помочь? Subrat nayak.
Я .. сделал это. Спасибо John
Спасибо, что вернулись. John
Джон, также, пожалуйста, начните голосовать за все ответы (не только на ваши собственные вопросы), которые были полезны для вас. Подумайте над ответом Бруно уже за повышение (даже если оно еще не до вашего окончательного удовлетворения). Kurt Pfeifle

Ваш Ответ

3   ответа
11

Я решил это, используя первый (рекомендуемый) подход Бруно.

1) Создайте помощник события страницы сonEndPage событие:

class PDFBackground extends PdfPageEventHelper {

    @Override
    void onEndPage(PdfWriter writer, Document document) {
        Image background = Image.getInstance("myimage.png");
        // This scales the image to the page,
        // use the image's width & height if you don't want to scale.
        float width = document.getPageSize().getWidth();
        float height = document.getPageSize().getHeight();
        writer.getDirectContentUnder()
                .addImage(background, width, 0, 0, height, 0, 0);
    }

}

2) При создании вашего писателя зарегистрируйте свой помощник по событиям страницы:

PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
writer.setPageEvent(new PDFBackground());
4

Я решил это с помощью второго варианта Бруно. Вот код

public static String addBackgroundImageToPDF(ByteArrayOutputStream bos, String destPdfFileName, String templateImageFile)
{
  PdfReader sourcePDFReader = null;
  try
  {
        sourcePDFReader = new PdfReader(bos.toByteArray());
        int noOfPages = sourcePDFReader.getNumberOfPages();
        PdfStamper stamp = new PdfStamper(sourcePDFReader, new FileOutputStream(destPdfFileName));
        int i = 0;
        Image templateImage = Image.getInstance(templateImageFile);
        templateImage.setAbsolutePosition(0, 0);
        PdfContentByte tempalteBytes;
        while (i < noOfPages)
        {
              i++;
              tempalteBytes = stamp.getUnderContent(i);    
              tempalteBytes.addImage(templateImage);  
        }
         stamp.close();
        return destPdfFileName;
  }
  catch (Exception ex)
  {
        LOGGER.log(Level.INFO, "Error when applying template image as watermark");
  }
  finally
  {
        if (sourcePDFReader != null)
        {
              sourcePDFReader.close();
        }
  }
}
2

Вы можете выбрать один из двух вариантов:

Use the background image in a page event (to the 'under' content in the onEndPage() method)/ Create the first PDF in memory, then add the background image in a second pass using the code you posted.

Я предпочитаю вариант 1.

Благодарю. Не могли бы вы опубликовать пример кода для варианта 1 John
Пожалуйста, прочитайте документацию:itextpdf.com/book/chapter.php?id=5 а такжеitextpdf.com/themes/keyword.php?id=220

Похожие вопросы