app.logica.gestores.GestorPDF.java Source code

Java tutorial

Introduction

Here is the source code for app.logica.gestores.GestorPDF.java

Source

 /**
  * Copyright (C) 2016 Fernando Berti - Daniel Campodonico - Emiliano Gioria - Lucas Moretti - Esteban Rebechi - Andres Leonel Rico
  * This file is part of Olimpo.
  *
  * Olimpo is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * Olimpo is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with Olimpo. If not, see <http://www.gnu.org/licenses/>.
  */
 package app.logica.gestores;

 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.concurrent.FutureTask;

 import javax.annotation.Resource;
 import javax.imageio.ImageIO;

 import org.springframework.stereotype.Service;

 import com.itextpdf.text.Document;
 import com.itextpdf.text.Image;
 import com.itextpdf.text.PageSize;
 import com.itextpdf.text.pdf.PdfWriter;

 import app.comun.ConversorFechas;
 import app.comun.FormateadorString;
 import app.datos.clases.CatalogoVista;
 import app.datos.entidades.Inmueble;
 import app.datos.entidades.PDF;
 import app.datos.entidades.Reserva;
 import app.datos.entidades.Venta;
 import app.excepciones.GenerarPDFException;
 import app.excepciones.GestionException;
 import javafx.application.Platform;
 import javafx.embed.swing.SwingFXUtils;
 import javafx.fxml.FXMLLoader;
 import javafx.scene.Node;
 import javafx.scene.Parent;
 import javafx.scene.Scene;
 import javafx.scene.SnapshotParameters;
 import javafx.scene.control.Label;
 import javafx.scene.image.ImageView;
 import javafx.scene.image.WritableImage;
 import javafx.scene.layout.GridPane;
 import javafx.scene.layout.Pane;

 @Service
 /**
  * Gestor que implementa la generacin de PDFs a partir de un objeto dado.
  */
 public class GestorPDF {

     @Resource
     protected FormateadorString formateador;

     @Resource
     protected ConversorFechas conversorFechas;

     private PDF pdf;

     private static final String URLDocumentoReserva = "/res/pdf/documentoReserva.fxml";

     private static final String URLDocumentoVenta = "/res/pdf/documentoVenta.fxml";

     private static final String URLCatalogo = "/res/pdf/catalogoA4.fxml";

     private static final String URLFilaCatalogo = "/res/pdf/filaCatalogoA4.fxml";

     /**
      * Mtodo para crear un PDF a partir de una pantalla.
      *
      * @param pantallaAPDF
      *            pantalla que se imprimir en PDF
      * @return PDF de una captura de la pantalla pasada
      */
     private PDF generarPDF(Node pantallaAPDF) throws Exception {
         //Se imprime la pantalla en una imagen
         new Scene((Parent) pantallaAPDF);
         WritableImage image = pantallaAPDF.snapshot(new SnapshotParameters(), null);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", baos);
         byte[] imageInByte = baos.toByteArray();
         baos.flush();
         baos.close();

         //Se carga la imagen en un PDF
         Image imagen = Image.getInstance(imageInByte);
         Document document = new Document();
         ByteArrayOutputStream pdfbaos = new ByteArrayOutputStream();
         PdfWriter escritor = PdfWriter.getInstance(document, pdfbaos);
         document.open();
         imagen.setAbsolutePosition(0, 0);
         imagen.scaleToFit(PageSize.A4.getWidth(), PageSize.A4.getHeight());
         document.add(imagen);
         document.close();

         //Se obtiene el archivo PDF
         byte[] pdfBytes = pdfbaos.toByteArray();
         pdfbaos.flush();
         escritor.close();
         pdfbaos.close();

         //Se genera un objeto PDF
         return (PDF) new PDF().setArchivo(pdfBytes);
     }

     /**
      * Mtodo para crear un PDF a partir de varias pantalla.
      *
      * @param pantallaAPDF
      *            pantalla que se imprimir en PDF
      * @return PDF de una captura de la pantalla pasada
      */
     private PDF generarPDF(ArrayList<Node> pantallasAPDF) throws Exception {
         Document document = new Document();
         ByteArrayOutputStream pdfbaos = new ByteArrayOutputStream();
         PdfWriter escritor = PdfWriter.getInstance(document, pdfbaos);
         document.open();

         for (Node pantalla : pantallasAPDF) {
             new Scene((Parent) pantalla);
             WritableImage image = pantalla.snapshot(new SnapshotParameters(), null);
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", baos);
             byte[] imageInByte = baos.toByteArray();
             baos.flush();
             baos.close();
             Image imagen = Image.getInstance(imageInByte);
             imagen.setAbsolutePosition(0, 0);
             imagen.scaleToFit(PageSize.A4.getWidth(), PageSize.A4.getHeight());
             document.add(imagen);
             document.newPage();
         }

         document.close();

         byte[] pdfBytes = pdfbaos.toByteArray();
         pdfbaos.flush();
         escritor.close();
         pdfbaos.close();
         return (PDF) new PDF().setArchivo(pdfBytes);
     }

/**
 * Mtodo para crear un PDF de un catalogo a partir de los datos de un CatalogoVista.
 * Pertenece a la taskcard 23 de la iteracin 2 y a la historia 5
 *
 * @param catalogo
 *            datos que se utilizaran para generar el PDF de un catlogo
 * @return catalogo en PDF
 */
public PDF generarPDF(CatalogoVista catalogo) throws GestionException {
   pdf = null;
   Integer numeroInmuebles = catalogo.getFotos().size();
   ArrayList<Node> paginas = new ArrayList<>();
   Integer numeroTotalDePaginas = (numeroInmuebles + 2) / 3;
   Date fechaHoy = new Date();

   ArrayList<Inmueble> inmuebles = new ArrayList<>();
   catalogo.getFotos().forEach((i, f) -> {
      inmuebles.add(i);
   });

   try{
      FutureTask<Throwable> future = new FutureTask<>(() -> {
         try{
            Integer inmueblesProcesados = 0;
            for(int numeroPagina = 1; numeroPagina <= numeroTotalDePaginas; numeroPagina++){
               FXMLLoader loader = new FXMLLoader();
               loader.setLocation(getClass().getResource(URLCatalogo));
               Pane paginaCatalogo = (Pane) loader.load();

               Label label = (Label) paginaCatalogo.lookup("#labelFechaEmision");
               label.setText(formateador.nombrePropio(conversorFechas.diaMesYAnioToString(fechaHoy)));
               label = (Label) paginaCatalogo.lookup("#labelNumeroPagina");
               label.setText(numeroPagina + " de " + numeroTotalDePaginas);

               for(int i = 0; i < 3 && inmueblesProcesados < numeroInmuebles; i++, inmueblesProcesados++){
                  FXMLLoader loaderFila = new FXMLLoader();
                  loaderFila.setLocation(getClass().getResource(URLFilaCatalogo));
                  Pane fila = (Pane) loaderFila.load();
                  Inmueble inmueble = inmuebles.get(inmueblesProcesados);
                  if(catalogo.getFotos().get(inmueble) != null){
                     File imagenTMP = new File("imagen_tmp.png");
                     FileOutputStream fos = new FileOutputStream(imagenTMP);
                     fos.write(catalogo.getFotos().get(inmueble).getArchivo());
                     fos.flush();
                     fos.close();

                     ImageView imagen = (ImageView) fila.lookup("#imageFoto");
                     imagen.setImage(new javafx.scene.image.Image(imagenTMP.toURI().toString()));
                  }

                  label = (Label) fila.lookup("#labelCodigo");
                  label.setText("Inmueble N " + inmueble.getId());

                  label = (Label) fila.lookup("#labelTipoInmueble");
                  label.setText(inmueble.getTipo().toString());

                  label = (Label) fila.lookup("#labelPais");
                  label.setText(formateador.nombrePropio(inmueble.getDireccion().getLocalidad().getProvincia().getPais().toString()));

                  label = (Label) fila.lookup("#labelProvincia");
                  label.setText(formateador.nombrePropio(inmueble.getDireccion().getLocalidad().getProvincia().toString()));

                  label = (Label) fila.lookup("#labelLocalidad");
                  label.setText(formateador.nombrePropio(inmueble.getDireccion().getLocalidad().toString()));

                  label = (Label) fila.lookup("#labelBarrio");
                  label.setText(formateador.nombrePropio(inmueble.getDireccion().getBarrio().toString()));

                  StringBuilder direccion = new StringBuilder("");
                  direccion.append(inmueble.getDireccion().getCalle());
                  direccion.append(" ");
                  direccion.append(inmueble.getDireccion().getNumero());

                  if(inmueble.getDireccion().getPiso() != null){
                     direccion.append(" - Piso ");
                     direccion.append(inmueble.getDireccion().getPiso());
                  }
                  if(inmueble.getDireccion().getDepartamento() != null){
                     direccion.append(" - Dpto. ");
                     direccion.append(inmueble.getDireccion().getDepartamento());
                  }
                  if(inmueble.getDireccion().getOtros() != null){
                     direccion.append(" - ");
                     direccion.append(inmueble.getDireccion().getOtros());
                  }
                  label = (Label) fila.lookup("#labelDireccion");
                  label.setText(formateador.nombrePropio(direccion.toString()));

                  label = (Label) fila.lookup("#labelDormitorios");
                  if(inmueble.getDatosEdificio().getDormitorios() != null){
                     label.setText(inmueble.getDatosEdificio().getDormitorios().toString());
                  }
                  else{
                     label.setText("-");
                  }

                  label = (Label) fila.lookup("#labelBaos");
                  if(inmueble.getDatosEdificio().getBaos() != null){
                     label.setText(inmueble.getDatosEdificio().getBaos().toString());
                  }
                  else{
                     label.setText("-");
                  }

                  label = (Label) fila.lookup("#labelGaraje");
                  if(inmueble.getDatosEdificio().getGaraje() != null){
                     label.setText(inmueble.getDatosEdificio().getGaraje() ? "SI" : "NO");
                  }
                  else{
                     label.setText("-");
                  }

                  label = (Label) fila.lookup("#labelPatio");
                  if(inmueble.getDatosEdificio().getPatio() != null){
                     label.setText(inmueble.getDatosEdificio().getPatio() ? "SI" : "NO");
                  }
                  else{
                     label.setText("-");
                  }

                  label = (Label) fila.lookup("#labelSuperficieTerreno");
                  if(inmueble.getSuperficie() != null){
                     label.setText(inmueble.getSuperficie() + " metros cuadrados.");
                  }
                  else{
                     label.setText("-");
                  }

                  label = (Label) fila.lookup("#labelSuperficieEdificada");
                  if(inmueble.getDatosEdificio().getSuperficie() != null){
                     label.setText(inmueble.getDatosEdificio().getSuperficie() + " metros cuadrados.");
                  }
                  else{
                     label.setText("-");
                  }

                  label = (Label) fila.lookup("#labelPrecio");
                  DecimalFormat formateadorDouble = new DecimalFormat("#.00");
                  label.setText(formateadorDouble.format(inmueble.getPrecio()) + " USD");

                  GridPane gridPaneFilas = (GridPane) paginaCatalogo.lookup("#gridPaneFilas");
                  gridPaneFilas.add(fila, 0, i);
               }
               paginas.add(paginaCatalogo);
            }
            pdf = generarPDF(paginas);
         } catch(Throwable e){
            return e;
         }
         return null;
      });

      if(!Platform.isFxApplicationThread()){
         Platform.runLater(future);
      }
      else{
         future.run();
      }
      Throwable excepcion = future.get();
      if(excepcion != null){
         throw excepcion;
      }
      if(pdf == null){
         throw new NullPointerException("Error al generar PDF");
      }

   } catch(Throwable e){
      e.printStackTrace();
      throw new GenerarPDFException(e);
   }

   return pdf;
}

     /**
      * Mtodo para crear un PDF de una reserva a partir de los datos de una ReservaVista.
      * Pertenece a la taskcard 25 de la iteracin 2 y a la historia 7
      *
      * @param reserva
      *            datos que se utilizaran para generar el PDF de una reserva
      * @return reserva en PDF
      */
     public PDF generarPDF(Reserva reserva) throws GestionException {
         try {
             //Inicializacin de parmetros
             pdf = null;

             //Cargar pantalla que representa al PDF
             FXMLLoader loader = new FXMLLoader();
             loader.setLocation(getClass().getResource(URLDocumentoReserva));
             Pane documentoReserva = (Pane) loader.load();

             FutureTask<Throwable> future = new FutureTask<>(() -> {
                 try {
                     //Cargar datos a la pantalla que representa al PDF
                     Label label = (Label) documentoReserva.lookup("#lblNombreOferente");
                     label.setText(formateador.nombrePropio(reserva.getCliente().getNombre()));
                     label = (Label) documentoReserva.lookup("#lblApellidoOferente");
                     label.setText(formateador.nombrePropio(reserva.getCliente().getApellido()));
                     label = (Label) documentoReserva.lookup("#lblDocumentoOferente");
                     label.setText(reserva.getCliente().getTipoDocumento() + " - "
                             + reserva.getCliente().getNumeroDocumento());
                     label = (Label) documentoReserva.lookup("#lblNombrePropietario");
                     label.setText(formateador.nombrePropio(reserva.getInmueble().getPropietario().getNombre()));
                     label = (Label) documentoReserva.lookup("#lblApellidoPropietario");
                     label.setText(formateador.nombrePropio(reserva.getInmueble().getPropietario().getApellido()));
                     label = (Label) documentoReserva.lookup("#lblCodigoInmueble");
                     label.setText(Integer.toString(reserva.getInmueble().getId()));
                     label = (Label) documentoReserva.lookup("#lblTipoInmueble");
                     label.setText(reserva.getInmueble().getTipo().getTipo().toString());
                     label = (Label) documentoReserva.lookup("#lblLocalidadInmueble");
                     label.setText(reserva.getInmueble().getDireccion().getLocalidad().toString());
                     label = (Label) documentoReserva.lookup("#lblBarrioInmueble");
                     label.setText(reserva.getInmueble().getDireccion().getBarrio().toString());
                     label = (Label) documentoReserva.lookup("#lblCalleInmueble");
                     label.setText(reserva.getInmueble().getDireccion().getCalle().toString());
                     label = (Label) documentoReserva.lookup("#lblAlturaInmueble");
                     label.setText(reserva.getInmueble().getDireccion().getNumero());
                     label = (Label) documentoReserva.lookup("#lblPisoInmueble");
                     label.setText(reserva.getInmueble().getDireccion().getPiso());
                     label = (Label) documentoReserva.lookup("#lblDepartamentoInmueble");
                     label.setText(reserva.getInmueble().getDireccion().getDepartamento());
                     label = (Label) documentoReserva.lookup("#lblOtrosInmueble");
                     label.setText(reserva.getInmueble().getDireccion().getOtros());
                     label = (Label) documentoReserva.lookup("#lblImporte");
                     label.setText(String.format("$ %10.2f", reserva.getImporte()));
                     label = (Label) documentoReserva.lookup("#lblFechaRealizacion");
                     label.setText(conversorFechas.diaMesYAnioToString(reserva.getFechaInicio()));
                     label = (Label) documentoReserva.lookup("#lblFechaVencimiento");
                     label.setText(conversorFechas.diaMesYAnioToString(reserva.getFechaFin()));
                     label = (Label) documentoReserva.lookup("#lblHoraGenerado");
                     Date ahora = new Date();
                     label.setText(String.format(label.getText(), conversorFechas.horaYMinutosToString(ahora),
                             conversorFechas.diaMesYAnioToString(ahora)));

                     //Generacin del archivo
                     pdf = generarPDF(documentoReserva);
                 } catch (Throwable e) {
                     return e;
                 }
                 return null;
             });

             //Asegurarse de que lo anterior se corra en el hilo de javaFX
             if (!Platform.isFxApplicationThread()) {
                 Platform.runLater(future);
             } else {
                 future.run();
             }

             //Si hubo error se lanza excepcin
             Throwable excepcion = future.get();
             if (excepcion != null) {
                 throw excepcion;
             }
             if (pdf == null) {
                 throw new NullPointerException("Error al generar PDF");
             }
         } catch (Throwable e) {
             throw new GenerarPDFException(e);
         }

         return pdf;
     }

     /**
      * Mtodo para crear un PDF de una venta a partir de los datos de una Venta.
      * Pertenece a la taskcard 30 de la iteracin 2 y a la historia 8
      *
      * @param venta
      *            datos que se utilizaran para generar el PDF de una venta
      * @return venta en PDF
      */
     public PDF generarPDF(Venta venta) throws GestionException {
         try {
             //se carga el fxml
             pdf = null;
             FXMLLoader loader = new FXMLLoader();
             loader.setLocation(getClass().getResource(URLDocumentoVenta));
             Pane documentoVenta = (Pane) loader.load();

             FutureTask<Throwable> future = new FutureTask<>(() -> {
                 try {
                     //se setean los campos del documento con los datos de la venta
                     Label label = (Label) documentoVenta.lookup("#lblNombreComprador");
                     label.setText(formateador.nombrePropio(venta.getCliente().getNombre()));
                     label = (Label) documentoVenta.lookup("#lblApellidoComprador");
                     label.setText(formateador.nombrePropio(venta.getCliente().getApellido()));
                     label = (Label) documentoVenta.lookup("#lblDocumentoComprador");
                     label.setText(venta.getCliente().getTipoDocumento() + " - "
                             + venta.getCliente().getNumeroDocumento());
                     label = (Label) documentoVenta.lookup("#lblNombrePropietario");
                     label.setText(formateador.nombrePropio(venta.getInmueble().getPropietario().getNombre()));
                     label = (Label) documentoVenta.lookup("#lblApellidoPropietario");
                     label.setText(formateador.nombrePropio(venta.getInmueble().getPropietario().getApellido()));
                     label = (Label) documentoVenta.lookup("#lblDocumentoPropietario");
                     label.setText(venta.getPropietario().getTipoDocumento() + " - "
                             + venta.getPropietario().getNumeroDocumento());
                     label = (Label) documentoVenta.lookup("#lblCodigoInmueble");
                     label.setText(Integer.toString(venta.getInmueble().getId()));
                     label = (Label) documentoVenta.lookup("#lblTipoInmueble");
                     label.setText(venta.getInmueble().getTipo().getTipo().toString());
                     label = (Label) documentoVenta.lookup("#lblLocalidadInmueble");
                     label.setText(venta.getInmueble().getDireccion().getLocalidad().toString());
                     label = (Label) documentoVenta.lookup("#lblBarrioInmueble");
                     label.setText(venta.getInmueble().getDireccion().getBarrio().toString());
                     label = (Label) documentoVenta.lookup("#lblCalleInmueble");
                     label.setText(venta.getInmueble().getDireccion().getCalle().toString());
                     label = (Label) documentoVenta.lookup("#lblAlturaInmueble");
                     label.setText(venta.getInmueble().getDireccion().getNumero());
                     label = (Label) documentoVenta.lookup("#lblPisoInmueble");
                     label.setText(venta.getInmueble().getDireccion().getPiso());
                     label = (Label) documentoVenta.lookup("#lblDepartamentoInmueble");
                     label.setText(venta.getInmueble().getDireccion().getDepartamento());
                     label = (Label) documentoVenta.lookup("#lblOtrosInmueble");
                     label.setText(venta.getInmueble().getDireccion().getOtros());
                     label = (Label) documentoVenta.lookup("#lblImporte");
                     label.setText(String.format("$ %10.2f", venta.getImporte()));
                     label = (Label) documentoVenta.lookup("#lblMedioDePago");
                     label.setText(venta.getMedioDePago());
                     label = (Label) documentoVenta.lookup("#lblFechaVenta");
                     label.setText(conversorFechas.diaMesYAnioToString(venta.getFecha()));
                     label = (Label) documentoVenta.lookup("#lblHoraGenerado");
                     Date ahora = new Date();
                     label.setText(String.format(label.getText(), conversorFechas.horaYMinutosToString(ahora),
                             conversorFechas.diaMesYAnioToString(ahora)));

                     //genera el archivo
                     pdf = generarPDF(documentoVenta);
                 } catch (Throwable e) {
                     return e; //si algo falla
                 }
                 return null; //si no falla nada
             });

             //se asegura de que se corra en el hilo de javaFX
             if (!Platform.isFxApplicationThread()) {
                 Platform.runLater(future);
             } else {
                 future.run();
             }
             Throwable excepcion = future.get();

             //si hubo error se lanza excepcin
             if (excepcion != null) {
                 throw excepcion;
             }
             if (pdf == null) {
                 throw new NullPointerException("Error al generar PDF");
             }
         } catch (Throwable e) {
             throw new GenerarPDFException(e);
         }

         return pdf;
     }
 }