PDF

Estampando archivos PDF al vuelo con la librería iTextPDF en Java.

Algunas empresas proporcionan documentos en formato PDF personalizados para los usuarios que lo solicitan, indicando normalmente el nombre y la fecha de servicio puesto que se trata habitualmente de documentos protegidos y proporcionados bajo suscripción.

En estos casos se suele tener un documento original en formato PDF preparado para servírselo al usuario a falta de poner esta información en el pie de página o en el costado, o simplemente una marca de agua.

En este post veremos cómo, a partir de un documento PDF de base se puede servir una copia personalizada con un texto en el costadillo y una marca de agua, utilizando la librería iTextPDF para la manipulación de ficheros PDF. Adicionalmente serviremos el fichero con algunas restricciones de seguridad.

En primer lugar deberemos tener el documento PDF de base que será servido al cliente bajo demanda. Este fichero se suele generar de un Word, una imagen escaneada, etcétera. En el caso de que tenga un password de acceso o edición, deberemos conocerlo para poder acceder a él.

La librería iTextPDF nos proporciona diferentes funcionalidades, desde la creación de un fichero en blanco hasta el estampado del fichero. Esta última opción es la que veremos. Los pasos son los siguientes:

  1. Apertura del fichero, usando la clave si procede.
  2. Creación del objeto para el estampado.
  3. Establecimiento de las opciones de encriptación de salida (si procede).
  4. Recorrido por todas y cada una de las páginas que tiene (en el caso de que queramos el estampado en todas ellas).
  5. Determinación de las dimensiones y rotación de la página, para poder poner el costadillo y la marca de agua centrada.
  6. Colocación de la marca de agua y el costadillo.
  7. Impresión final del fichero por el flujo de bytes de salida.

En este ejemplo se ha condensado todo en una función que lee los valores de un fichero .properties que se encuentra en el raíz del directorio src (para una aplicación en Tomcat), pero es fácilmente adaptable a otras necesidades.

Código fuente completo:


public static void estampaPDF(String fileNameOrigen, OutputStream outputStream) {
try {
     String archivo_entrada = fileNameOrigen;

     PdfReader pdfReader = new PdfReader(archivo_entrada);
     PdfStamper pdfStamper = new PdfStamper(pdfReader,outputStream);

     //Salida con clave de seguridad
     pdfStamper.setEncryption(null,"password".getBytes(),(PdfWriter.ALLOW_PRINTING|PdfWriter.ALLOW_COPY|PdfWriter.ALLOW_SCREENREADERS|PdfWriter.ALLOW_MODIFY_ANNOTATIONS|PdfWriter.ALLOW_FILL_IN), PdfWriter.STRENGTH128BITS);

     float alto_pagina = 0;
     float ancho_pagina = 0;
     float angulo_marca_agua=0;

     //Por cada una de las páginas
     for(int i=1; i<= pdfReader.getNumberOfPages(); i++){

          PdfContentByte content = pdfStamper.getOverContent(i);
          PdfContentByte content_fondo = pdfStamper.getUnderContent(i);

          //Comprobamos si la página está en vertical o en horizontal
          if((pdfReader.getPageRotation(i)==0)||(pdfReader.getPageRotation(i)==180))
          {
               alto_pagina = pdfReader.getPageSize(i).getHeight();
               ancho_pagina = pdfReader.getPageSize(i).getWidth();
               angulo_marca_agua = 60;
          }
          else //Si no es vertical, será apaisada
          {
               alto_pagina = pdfReader.getPageSize(i).getWidth();
               ancho_pagina = pdfReader.getPageSize(i).getHeight();
               angulo_marca_agua = 30;
          }

         //Costadillo
         String texto_costadillo = resourceBundle.getString("costadillo");

         //Marca de agua
         String marca_agua= resourceBundle.getString("marca_agua");


         Phrase frase = new Phrase(texto_costadillo, FontFactory.getFont(BaseFont.HELVETICA, 8));
         ColumnText.showTextAligned(content, Element.ALIGN_CENTER, frase, 30, alto_pagina/2, 90);

         //Marca de agua en color gris, rotada y con relleno blanco
         Phrase frase_marca_agua= new Phrase(marca_agua, FontFactory.getFont(BaseFont.HELVETICA, 85, Font.BOLD));
         content_fondo.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);
         content_fondo.setColorStroke(new BaseColor(0xD7,0xD7,0xD7));
         content_fondo.setColorFill(BaseColor.WHITE);

         ColumnText.showTextAligned(content_fondo, Element.ALIGN_CENTER, frase_marca_agua,ancho_pagina/2 , alto_pagina/2, angulo_marca_agua);

      }

      pdfStamper.close();

      } catch (IOException e) {
       log.severe(e.toString());
      } catch (DocumentException e) {

      log.severe(e.toString());
      }
 }

Anuncios