lunes, 12 de abril de 2010

Leer un PDF con PDFBox


Hace poco tiempo me tope con la necesidad de leer pdf's desde un servidor para obtener el texto del pdf y sus propiedades, por lo que tuve que investigar con que herramientas podría leer un pdf para convertirlo en un String y después manipular el contenido para obtener solo el texto que me interesaba, me tope con un muy buen blog el cual te explica como hacerlo con PDFBox a mi parecer esta muy entendible y me sirvió para mi propósito, lo único que hice fue modificarlo un poco:
este es el link del blog que mencione anteriormente: http://noelia-java.blogspot.com/2009/07/leer-pdf-desde-java.html

Estas son las clases que genere yo:


/**
*
* @author nany
*/
public class EntidadPDF {
private String titulo;
private String autor;
private int numeroDePaginas;
private String tema;
private String palabrasClave;
private String creador;
private String productor;
private String contenido;//el contenido completo del documento

public String getAutor() {
return autor;
}

public void setAutor(String autor) {
this.autor = autor;
}

public String getContenido() {
return contenido;
}

public void setContenido(String contenido) {
this.contenido = contenido;
}

public String getCreador() {
return creador;
}

public void setCreador(String creador) {
this.creador = creador;
}

public int getNumeroDePaginas() {
return numeroDePaginas;
}

public void setNumeroDePaginas(int numeroDePaginas) {
this.numeroDePaginas = numeroDePaginas;
}


public String getPalabrasClave() {
return palabrasClave;
}

public void setPalabrasClave(String palabrasClave) {
this.palabrasClave = palabrasClave;
}

public String getProductor() {
return productor;
}

public void setProductor(String productor) {
this.productor = productor;
}


public String getTema() {
return tema;
}

public void setTema(String tema) {
this.tema = tema;
}

public String getTitulo() {
return titulo;
}

public void setTitulo(String titulo) {
this.titulo = titulo;
}

}


El método que leera el pdf dada una url esta contenido en al siguiente clase

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import org.pdfbox.pdfparser.PDFParser;
import org.pdfbox.pdmodel.PDDocument;
import org.pdfbox.pdmodel.PDDocumentInformation;
import org.pdfbox.util.PDFTextStripper;

/**
*
* @author nany
*/
public class ContenedorPDF {

private FileInputStream file = null;
private PDDocument document = null;

/**
* Abre el archivo especificado en la ruta para generar un objeto de tipo EntidadPDF
* @param archivo
* @return
* @throws org.pdfbox.exceptions.CryptographyException
* @throws org.pdfbox.exceptions.InvalidPasswordException
*/
public EntidadPDF convertirAModelo(String archivo) {
EntidadPDF entPdf = new EntidadPDF();
try {

//leemos el pdf del articulo lo efectivo
URL url = new URL(archivo);
InputStream is = url.openStream();

PDFParser parser = new PDFParser(is);

parser.parse();
document = parser.getPDDocument();

//Obtenemos todo el contenido del pdf
PDFTextStripper stripper = new PDFTextStripper();
entPdf.setContenido(stripper.getText(document));


//obtenemos la informacion de las propiedades del pdf
PDDocumentInformation info = document.getDocumentInformation();

entPdf.setTitulo(info.getTitle());
entPdf.setAutor(info.getAuthor());
entPdf.setNumeroDePaginas(document.getNumberOfPages());
entPdf.setTema(info.getSubject());
entPdf.setPalabrasClave(info.getKeywords());
entPdf.setCreador(info.getCreator());
entPdf.setProductor(info.getProducer());


} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {//no se pudo abrir el archivo
e.printStackTrace();
} finally {
if (file != null) {
try {
file.close();
} catch (IOException e) {//no se pudo cerrar el archivo
e.printStackTrace();
}
}
if (document != null) {
try {
document.close();
} catch (IOException e) {//no se pudo cerrar el documento
e.printStackTrace();
}
}
}

return entPdf;
}


}

Bien espero y le sea de ayuda, le dejo otro link de otras librerías que permiten la manipulación del pdf
http://www.qoppa.com/Enlace

viernes, 9 de abril de 2010

Seleccionar un parte especifica de un String en Java con Scanner

Hola:

Muchas veses cuando desarrollamos sistemas nos topamos con problemitos como el siguiente:

Queremos extraer los caracteres o fracmentos en rojo de un String como este:
2o. Marzo-Abril

Seria una buena idea hacerlo con StringTokenizer pero tambien hay otra manera sensilla y elegante para hacerlo, solo tenemos que saber algo de expresiones, por ejemplo

para el caracter 2 bien podria ser un 3,4,5,6... por lo tanto la expresion para esta seria que siempre este caracter es un digito \d esta es la expresion para un digito

Marzo y Abril bien podrian ser Enero y Febrero, por lo tanto sabremos que siempre con palabras, me refiero que puede ser [a-z] y [A-Z], aqui se puede ocupar mas de una expresion pero para este ejemplo ocuparemos \w

Por lo tanto nuestra expresion completa seria esta:

String input = "2o. Marzo-Abril";
String expr="(\\d)o.\\s(\\w+)-(\\w+)";

Los parentesis son porque queremos obtener tres grupos que cumplan con la expresion que esta dentro de ellos.

String input = "2o. Marzo-Abril";
String expr="(\\d)o.\\s(\\w+)-(\\w+)";


Scanner s = new Scanner(input);
s.findInLine(expr);
MatchResult result = s.match();
for (int i=1; i<=result.groupCount(); i++)
System.out.println(i+" "+result.group(i));
s.close();

El resultado seria este:

1 2
2 Marzo
3 Abril


Pero que pasaria si el input fuera este:

String input = "40o. Marzo-Abril";

1 0
2 Marzo
3 Abril

en el grupo 1 obtenemos el 0 pero nosotros esperariamos un 40, pero es logico
puesto que nuestre expresion solo es \d que espera solo una posicion de un digito, para que sean varios necesitariamos \d+

String input = "40o. Marzo-Abril";
String expr="(\\d+)o.\\s(\\w+)-(\\w+)";


Scanner s = new Scanner(input);
s.findInLine(expr);
MatchResult result = s.match();
for (int i=1; i<=result.groupCount(); i++)
System.out.println(i+" "+result.group(i));
s.close();


Resultados:
1 40
2 Marzo
3 Abril

Saludos.