lunes, 27 de abril de 2020

PDF con IText (2). Identicar un documento por el contenido

0. Introducción

Ahora ya tenemos los documentos separados, pero queremos saber a quien corresponde el documento.
Se dispone de una lista de personas obtenida de nuestra BD, y sabemos que los datos de las personas se imprimen siempre en la misma posición.

1. Sistemas de coordenadas de IText 7

Veamos:

  1. El sistema de coordenadas de IText 7 és bastante enfarragoso, pues en principio, el origen de coordenadas X,Y se encuentra en la parte inferior izquierda del papel (documento). 
  2. Se pueden modificar los orígines de coordenadas, pero no vamos a entrar en detalle.
  3. Las coordenadas van por unidades propias, de manera que en un A4, tenemos un rectángulo que va desde el punto (0,0) hasta el (595, 894)
Por tanto, se puede establecer una relación aproximada entre unidades de medida (mm) y unidades del IText.

2. Localizar la zona donde se imprimen los datos (por ejempo el DNI)

Con IText, se puede obtener el texto que hay en un rectángulo.
Según lo visto en el punto anterior se mide donde empieza y acaba dicho campo sobre el papel y se define un rectángulo.... Pero esto es una simple aproximación, pues parece ser que en PDF los textos son cuadros de texto bastante mas grandes de lo que se muestra en el papel impreso. Por tanto, dento del rectángulo que hemos medido del DNI, se cuela bastante más texto del deseado, por tanto hay que hacer varias pruebas de rectángulos por la zona donde hemos medido hasta que pillemos un rectángulo que nos devuelva poco texto y que al menos contenga el texto que queremos (el DNI).

En mi caso el rectángulo que me da esto es:


public static final Rectangle rect = new Rectangle(20, 725, 25, 750); 


3. Obtener el texto de dicho rectángulo

Para ello tengo esta función que me devuelve el texto de la zona afectada por el rectángulo en un PDF


protected static String getText(final String fileName, Rectangle rect) throws IOException {
   
     PdfDocument pdfDoc = new PdfDocument(new PdfReader(fileName));
     TextRegionEventFilter regionFilter = new TextRegionEventFilter(rect);
     ITextExtractionStrategy strategy = new FilteredTextEventListener(new LocationTextExtractionStrategy(), regionFilter);
     
     PdfPage page=pdfDoc.getFirstPage();
        
     String rectangleText = PdfTextExtractor.getTextFromPage(page, strategy);
        return rectangleText;
     
 }

4. Renombrar los documentos

De entrada partimos de una carpeta donde están los documentos y un lista con los datos de las personas que afectan los documentos.
Hemos creado una función que no voy a mostrar que nos da el nuevo nombre del documento (en ese nuevo nombre podemos meter el nombre de la persona, dni etc para aclaranos)
Hay que tener en ecuenta que puede haber más de un documento por persona.
Al final nos devuelve los documentos con los nuevos nombres que nos dan una idea de que persona son.
Como se ve, hay unas variables globales que guardan la carpeta origen(SOURCE_FOLDER) y destino (DEST_FOLDER)
Se ha hecho uso de las libreria de Apache Commons io para copiar las librerias.


protected static void renombrar(List<Persona> personas) throws IOException {
 File outDir =new File(DEST_FOLDER);
 outDir.mkdirs();
  
 File folder = new File(SOURCE_FOLDER);
 int i=0;
 for (File fileEntry:folder.listFiles( (dir, name) -> name.endsWith(".pdf")) ) {
  String text=getText(fileEntry.getCanonicalPath(),rect);
   
  for(Persona persona :personas) {
   if (text.contains(persona.getNif().trim())) {
    String newName=newFileName(DEST_FOLDER, persona,++i);
    FileUtils.copyFile(fileEntry, new File(newName));     
    } 
    
   }
  }
 }






No hay comentarios :

Publicar un comentario