En esta ocasión presentare como exportar datos desde nuestra aplicación creada con ADF Business Components a un archivo PDF, tradicionalmente se usas Jasper reports para obtener reportes en pdf e inclusive me han recomendado usar BI-publisher para la obtención de reportes (estas son librerías licenciadas).
Pero trabajando con jdeveloper haciendo uso de ADF se ha presentado la tarea de exportar a PDF los datos que obtenga desde el Aplication Module, la tarea será crear un archivo pdf que muestre los datos de una persona junto con su foto, lo interesante es que dichos datos y foto están almacenados en una base de datos.
Antecedentes: Los datos se obtienen de una base de datos oracle, la tabla RHU_TAB_PERSONAS contiene los registros correspondientes a las persona, en esta tabla existe un campo FOTO de tipo BLOB que almacena la imagen de la persona.
Creando la Aplicación
Primero creamos una aplicación de tipo Fusion Web Aplication, esto generará dos proyectos el primero el Modelo y el segundo la Vista y Controlador.
En el Proyecto Modelo, creamos el Business Components referente a la tabla RHU_TAB_PERSONAS. (Para crear BC debes hacer clic derecho en el proyecto Modelo y seleccionas la opción New o Nuevo de la ventana seleccionas Business Components y continúas con el asistente)

Reescribiendo el QUERY del ViewObject
Para simular el proceso de login dentro de la aplicación vamos a crear una Bind Variable dentro de la View Object de las Personas, para ello nos ubicamos en la sección Query del ViewObject y editamos el query de la siguiente manera:
SELECT RhuTabPersonasEO.CEDULA, RhuTabPersonasEO.LUGAR_NACIMIENTO,
RhuTabPersonasEO.LUGAR_RESIDENCIA, RhuTabPersonasEO.NACIONALIDAD,
RhuTabPersonasEO.LUGAR_PROCEDENCIA, RhuTabPersonasEO.TIPO_IDENTIFICACION,
RhuTabPersonasEO.PRIMER_NOMBRE, RhuTabPersonasEO.PRIMER_APELLIDO,
RhuTabPersonasEO.DIRECCION, RhuTabPersonasEO.FECHA_NACIMIENTO,
RhuTabPersonasEO.GENERO, RhuTabPersonasEO.ESTADO_CIVIL,
RhuTabPersonasEO.ESTADO, RhuTabPersonasEO.SEGUNDO_NOMBRE,
RhuTabPersonasEO.SEGUNDO_APELLIDO, RhuTabPersonasEO.TIPO_SANGRE,
RhuTabPersonasEO.LIBRETA_MILITAR, RhuTabPersonasEO.EMAIL,
RhuTabPersonasEO.TELEFONO, RhuTabPersonasEO.CELULAR,
RhuTabPersonasEO.FOTOFROM RHU_TAB_PERSONAS RhuTabPersonasEO
WHERE RhuTabPersonasEO.CEDULA = :VARCEDULA
No olviden definir la variable VARCEDULA tal como se muestra a continuación:

Agregando View Objects al Aplication Module
Agregamos la View Object al Data Model para que se pueda usar desde el proyecto VistaControlador para ello nos ubicamos en la sección Data Model del Aplication Module y pasamos la ViewObject de la sección “Available View Objects” al Data Model (Se ha definido como CandidatoVO el nombre de la instancia del ViewObject aunque se puede definir cualquier nombre):

Controlador
Creamos 2 páginas una llamada login y otra llamada Curriculum

En la primera creamos un formulario a través de la operación ExecuteWithParams

En la página Curriculum.jspx creamos un formulario de lectura haciendo uso del Data Control.

Una vez creado el formulario agregamos el control:
<af:commandImageLink text="Descargar a PDF"
icon="/images/doc_pdf.png">
<af:fileDownloadActionListener contentType="application/pdf"
filename="curriculum.pdf"
method="#{DownloadBean.downloadCVtoPdf}"/>
</af:commandImageLink>
La propiedad method apunta a una clase java que tiene el metodo downloadCVtoPdf es justamente este método el que va hacer uso del Aplication module y creara un pdf para descargar.
La pagina Curriculum tendrá el siguiente aspecto:

Incluyendo las Librerías
Debemos incluir una librería muy completa llamada Itext (http://itextpdf.com/) dentro de nuestro proyecto ViewController para ello debemos copiar el archivo itext-2.0.6 dentro de la carpeta \public_html\WEB-INF\lib. Hacemos clic en las propiedades del proyecto ViewController, nos ubicamos en la sección libraries and Classpath y agregamos la libreria itext.

Exportando a PDF
La tarea de exportar PDF se realiza íntegramente en el método downloadCVtoPdf que usa nuestro af:fileDownloadActionListener
Analicemos el código
//Este metodo permite crear un archivo pdf que tiene los datos de una persona junto con su foto obtenidos desde la base de datos
public void downloadCVtoPdf(FacesContext facesContext,
OutputStream outputStream) {
try {
//haciendo uso de la clase AdfUtils obtenemos el iterator de la pagina jsf actual
//El iterator CandidatoVOIterator se encuentra en el Page Definition de la pagina
//Curriculum.jspx
BindingContainer bindings = ADFUtils.getBindingContainer();
DCIteratorBinding dcitr = (DCIteratorBinding)bindings.get("CandidatoVOIterator");
//Obtenemos la fila actual del Iterator
Row myrow= dcitr.getCurrentRow();
//Verificamos que exista una fila actual
if(myrow!= null){
//Convertimos la fila actual al tipo de datos de fila del View Object RhuTabPersonasEOVO
RhuTabPersonasEOVORowImpl mycandidato= (RhuTabPersonasEOVORowImpl)myrow;
//Creamos un documento de la clase com.lowagie.text.Document existente en la librería Itext
Document document = new Document();
try {
//Se crea una instancia PDF y se habre el documento para su escritura esto se hace con las
//librería itext
PdfWriter.getInstance(document, outputStream);
document.open();
//Obtengo los datos correspondiente a Cedula Y Nombre del Iterator.
String cadena= " Cedula: "+mycandidato.getCedula()+"<br/>";
cadena+= " Nombres: "+mycandidato.getPrimerNombre()+"<br/>";
//Se crea un objeto tipo imagen de la clase com.lowagie.text.Image de la librería itext
//instanciando una imagen ubicada en el servidor
Image imglogo = Image.getInstance(urlfiles+"logoredempleos.jpg");
//Escalamos y alineamos la imagen a un 40% de su tamaño original
imglogo.scalePercent(40);
imglogo.setAlignment(Image.ALIGN_CENTER );
//Agregamos la imagen al documento pdf que estamos escribiendo
document.add(imglogo);
//Creamos un texto tipo parrafo haciendo uso de la clase com.lowagie.text.Paragraph
Paragraph pargutn=new Paragraph("www.utn.edu.ec");
pargutn.setAlignment(Paragraph.ALIGN_CENTER);
//Agregamos el parrafo al documento pdf que estamos escribiendo
document.add(pargutn);
Image imgseperador = Image.getInstance(urlfiles+"grisbarra.png");
document.add(imgseperador);
//Obtenemos la imagen de la persona con el metodo getImageCV que devuelve un array de bytes
byte[] imgbyte= getImageCV(mycandidato.getCedula());
//Verificamos si existe la foto
if(imgbyte.length>0){
//Creamos una imagen para el doc pdf en base al array de bytes que contienen la foto de la
//persona
Image imgfoto = Image.getInstance(imgbyte);
//escalamos la imagen a 113 pixeles de ancho y 150 de largo
imgfoto.scaleAbsolute(113,150);
imgfoto.setAlignment(Image.LEFT | Image.TEXTWRAP);
imgfoto.setAlt("Ricardo Ruano");
//Agregamos la foto al documento pdf que estamos escribiendo
document.add(imgfoto);
}
Paragraph p= new Paragraph("CURRICULUM VITAE");
p.setAlignment(Paragraph.ALIGN_CENTER);
document.add(new Paragraph("CURRICULUM VITAE"));
//Agregamos la información textual de la persona al documento pdf
HtmlParser.parse(document, new StringReader("<div style=\"font-size:10px;padding-left:20px; \">"+cadena+"</div>"));
} catch (DocumentException e) {
e.printStackTrace();
}
document.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* Este metodo obtiene la foto de la persona obtenida desde la base de datos a traves del aplication module
* la foto se devuelve en un array de bytes para ser procesado por la clase itext
*/
public byte[] getImageCV( String IDUser)
throws IOException
{
String appModuleName = "model.RedAppModule";
String appModuleConfig = "RedAppModuleLocal";
String voQuery = "select foto from RHU_TAB_PERSONAS where CEDULA = ?";
String mimeType = "gif";
String idUsuario = IDUser;
byte[] buffer = new byte[0];
ApplicationModule am = Configuration.createRootApplicationModule(appModuleName, appModuleConfig);
//Creo una view Object temporal en base al query que devuelve el campo tipo blob
ViewObject vo = am.createViewObjectFromQueryStmt("TempView", voQuery);
int i=0;
// Seteo el campo para ejecutar el query este campo indica el id del registro
vo.setWhereClauseParam(i, idUsuario);
// Ejecuto el query
vo.executeQuery();
// Obtengo el resultado (solamente la primer fila que contendra nuestro cuenta)
Row persona = vo.first();
BlobDomain image = null;
if (persona != null)
{
// Asumimos que el campo de tipo blob esta en la primer columna
image = (BlobDomain) persona.getAttribute(0);
}
else
{
return buffer;
}
InputStream is = image.getInputStream();
// Borro la View Object temporal
vo.remove();
// Ejecuto el Release al Aplication Module
Configuration.releaseRootApplicationModule(am, false);
return image.toByteArray();
}
Ejecutando la Aplicación
Una vez lista la aplicación , se mostrara la pagina login.jspx donde se debe ingresar la cedula de la persona:

Haciendo clic en login se mostrara la página curriculum.jspx donde se muestra la foto de la persona junto con sus datos:

Para exportar estos datos a pdf hacemos clic en Descargar a PDF

El resultado final será

Como pueden notar solo he presentado los datos correspondientes a Cedula y Nombre pero ustedes pueden presentar cualquier cantidad de datos existentes el Iterator de la pagina.
Para decargarte el ejemplo y el script de la base de datos ve a
http://rapidshare.com/files/339050053/DownloadPDF.zip.html
Visita www.jpmonteolivo.gov.ec un paraíso oculto en el cielo
Salu2 desde Ibarra-Ecuador