Ángel Ibáñez Hernández


.NET/SQL Analista Programador +20 años experiencia

PdfLogicExtractor

Descripción de PdfLogicalExtractor

PdfLogicExtractor es una pieza de sofware diseñada para extraer información de documentos pdf de manera lógica y ordenada, de tal forma que pueda después ser procesada por los sistemas en que se integre.

El sistema se basa en lógica adaptable implementada en un sistema de plantillas que puedan procesar todos documentos de un determinado tipo.

Una plantilla es capaz de adaptarse a las variaciones establecidas en su definición, como por ejemplo meses con diferente número de días, zonas del documento desplazadas o diferencias entre páginas dentro de un mismo documento. Y en general cualquier tipo de lógica de extracción que se necesite.

La lógica de extracción de plantilla puede ejecutar limpieza de resultados en base a reglas predefinidas, obteniendo tipos de dato puros o eliminando partes de textos poco significativas.

La lógica de extracción de plantilla puede efectuar cálculos en base a resultados obtenidos de diferentes extracciones o valores predefinidos, como por ejemplo calcular totales en una tabla en base a precio por unidades.

Así mismo, se pueden programar ex profeso todas las funcionalidades o excepciones que la lógica de plantilla de un tipo de documento requiera para resultar una herramienta más efectiva.

Instalación

El sistema está contenido en una librería de enlace dinámico o dll, incluida en un paquete de NuGet, que se puede incoporar a cualquier tipo de plataforma o proyecto de software del universo .NET.

La integración directa en un proyecto .NET puede hacerse incluyendo el NuGet en el propio proyecto y utilizando las llamadas estándar bien definidas en la documentación o en el propio sistema intelligence de Visual Studio.

Abra el gestor de nugets de Visual Studio y busque "Angelves" para acceder a nuestros paquetes.



Nuget 2
Nuget 2

Instalación manual por consola:

PM> NuGet\Install-Package Angelves.PdfLogicalExtractor -Version 1.0.2

Interface

La integración define una única interfaz de software muy sencilla con unas pocas llamadas sobrecargas y un modelo de datos de respuesta accesible directamente, que puede procesarse fácilmente como respuestas JSON.

namespace Angelves.PdfLogicalExtractor.PublicInterface
{
    public interface ILetsGoToExtraction
    {
        ExtractionResult Start(Template template, string filePath, DocumentType type);

        ExtractionResult Start(string templatePath, string filePath, DocumentType type);

        ExtractionResult Start(string templatePath, Stream fileStream, DocumentType type);
		
        ExtractionResult Start(Template template, Stream fileStream, DocumentType type);

        string GetWordsInPdf(string filePath, string? filter1 = null, int round = 0);
    }
}

Plantillas

Una Plantilla es un archivo en formato JSON que implemente lógica de extracción contra un documento PDF.

El objetivo de estas plantillas es obtener un resultado ordenado, capaz de ser procesado por una aplicación o sistema, procedente de la lectura en texto plano.


La siguiente tabla contiene una Descripción de las secciones de un plantilla, donde poder definir los boxes de extracción.

Seccion Descripción
Name En esta propiedad se establece el nombre de la plantilla.
Config En esta sección se establece la configuración de la plantilla.
Offsets
[pro]
En esta sección se establecen los puntos de control para detectar desplazamientos en el texto sobre el formato original.
Metaboxes
[pro]
En esta sección se definen los Metaboxes. Estos elementos son cajas de extracción en sí mismas pero no tienen repercusión en la salida, pues se usan en el cálculo de fórmulas.
Boxes En esta sección se definen los Boxes o cajas de extracción, que son los datos que extraemos del documento, cálculos, tablas, etc.
Renames En esta sección se establecen los renombramientos de campos de salida. Esta sección es últil para redifinir nombres automáticos procedentes de operaciones de extracción.

La siguiente tabla contiene una Descripción de los comandos que puede usar dentro de un Box en la Definición de la plantilla.

Funcionalidad Descripción
name Nombre del Box. esta propiedad es importante para cálculos.
id (*1)
[pro]
Identificador de offsets
type Define el tipo del Box:
Tipo Descripción parámetros
Literal Valor exacto que se toma desde la plantilla.
Empty Campo vacío.
Text Texto extraido.
Number Número entero.
Decimal Número decimal.
DateTime Fecha o fecha y hora. El formato en Format.
TextSplit Texto dividido mediante un carácter de corte. carácter de corte en Parameters[0].
Table Tabla en el documento. Definición en Header: array de objetos Json Box, que definen la cabecera.
Array Lista de valores desde una posición inicial a una posición final. Lista de parámetros:
Parametro Descripción
additionaldata Text o Number
w El ancho de las columnas.
ArraySwap (*2)
[pro]
Array con los ejes volteados integrado en Table. Este tipo genera un row por cada entrada válida. Lista de parámetros:
Parametro Descripción
additionaldata Text o Number
deletenullsinarray Borra del array original los valores nulos.
arrayindex Objeto Json con y1 e y2, que definen la fila de la extración de índice, días por ejemplo, en la fila superior.
w El ancho de las columnas.
idoffset Vículo del box con el id del control de offset.
required El box es requerido o no.
metabox
[pro]
Convierte un Box normal en un Metabox que no será reflejado en la salida.
x1, x2, y1 e y2 Coordenadas de extracción del texto.
deviationbetweenpages
[pro]
Derivación de la coordenada Y entre páginas.
master (*2) Booleano que establece la columna que maestra en la extracción de Table.
additionaldata Datos adicionales requeridos por algún tipo de Box.
parameters Array de parámetros requeridos por algún tipo de Box.
alternativecoords
[pro]
Coordenadas alternativas en base a condiciones
Array Json de condiciones con un campo "condition" donde se expresa una fórmula igual a resultado, y con 4 campos opcionales x1, x2, y1 e y2, donde se establecen las nuevas coordenadas en caso de cumplirse la condición.
extractionrules Reglas en la extracción de datos.
Array Json con los campos "action", "target" y "parameters[]":
action Descripción target parameters
Erase Borra el resultado de la extracción.
EraseFrom Borra el resultado desde el primer carácter hasta el final. carácter
EraseTo Borra el resultado desde el principio hasta el primer carácter. carácter
MaxRightCharsFromChar extracción de un número de caracteres desde un carácter dado hacia la derecha. carácter
QuitSpaces Quita todos los espacios.
QuitLineReturns Quita todas las líneas de retorno y salto de carro.
Replace Reemplaza el texto buscado por el texto reemplazado. Texto buscado [0] = Texto reemplazado, [1] = "exact" si es exacto.
ToLower Transforma en minúsculas.
ToUpper Transforma en mayúsculas.
ToRoundInteger Convierte texto en un texto con formato entero redondeado, si puede.
ToDecimal Convierte texto en un texto con formato decimal con dos decimales, si puede.
ToDate Convierte texto en un texto con formato DateTime, si puede.
El formato lo toma de Format.
formula
[pro]
fórmulas de cálculo con números en plantilla y/o metaboxes o boxes.
Sintaxis de fórmulas:
Elemento Descripción
[SELF] Valor original extraido sin modificar.
[BOX: name] Valor de un Box o un Metabox identificado por "name".
[BOXROW: name] (*2) Valor de un Box o un Metabox perteneciente a la misma fila de una tabla identificado por "name".
[SWAPVALUE] (*2) El resultado del valor extraído por cada row del ArraySwap.
+, -, * y / Operadores matemáticos admitidos. Si no se usa ningún operador matemático se entenderá que los valores son literales y el resultado es un texto.
comments Comentarios, sin utilidad en el proceso.
(*1): Aplicable a la sección offsets
(*2): Aplicable solo a Tables.
(*3): Aplicable solo a Renames.
[pro]: Sólo versión professional.

Ejemplo

{
  "templatename": "EXAMPLE TEMPLATE",
  "config": {
    "externalsfieldsintables": false,
    "decimalseparator": ","
  },
  "offsets": [
    {
      "id": 1,
      "text": "PROGRAM",
      "x": 82.92,
      "y": 153.95
    },
    {
      "id": 2,
      "text": "ADVERTISER:",
      "x": 82.92,
      "y": 101.99
    }
  ],
  "metaboxes": [
    {
      "name": "end_month_1",
      "type": "Number",
      "x1": 714,
      "y1": 146,
      "x2": 723,
      "y2": 153
    },
    {
      "name": "end_month_2",
      "type": "Number",
      "x1": 705,
      "y1": 146,
      "x2": 714,
      "y2": 143
    },
    {
      "name": "end_month_3",
      "type": "Number",
      "x1": 696,
      "y1": 146,
      "x2": 705,
      "y2": 153
    }
  ],
  "boxes": [
    {
      "name": "station",
      "required": true,
      "x1": 600,
      "y1": 60,
      "x2": 800,
      "y2": 80
    },
    {
      "name": "advertiser",
      "idoffset": 2,
      "required": true,
      "x1": 160,
      "y1": 90,
      "x2": 350,
      "y2": 110
    },
    {
      "name": "product",
      "idoffset": 2,
      "required": true,
      "x1": 160,
      "y1": 106,
      "x2": 350,
      "y2": 116
    },
    {
      "name": "campaign",
      "type": "Empty"
    },
    {
      "name": "reference",
      "idoffset": 2,
      "required": true,
      "x1": 600,
      "y1": 90,
      "x2": 800,
      "y2": 110,
      "extractionrules": [
        {
          "action": "QuitSpaces"
        },
        {
          "action": "Erase",
          "target": "N.ORDER:"
        }
      ]
    },
    {
      "name": "invoicedate",
      "type": "DateTime",
      "idoffset": 2,
      "required": true,
      "format": "dd/MM/yyyy",
      "x1": 600,
      "y1": 106,
      "x2": 800,
      "y2": 125,
      "extractionrules": [
        {
          "action": "Erase",
          "target": "DATE:"
        },
        {
          "action": "QuitSpaces"
        }
      ]
    },
    {
      "name": "table1",
      "type": "Table",
      "header": [
        {
          "name": "format",
          "idoffset": 1,
          "required": true,
          "master": true,
          "x1": 235,
          "y1": 171.10,
          "x2": 273,
          "y2": 178.41,
          "extractionrules": [
            {
              "action": "QuitSpaces"
            },
            {
              "action": "Erase",
              "target": "20"
            },
            {
              "action": "Erase",
              "target": "\""
            }
          ]
        },
        {
          "name": "duration",
          "idoffset": 1,
          "required": true,
          "x1": 235,
          "x2": 280,
          "extractionrules": [
            {
              "action": "QuitSpaces"
            },
            {
              "action": "Erase",
              "target": "CRADLE"
            },
            {
              "action": "Erase",
              "target": "\""
            }
          ]
        },
        {
          "name": "program",
          "idoffset": 1,
          "required": true,
          "x1": 70,
          "x2": 180
        },
        {
          "name": "startend_hour",
          "type": "TextSplit",
          "idoffset": 1,
          "parameters": [ "-" ],
          "x1": 180,
          "x2": 235,
          "extractionrules": [
            {
              "action": "QuitSpaces"
            },
            {
              "action": "Erase",
              "target": "("
            },
            {
              "action": "Erase",
              "target": "MF"
            },
            {
              "action": "Erase",
              "target": "S-U"
            },
            {
              "action": "Erase",
              "target": ")"
            }
          ]
        },
        {
          "name": "swap",
          "type": "ArraySwap",
          "idoffset": 1,
          "additionaldata": "Number",
          "deletenullsinarray": true,
          "x1": 444.21,
          "x2": 723.43,
          "w": 9.007,
          "arrayindex": {
            "y1": 146,
            "y2": 153
          },
          "alternativecoords": [
            {
              "condition": "[BOX:end_month_1] ! 31",
              "x2": 714.42
            },
            {
              "condition": "[BOX:end_month_2] ! 30",
              "x2": 705.41
            },
            {
              "condition": "[BOX:end_month_3] ! 29",
              "x2": 696.41
            }
          ]
        },
        {
          "name": "totalpasses",
          "type": "Decimal",
          "idoffset": 1,
          "x1": 310,
          "x2": 350
        },
        {
          "name": "unitprice",
          "type": "Decimal",
          "formula": "[BOXROW:totalprice] / [BOXROW:totalpasses]"
        },
        {
          "name": "discount",
          "type": "Decimal",
          "idoffset": 1,
          "x1": 380,
          "x2": 410,
          "extractionrules": [
            {
              "action": "Erase",
              "target": "%"
            },
            {
              "action": "QuitSpaces"
            }
          ]
        },
        {
          "name": "agencydiscount",
          "type": "Empty"
        },
        {
          "name": "totalprice",
          "type": "Decimal",
          "idoffset": 1,
          "required": true,
          "x1": 410,
          "x2": 445,
          "extractionrules": [
            {
              "action": "Erase",
              "target": "€"
            },
            {
              "action": "QuitSpaces"
            }
          ]
        }
      ]
    },
    {
      "name": "comments",
      "idoffset": 2,
      "x1": 60,
      "y1": 230,
      "x2": 720,
      "y2": 260,
      "extractionrules": [
        {
          "action": "QuitSpaces"
        },
        {
          "action": "Erase",
          "target": "COMMENTS:"
        }
      ]
    }
  ],
  "renames": [
    {
      "name": "startend_hour.INDEX[0]",
      "rename": "starthour",
      "exact": true,
      "casesensitive": false
    },
    {
      "name": "startend_hour.INDEX[1]",
      "rename": "endhour",
      "exact": true,
      "casesensitive": false
    },
    {
      "name": "swap.SWAP[",
      "rename": "passes",
      "exact": false,
      "casesensitive": false
    }
  ]
}

Licencia de Uso Comercial

Este software es proporcionado bajo los términos de esta Licencia de Uso Comercial ("Licencia"). Al descargar, instalar o utilizar este software, usted acepta los términos y condiciones de esta Licencia.

  1. Concesión de Licencia:

    Este software es un NuGet que puede ser descargado libremente. El propósito del software es ofrecer una funcionalidad para ordenar lógicamente la lectura de un PDF en texto plano proporcionado por un software de terceros. Se concede al usuario una licencia limitada, no exclusiva y no transferible para utilizar este software con el propósito de evaluación durante un período de prueba de 30 días. Después de este período, el usuario debe adquirir una licencia comercial para seguir utilizando este software.

  2. Restricciones de Uso:

    El usuario no puede descompilar, modificar o revender este software. Sin embargo, el usuario podrá redistribuir el software cuando sea integrado en su propio software bajo una licencia comercial. El usuario deberá adquirir una licencia válida para utilizar este software con fines comerciales.

  3. Excepción de Responsabilidad:

    El software de terceros proporcionado para la lectura de PDFs puede no ser capaz de leer algunos tipos de PDFs, como aquellos procedentes de imágenes escaneadas. El titular de la licencia no será responsable de ninguna pérdida o daño derivado de la incapacidad del software de terceros para leer un PDF determinado.

  4. Derechos de Propiedad:

    Todos los derechos de propiedad y propiedad intelectual de este software son propiedad del titular de la licencia. Este software está protegido por leyes de derechos de autor y otras leyes aplicables.

  5. Renuncia de Garantías:

    Este software se proporciona "tal cual," sin garantías de ningún tipo, ya sean expresas o implícitas. El titular de la licencia no será responsable de ningún daño directo, indirecto, incidental, especial, ejemplar o consecuente derivado del uso o la imposibilidad de utilizar este software.

  6. Ley Aplicable:

    Esta Licencia se regirá e interpretará de acuerdo con las leyes del Estado Español sin tener en cuenta sus principios de conflicto de leyes.

  7. Términos Adicionales:

    Los términos y condiciones de esta Licencia pueden ser sujetos a cambios sin previo aviso. Es responsabilidad del usuario revisar periódicamente los términos de esta Licencia.

  8. Licencia de software de terceros:

    PdfPig Liscence
    Newtonsoft Json Liscence

Al descargar, instalar o utilizar este software, usted reconoce haber leído y entendido los términos y condiciones de esta Licencia y acepta cumplir con ellos.