Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iText : How do I insert background image in the same document to be flushed to response

Tags:

java

itext

I am creating a PDF and writing the stream in response. Before writing in the stream, I want to add a background image as watermark in all the pages so that PDF document flushed through response is the final one with watermark.

Hi this is my code sample. Any help would be much appriciated

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();
  }
}

I now would like to add a background image using the below code and write the output PDF to the same stream

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();
     }
}
like image 417
John Avatar asked Oct 01 '12 16:10

John


3 Answers

I solved this using Bruno's first (recommended) approach.

1) Create a page event helper with an onEndPage event:

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) When creating your writer, register your page event helper:

PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
writer.setPageEvent(new PDFBackground());
like image 172
Sean Connolly Avatar answered Sep 28 '22 09:09

Sean Connolly


I have solved this with Bruno's second option. Here is the code.

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();
        }
  }
}
like image 37
John Avatar answered Sep 28 '22 10:09

John


You can choose between two options:

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

I prefer option 1.

like image 20
Bruno Lowagie Avatar answered Sep 28 '22 11:09

Bruno Lowagie