Sellando ficheros PDF – PDF Stamping

Hola, con este post comienzo lo que espero sea una provechosa lista de tips & tricks para usar en nuestros desarrollos del día a día. Después de una temporada desarrollando Java EE he acumulado unos cuantos scripts, tutoriales, algoritmos y demás que guardo en una carpeta que me gusta llamar «como oro en paño».

Me ha parecido buena idea comenzar por una de las más recientes incorporaciones a mi colección, con la que conseguiremos algo como esto:

Resultado-01

Con esta utilidad trato de simplificar la tarea de añadir un sello la los ficheros PDF que genera nuestra aplicación. Con esta utilidad podremos crear un sello con varias líneas de texto, personalizando:

  • El tipo de fuente
  • El tamaño del texto para cada línea
  • El ancho del sello
  • El ángulo de giro del sello
  • El grado de transparencia del sello
  • Podremos hacer que el fichero quede protegido contra modificaciones

En esta ocasión he preferido incluir sólo texto, sin ningún gráfico.

Comienzo con lo interesante…

El punto de partida.

Como entrada para generar el sello le podremos proporcionar a esta utilidad varios tipos de input

  • java.io.InputStream
  • java.io.File
  • byte []

Al final nuestra utilidad se basará siempre en el uso de InputStream, por lo que a la hora de realizar la invocación no será necesario que guardéis vuestro documento en disco o en memoria, podéis, por ejemplo, dar directamente el InputStream que esta conectado con un campo de tipo Blob de vuestra base de datos.

El destino.

Como destino para la generación del archivo PDF sellado proporcionaremos un objeto java.io.OutputStream buscando la máxima eficiencia, ya que será habitual que  queramos descargar el documento con el sello.

También he provisto un método que devuelve un java.io.InputStream para hacer luego otros tratamientos o guardar el documento en una base de datos, pero implicaría que la utilidad debe reservar el espacio temporal sobre el que se genera el nuevo archivo, y para esto siempre hay dos opciones, disco y memoria, cada uno con sus pros y contras, pero creo que esto lo dejaremos para otro post, así que para esta ocasión he optado por usar disco para esa tarea.

Las opciones.

He considerado oportuno dotar a la utilidad de las siguientes opciones, añadiéndolas como parámetros al constructor

  • width. Ancho de la tabla que contendrá nuestro sello
  • fillOpacity. Grado de opacidad del texto, valores entre cero y 1
  • strokeOpacity. Otro grado de opacidad del trazo, supongo que para los gráficos, no he prestado mucha atención a este parámetro 🙂
  • stampColor. Color del sello, de la clase java.awt.Color
  • fontFamily. Una constante de la clase com.lowagie.text.Font
  • secure. Indica si queremos que el PDF generado esté protegido, en caso de ser true, sólo se permitirá la impresión.

El estampado.

Para el estampado proporcionaremos los textos, el tamaño para cada uno, el PDF original y el java.io.OutputStream para el resultado, y de forma opcional el rango de páginas a estampar.

También es posible indicar un ángulo de inclinación para el sello, el valor deberá estar entre 0 y 90 grados (la utilidad hace la conversión a radianes) para que salga bien, podéis probar otros valores y ver lo que pasa.

Aquí os dejo algo de código, más en github: https://github.com/jotraverso/pdf-stamper

	/**
	 * Stamp.
	 *
	 * @param texts
	 *            the texts
	 * @param fontSizes
	 *            the font sizes
	 * @param pdf
	 *            the pdf
	 * @param result
	 *            the result
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 * @throws DocumentException
	 *             the document exception
	 */
	public void stamp(final String[] texts, final float[] fontSizes, final InputStream pdf, final OutputStream result) throws IOException,
			DocumentException {
		stampPages(texts, fontSizes, 1, 1, 0, pdf, result);
	}

	/**
	 * Stamp pages.
	 *
	 * @param texts
	 *            the texts
	 * @param fontSizes
	 *            the font sizes
	 * @param startPage
	 *            the start page
	 * @param endPage
	 *            the end page, a number less than 0 for all pages.
	 * @param degrees
	 *            rotation, between 0 and 90.
	 * @param pdf
	 *            the pdf
	 * @param result
	 *            the result
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 * @throws DocumentException
	 *             the document exception
	 */
	public void stampPages(final String[] texts, final float[] fontSizes, final int startPage, final int endPage, float degrees,
			final InputStream pdf, final OutputStream result) throws IOException, DocumentException {
		PdfReader reader = new PdfReader(pdf);
		int end = endPage;
		if (end < 0 || end > reader.getNumberOfPages()) {
			end = reader.getNumberOfPages();
		}

		PdfStamper stamper = new PdfStamper(reader, result);
		if (secured) {
                //...
		}
                // The magic continues 🙂
	}

	/**
	 * Main method.
	 *
	 * @param args
	 *            no arguments needed
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 * @throws DocumentException
	 *             the document exception
	 * @throws SQLException
	 *             the sQL exception
	 */
	public static void main(final String[] args) throws IOException, DocumentException, SQLException {
		SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy");
		String fecha = sdf.format(new Date()).toUpperCase();
		String[] textos = new String[] { "INSERVIBLE", fecha };
		float[] sizes = new float[] { 32, 22 };
		Stamper stamper = new Stamper(350, 0.85f, 0.90f, Color.blue, Font.COURIER, true);
		stamper.stampPages(textos, sizes, 1,1, 25,new URL(ORIGINAL).openStream(), new FileOutputStream("azul-" + RESULT));
		System.out.println("Archivos generados!!");
	}

Código fuente

https://github.com/jotraverso/pdf-stamper 

Referencias

Ejemplo de iText sobre transparencia. http://itextpdf.com/examples/iia.php?id=181

Deja un comentario