/// <summary>
        /// Extrae el texto con los patrones aprendidos con tal de comparar si son falsos positivos.
        /// </summary>
        /// <param name="checkResult">PdfCheckResult para comparar los falsos positivos.</param>
        /// <returns></returns>
        public List <PdfTagPattern> ExtractToCheck(PdfCheckResult checkResult)
        {
            PdfTagExtractionResult result = new PdfTagExtractionResult()
            {
                Pdf          = checkResult.Pdf,
                MetadataType = Type.GetType(MetadataName)
            };

            _Converters = new Dictionary <Type, object>();

            IHierarchySet hierarchySet = GetHierarchySet();

            foreach (var page in checkResult.Pdf.PdfUnstructuredPages)
            {
                ExtractFromRectangles(page.WordGroups,
                                      result.MetadataType, hierarchySet, result, page.PdfPageN);

                ExtractFromRectangles(page.Lines,
                                      result.MetadataType, hierarchySet, result, page.PdfPageN, "LinesInfos");

                ExtractFromText(result.MetadataType, result, page, hierarchySet);

                ExtractFromColorFontText(page.ColorFontWordGroups,
                                         result.MetadataType, hierarchySet, result, page.PdfPageN);
            }

            result.Converters = _Converters;

            return(result.CheckWithRightMetadata(checkResult.InvoiceMetadata)); // Comprobamos que los patrones que pasemos como resultado hayan extraído el texto correctamente.
        }
예제 #2
0
        /// <summary>
        /// Ejecuta patrones los extracción de textos
        /// almacenados.
        /// </summary>
        /// <param name="pdf"></param>
        /// <returns></returns>
        public PdfTagExtractionResult Extract(PdfUnstructuredDoc pdf)
        {
            PdfTagExtractionResult result = new PdfTagExtractionResult()
            {
                Pdf          = pdf,
                MetadataType = Type.GetType(MetadataName)
            };

            _Converters = new Dictionary <Type, object>();

            IHierarchySet hierarchySet = GetHierarchySet();

            foreach (var page in pdf.PdfUnstructuredPages)
            {
                ExtractFromRectangles(page.WordGroups,
                                      result.MetadataType, hierarchySet, result);

                ExtractFromRectangles(page.Lines,
                                      result.MetadataType, hierarchySet, result, "LinesInfos");

                ExtractFromText(result.MetadataType, result, page, hierarchySet);

                ExtractFromTextStrings(page.TextStringGroups,
                                       result.MetadataType, hierarchySet, result);
            }

            result.Converters = _Converters;

            result.GetMetadata();

            return(result);
        }
        /// <summary>
        /// Ejecuta los patrones de extracción de textos
        /// almacenados.
        /// </summary>
        /// <param name="pdf">Archivo PDF sobre el que extraer.</param>
        /// <returns></returns>
        public PdfTagExtractionResult Extract(PdfUnstructuredDoc pdf)
        {
            PdfTagExtractionResult result = new PdfTagExtractionResult()
            {
                Pdf          = pdf,
                MetadataType = Type.GetType(MetadataName)
            };

            _Converters = new Dictionary <Type, object>();

            IHierarchySet hierarchySet = GetHierarchySet();

            PdfPatternsPage = new Dictionary <int, List <PdfTagPattern> >();
            foreach (PdfTagPattern pattern in PdfPatterns) // Evitar que los bucles de extracción recorran siempre todos los patrones idependientemente del número de página.
            {
                if (PdfPatternsPage.ContainsKey(pattern.PdfPageN))
                {
                    PdfPatternsPage[pattern.PdfPageN].Add(pattern);
                }
                else
                {
                    PdfPatternsPage[pattern.PdfPageN] = new List <PdfTagPattern>()
                    {
                        pattern
                    }
                };
            }

            foreach (var page in pdf.PdfUnstructuredPages)
            {
                ExtractFromRectangles(page.WordGroups,
                                      result.MetadataType, hierarchySet, result, page.PdfPageN);

                ExtractFromRectangles(page.Lines,
                                      result.MetadataType, hierarchySet, result, page.PdfPageN, "LinesInfos");

                ExtractFromText(result.MetadataType, result, page, hierarchySet);

                ExtractFromColorFontText(page.ColorFontWordGroups,
                                         result.MetadataType, hierarchySet, result, page.PdfPageN);
            }

            result.Converters = _Converters;

            result.GetMetadata();

            return(result);
        }
        /// <summary>
        /// Ejecuata la extracción basada en limites
        /// textuales.
        /// </summary>
        /// <param name="metadataType">Tipo de la clase que implementa IMetadata.</param>
        /// <param name="result">Resultado de extracción.</param>
        /// <param name="page">PdfUnstructuredPage del doc. pdf.</param>
        /// <param name="hierarchySet">Catálogo de jerarquías.</param>
        private void ExtractFromText(Type metadataType,
                                     PdfTagExtractionResult result, PdfUnstructuredPage page,
                                     IHierarchySet hierarchySet)
        {
            foreach (var pattern in PdfPatterns)
            {
                if (pattern.PdfPageN == page.PdfPageN || pattern.IsLastPage) // Comprobamos que los patrones realicen la extracción sobre la página que les corresponde.
                                                                             // Se comprueba la última página porque en algunos documentos viene primero los albaranes y al final la factura.
                {
                    if (pattern.SourceTypeName == "PdfTextInfos")
                    {
                        foreach (Match match in Regex.Matches(page.PdfText, pattern.RegexPattern))
                        {
                            PropertyInfo pInf = metadataType.GetProperty(pattern.MetadataItemName);

                            if (pInf.PropertyType == typeof(string))
                            {
                                result.AddResult(pattern, match.Value);
                            }
                            else
                            {
                                dynamic converter = null;

                                if (_Converters.ContainsKey(pInf.PropertyType))
                                {
                                    converter = _Converters[pInf.PropertyType];
                                }
                                else
                                {
                                    ITextParserHierarchy parserHierarchy = hierarchySet.GetParserHierarchy(pInf);
                                    converter = parserHierarchy.GetConverter(pInf.PropertyType);

                                    if (converter == null)
                                    {
                                        Type converterGenType = typeof(Converter <>).MakeGenericType(pInf.PropertyType);
                                        converter = Activator.CreateInstance(converterGenType);
                                    }
                                }

                                object pValue = converter.Convert(match.Value);
                                result.AddResult(pattern, pValue);
                            }
                        }
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Ejecuata la extracción basada en limites
        /// textuales.
        /// </summary>
        /// <param name="metadataType">Tipo de la clase que implementa IMetadata.</param>
        /// <param name="result">Resultado de extracción.</param>
        /// <param name="page">PdfUnstructuredPage del doc. pdf.</param>
        private void ExtractFromText(Type metadataType,
                                     PdfTagExtractionResult result, PdfUnstructuredPage page,
                                     IHierarchySet hierarchySet)
        {
            foreach (var pattern in PdfPatterns)
            {
                if (pattern.SourceTypeName == "PdfTextInfos")
                {
                    foreach (Match match in Regex.Matches(page.PdfText, pattern.RegexPattern))
                    {
                        PropertyInfo pInf = metadataType.GetProperty(pattern.MetadataItemName);

                        if (pInf.PropertyType == typeof(string))
                        {
                            result.AddResult(pattern, match.Value);
                        }
                        else
                        {
                            dynamic converter = null;

                            if (_Converters.ContainsKey(pInf.PropertyType))
                            {
                                converter = _Converters[pInf.PropertyType];
                            }
                            else
                            {
                                ITextParserHierarchy parserHierarchy = hierarchySet.GetParserHierarchy(pInf);
                                converter = parserHierarchy.GetConverter(pInf.PropertyType);
                                if (converter == null)
                                {
                                    Type converterGenType = typeof(Converter <>).MakeGenericType(pInf.PropertyType);
                                    converter = Activator.CreateInstance(converterGenType);
                                }
                            }
                            object pValue = converter.Convert(match.Value);
                            result.AddResult(pattern, pValue);
                        }
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Ejecuta el proceso de extracción de metadatos
        /// en base a los patrones almacenados.
        /// </summary>
        /// <param name="pdfDocRectangles">rectángulos del pdf doc.</param>
        /// <param name="metadataType">Implementa IMetadata.</param>
        /// <param name="hierarchySet">Catálogo de jerarquías.</param>
        /// <param name="result">Resultados.</param>
        /// <param name="sourceTypeName">Nombre de la fuente.</param>
        private void ExtractFromRectangles(List <PdfTextRectangle> pdfDocRectangles,
                                           Type metadataType, IHierarchySet hierarchySet, PdfTagExtractionResult result,
                                           string sourceTypeName = "WordGroupsInfos")
        {
            foreach (var pdfDocRectangle in pdfDocRectangles)
            {
                foreach (var pattern in PdfPatterns)
                {
                    if (pattern.SourceTypeName == sourceTypeName)
                    {
                        if (IsAlmostSameArea(pdfDocRectangle, pattern.PdfRectangle))
                        {
                            string               textInput       = pdfDocRectangle.Text;
                            PropertyInfo         pInf            = metadataType.GetProperty(pattern.MetadataItemName);
                            ITextParserHierarchy parserHierarchy = hierarchySet.GetParserHierarchy(pInf);

                            if (pInf.PropertyType == typeof(string))
                            {
                                parserHierarchy.SetParserRegexPattern(0, pattern.RegexPattern);
                            }

                            dynamic converter = parserHierarchy.GetConverter(pattern.RegexPattern);

                            MatchCollection matches = Regex.Matches(pdfDocRectangle.Text, pattern.RegexPattern);

                            string val = (pattern.Position < matches.Count) ?
                                         matches[pattern.Position].Value : null;

                            object pValue = null;

                            if (val != null && converter != null)
                            {
                                pValue = converter.Convert(val);
                            }

                            if (pValue != null && !PdfCompare.IsZeroNumeric(pValue))
                            {
                                result.AddResult(pattern, pValue);
                                if (!_Converters.ContainsKey(pInf.PropertyType))
                                {
                                    _Converters.Add(pInf.PropertyType, converter);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Ejecuta el proceso de extracción de metadatos
        /// a partir de los patrones almacenados.
        /// En este caso los metadatos deben coincidir en 4 propiedades:
        /// FontType, FontSize, ColorFill, ColorStroke.
        /// En caso de acierto, se compara la RegEx.
        /// </summary>
        /// <param name="pdfDocTextStrings">Los textStrings obtenidos con el texto y las 4 propiedades.</param>
        /// <param name="metadataType">Implementa IMetadata. Sirve para averiguar el tipo de dato. Ejemplos: int, string, etc.</param>
        /// <param name="hierarchySet">Catálogo de jerarquías.</param>
        /// <param name="result">Guarda los resultados obtenidos con este método de extracción.</param>
        private void ExtractFromTextStrings(List <PdfClownTextString> pdfDocTextStrings,
                                            Type metadataType, IHierarchySet hierarchySet, PdfTagExtractionResult result)
        {
            foreach (var textString in pdfDocTextStrings)
            {
                foreach (var pattern in PdfPatterns)
                {
                    if (pattern.SourceTypeName == "TextStringInfos")
                    {
                        if (textString.ColorFill.BaseDataObject.ToString().Equals(pattern.ColorFill) &&
                            textString.ColorStroke.BaseDataObject.ToString().Equals(pattern.ColorStroke) &&
                            textString.FontSize.ToString().Equals(pattern.FontSize) &&
                            textString.FontType.Name.Equals(pattern.FontType) &&
                            textString.Type.Equals(pattern.TsType))
                        {
                            if (pattern.TsType.Equals("NA") ||
                                (pattern.TsType.Equals("X") && textString.Rectangle != null && pattern.TsCoordinate.Equals(textString.Rectangle.Value.X.ToString())) ||
                                (pattern.TsType.Equals("Y") && textString.Rectangle != null && pattern.TsCoordinate.Equals(textString.Rectangle.Value.Y.ToString())))
                            {
                                // Cumple los 4 parámetros del textString
                                // por lo que debemos comprobar el contenido
                                // (convirtiendo el dato primero a un tipo comparable)

                                string               textInput       = textString.Text;
                                PropertyInfo         pInf            = metadataType.GetProperty(pattern.MetadataItemName);
                                ITextParserHierarchy parserHierarchy = hierarchySet.GetParserHierarchy(pInf);

                                if (pInf.PropertyType == typeof(string))
                                {
                                    parserHierarchy.SetParserRegexPattern(0, pattern.RegexPattern);
                                }

                                dynamic converter = parserHierarchy.GetConverter(pattern.RegexPattern);

                                MatchCollection matches = Regex.Matches(textString.Text, pattern.RegexPattern);

                                string val = (pattern.Position < matches.Count) ?
                                             matches[pattern.Position].Value : null;

                                object pValue = null;

                                if (val != null && converter != null)
                                {
                                    pValue = converter.Convert(val);
                                }

                                if (pValue != null && !PdfCompare.IsZeroNumeric(pValue))
                                {
                                    result.AddResult(pattern, pValue);
                                    if (!_Converters.ContainsKey(pInf.PropertyType))
                                    {
                                        _Converters.Add(pInf.PropertyType, converter);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Ejecuta el proceso de extracción de metadatos
        /// en base a los patrones almacenados.
        /// </summary>
        /// <param name="pdfDocColorFontText">Rectángulos del pdf doc con color, tamaño y nombre de fuente.</param>
        /// <param name="metadataType">Implementa IMetadata.</param>
        /// <param name="hierarchySet">Catálogo de jerarquías.</param>
        /// <param name="result">Resultados.</param>
        /// <param name="pageNumber">Número de la página sobre la que se realiza la extracción.</param>
        private void ExtractFromColorFontText(List <PdfColorFontTextRectangle> pdfDocColorFontText,
                                              Type metadataType, IHierarchySet hierarchySet, PdfTagExtractionResult result,
                                              int pageNumber)
        {
            string sourceTypeName = "ColorFontWordGroupsInfos";

            foreach (var pdfDocColorFontWord in pdfDocColorFontText)
            {
                foreach (var pattern in PdfPatterns)
                {
                    if (pattern.PdfPageN == pageNumber || pattern.IsLastPage) // Comprobamos que los patrones realicen la extracción sobre la página que les corresponde.
                                                                              // Se comprueba la última página porque en algunos documentos viene primero los albaranes y al final la factura.
                    {
                        if (pattern.SourceTypeName == sourceTypeName)
                        {
                            if (pdfDocColorFontWord.FillColor == pattern.FillColor &&
                                pdfDocColorFontWord.StrokeColor == pattern.StrokeColor &&
                                pdfDocColorFontWord.FontName == pattern.FontName &&
                                pdfDocColorFontWord.FontSize.ToString() == pattern.FontSize
                                ) // Comprobamos que tienen el mismo color, tamaño y nombre de fuente.
                                  // No comprobamos el CFType porque cuando llega aquí, pdfDocColorFontWord no tiene un CFType asignado aún.
                            {
                                if (pattern.CFType.Equals("NA") ||
                                    (pattern.CFType.Equals("X") && (pattern.PdfRectangle.Llx.Equals(pdfDocColorFontWord.Llx) || pattern.PdfRectangle.Urx.Equals(pdfDocColorFontWord.Urx))) ||
                                    (pattern.CFType.Equals("Y") && (pattern.PdfRectangle.Lly.Equals(pdfDocColorFontWord.Lly) || pattern.PdfRectangle.Ury.Equals(pdfDocColorFontWord.Ury))))
                                {
                                    string               textInput       = pdfDocColorFontWord.Text;
                                    PropertyInfo         pInf            = metadataType.GetProperty(pattern.MetadataItemName);
                                    ITextParserHierarchy parserHierarchy = hierarchySet.GetParserHierarchy(pInf);

                                    if (pInf.PropertyType == typeof(string))
                                    {
                                        parserHierarchy.SetParserRegexPattern(0, pattern.RegexPattern);
                                    }

                                    dynamic converter = parserHierarchy.GetConverter(pattern.RegexPattern);

                                    MatchCollection matches = Regex.Matches(pdfDocColorFontWord.Text, pattern.RegexPattern);

                                    string val = (pattern.Position < matches.Count) ?
                                                 matches[pattern.Position].Value : null;

                                    object pValue = null;

                                    if (val != null && converter != null)
                                    {
                                        pValue = converter.Convert(val);
                                    }

                                    if (pValue != null && !PdfCompare.IsZeroNumeric(pValue))
                                    {
                                        result.AddResult(pattern, pValue);
                                        if (!_Converters.ContainsKey(pInf.PropertyType))
                                        {
                                            _Converters.Add(pInf.PropertyType, converter);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Ejecuta el proceso de extracción de metadatos
        /// en base a los patrones almacenados.
        /// </summary>
        /// <param name="pdfDocRectangles">rectángulos del pdf doc.</param>
        /// <param name="metadataType">Implementa IMetadata.</param>
        /// <param name="hierarchySet">Catálogo de jerarquías.</param>
        /// <param name="result">Resultados.</param>
        /// <param name="pageNumber">Número de la página sobre la que se realiza la extracción.</param>
        /// <param name="sourceTypeName">Nombre de la fuente.</param>
        private void ExtractFromRectangles(List <PdfTextRectangle> pdfDocRectangles,
                                           Type metadataType, IHierarchySet hierarchySet, PdfTagExtractionResult result,
                                           int pageNumber,
                                           string sourceTypeName = "WordGroupsInfos")
        {
            foreach (var pdfDocRectangle in pdfDocRectangles)
            {
                foreach (var pattern in PdfPatterns)
                {
                    if (pattern.PdfPageN == pageNumber || pattern.IsLastPage) // Comprobamos que los patrones realicen la extracción sobre la página que les corresponde.
                                                                              // Se comprueba la última página porque en algunos documentos viene primero los albaranes y al final la factura.
                    {
                        if (pattern.SourceTypeName == sourceTypeName)
                        {
                            if (IsAlmostSameArea(pdfDocRectangle, pattern.PdfRectangle))
                            {
                                string               textInput       = pdfDocRectangle.Text;
                                PropertyInfo         pInf            = metadataType.GetProperty(pattern.MetadataItemName);
                                ITextParserHierarchy parserHierarchy = hierarchySet.GetParserHierarchy(pInf);

                                if (pInf.PropertyType == typeof(string))
                                {
                                    parserHierarchy.SetParserRegexPattern(0, pattern.RegexPattern);
                                }

                                dynamic converter = parserHierarchy.GetConverter(pattern.RegexPattern);

                                MatchCollection matches = Regex.Matches(pdfDocRectangle.Text, pattern.RegexPattern);

                                int p = pattern.Position;
                                int m = matches.Count;

                                string val = (pattern.Position < matches.Count) ?
                                             matches[pattern.Position].Value : null;

                                object pValue = null;

                                if (val != null && converter != null)
                                {
                                    pValue = converter.Convert(val);
                                }

                                if (pValue != null && !PdfCompare.IsZeroNumeric(pValue))
                                {
                                    result.AddResult(pattern, pValue);
                                    if (!_Converters.ContainsKey(pInf.PropertyType))
                                    {
                                        _Converters.Add(pInf.PropertyType, converter);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }