Cómo leer tablas en documentos con C#

This article was translated from English: Does it need improvement?
Translated
View the article in English

IronOCR permite a los desarrolladores de C# extraer datos de tablas en PDF e imágenes utilizando modelos avanzados de aprendizaje automático, manejando tanto tablas simples con celdas básicas como estructuras complejas como facturas con celdas combinadas utilizando el método ReadDocumentAdvanced.

<Descripción: Diagrama o captura de pantalla que ilustre el concepto de código -->

La extracción de datos de tablas con Tesseract puede resultar complicada porque el texto suele estar en las celdas y disperso por el documento. Sin embargo, nuestra biblioteca incluye un modelo de aprendizaje automático entrenado y puesto a punto para detectar y extraer datos de tablas con precisión. Tanto si se trata de procesar informes financieros, listas de inventario o datos de facturas, IronOCR proporciona las herramientas necesarias para analizar datos estructurados de forma eficaz.

Para tablas sencillas, confíe en la detección directa de tablas mediante la clase estándar OcrInput. Para estructuras más complejas, nuestro método exclusivo ReadDocumentAdvanced proporciona resultados sólidos, analizando tablas y entregando datos de forma eficaz. Este método avanzado aprovecha el aprendizaje automático para comprender la disposición de las tablas, las celdas combinadas y el formato complejo con el que el OCR tradicional suele tener problemas.

Inicio rápido: Extraer Celdas de Tablas Complejas en Una Llamada

Póngase en marcha en cuestión de minutos: este ejemplo muestra cómo una única llamada a IronOCR mediante ReadDocumentAdvanced le proporciona datos detallados de las celdas de una tabla a partir de un documento complejo. Demuestra la facilidad de uso cargando un PDF, aplicando la detección avanzada de tablas y devolviendo una lista de información de celdas directamente.

Nuget IconEmpieza a crear PDF con NuGet ahora:

  1. Instalar IronOCR con el gestor de paquetes NuGet

    PM > Install-Package IronOcr

  2. Copie y ejecute este fragmento de código.

    var cells = new IronTesseract().ReadDocumentAdvanced(new OcrInput().LoadPdf("invoiceTable.pdf")).Tables.First().CellInfos;
  3. Despliegue para probar en su entorno real

    Empieza a utilizar IronOCR en tu proyecto hoy mismo con una prueba gratuita
    arrow pointer

Los siguientes pasos te guían para comenzar a leer tablas usando IronOCR:


¿Cómo extraer datos de tablas sencillas?

Configurar la propiedad ReadDataTables en true habilita la detección de tablas utilizando Tesseract. Este enfoque funciona bien para tablas básicas con límites de celda claros y sin celdas combinadas. Creé un PDF de tabla simple para probar esta función, que puedes descargar aquí: 'simple-table.pdf'. Las tablas simples sin celdas fusionadas pueden ser detectadas utilizando este método. Para tablas más complejas, consulte el método descrito a continuación.

El método estándar de detección de tablas es especialmente eficaz para:

  • Exportación de hojas de cálculo
  • Tablas de datos básicos con una estructura coherente de filas y columnas
  • Informes con datos tabulares
  • Listas de inventario sencillas

Si se trabaja con Extracción de texto mediante OCR de PDF en general, este método se integra perfectamente con las capacidades más amplias de procesamiento de documentos de IronOcr.

:path=/static-assets/ocr/content-code-examples/how-to/read-table-in-document-with-tesseract.cs
using IronOcr;
using System;
using System.Data;

// Instantiate OCR engine
var ocr = new IronTesseract();

// Enable table detection
ocr.Configuration.ReadDataTables = true;

using var input = new OcrPdfInput("simple-table.pdf");
var result = ocr.Read(input);

// Retrieve the data
var table = result.Tables[0].DataTable;

// Print out the table data
foreach (DataRow row in table.Rows)
{
    foreach (var item in row.ItemArray)
    {
        Console.Write(item + "\t");
    }
    Console.WriteLine();
}
Imports Microsoft.VisualBasic
Imports IronOcr
Imports System
Imports System.Data

' Instantiate OCR engine
Private ocr = New IronTesseract()

' Enable table detection
ocr.Configuration.ReadDataTables = True

Dim input = New OcrPdfInput("simple-table.pdf")
Dim result = ocr.Read(input)

' Retrieve the data
Dim table = result.Tables(0).DataTable

' Print out the table data
For Each row As DataRow In table.Rows
	For Each item In row.ItemArray
		Console.Write(item & vbTab)
	Next item
	Console.WriteLine()
Next row
$vbLabelText   $csharpLabel

¿Cómo puedo leer tablas de facturación complejas?

Una de las tablas complejas más comunes que se encuentran en entornos empresariales son las facturas. Las facturas son tablas complejas con filas y columnas de datos, a menudo con celdas combinadas, anchos de columna variables y estructuras anidadas. Con IronOCR, utilizamos el método ReadDocumentAdvanced para manejarlos eficazmente. El proceso implica escanear el documento, identificar la estructura de la tabla y extraer los datos. En este ejemplo, utilizamos el archivo 'invoiceTable.pdf' para mostrar cómo IronOCR recupera toda la información de la factura.

El método ReadDocumentAdvanced requiere la instalación del paquete IronOcr.Extensions.AdvancedScan junto con el paquete base IronOCR. Esta extensión proporciona capacidades avanzadas de aprendizaje automático específicamente entrenadas para diseños de documentos complejos.

[{i:( Usar escaneo avanzado en .NET Framework requiere que el proyecto se ejecute en arquitectura x64. Navega a la configuración del proyecto y desactiva la opción 'Preferir 32 bits' para lograrlo. Obtenga más información en la siguiente guía de solución de problemas: "Escaneo avanzado en .NET Framework."
@@--CIERRE DE SOPORTE--@@

:path=/static-assets/ocr/content-code-examples/how-to/read-table-in-document-with-ml.cs
using IronOcr;
using System.Linq;

// Instantiate OCR engine
var ocr = new IronTesseract();

using var input = new OcrInput();
input.LoadPdf("invoiceTable.pdf");

// Perform OCR
var result = ocr.ReadDocumentAdvanced(input);

var cellList = result.Tables.First().CellInfos;
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Este método separa los datos de texto del documento en dos categorías: una encerrada por bordes y otra sin bordes. Para el contenido bordeado, la biblioteca lo divide aún más en subsecciones basadas en la estructura de la tabla. El método destaca en el manejo:

  • Partidas de factura con distintas descripciones
  • Desglose de precios en varias columnas
  • Bloques de direcciones de envío y facturación
  • Secciones de impuestos y cálculo total
  • Información de cabecera y pie de página

Los resultados se muestran a continuación. Dado que este método se centra en la información delimitada por bordes, cualquier celda combinada que abarque varias filas se tratará como una sola celda.

¿Qué aspecto tienen los datos extraídos?

IronSoftware OCR extrayendo datos de tablas de una factura de envío a un formato jerárquico estructurado

¿Cómo organizo y proceso las celdas de tabla extraídas?

En la implementación actual, las celdas extraídas aún no están organizadas correctamente. Sin embargo, cada celda contiene información valiosa como coordenadas X e Y, dimensiones y más. Usando estos datos, podemos crear una clase auxiliar para varios propósitos. La información de la celda incluye:

  • Coordenadas X/Y precisas para el posicionamiento
  • Dimensiones de ancho y alto
  • Contenido del texto
  • Puntuaciones de confianza
  • Relaciones entre celdas

Esta información detallada permite reconstruir la estructura de la tabla mediante programación y aplicar una lógica personalizada para la extracción de datos. También puede utilizar estas coordenadas para definir regiones específicas para el procesamiento OCR específico en operaciones posteriores.

A continuación, algunos métodos auxiliares básicos:

using System;
using System.Collections.Generic;
using System.Linq;

// A helper class to process table data by sorting cells based on coordinates
public static class TableProcessor
{
    // Method to organize cells by their coordinates (Y top to bottom, X left to right)
    public static List<CellInfo> OrganizeCellsByCoordinates(List<CellInfo> cells)
    {
        // Sort cells by Y (top to bottom), then by X (left to right)
        var sortedCells = cells
            .OrderBy(cell => cell.CellRect.Y)
            .ThenBy(cell => cell.CellRect.X)
            .ToList();

        return sortedCells;
    }

    // Example method demonstrating how to process multiple tables
    public static void ProcessTables(Tables tables)
    {
        foreach (var table in tables)
        {
            var sortedCells = OrganizeCellsByCoordinates(table.CellInfos);

            Console.WriteLine("Organized Table Cells:");

            // Initialize previous Y coordinate
            int previousY = sortedCells.Any() ? sortedCells.First().CellRect.Y : 0;

            foreach (var cell in sortedCells)
            {
                // Print a new line if the Y-coordinate changes, indicating a new row
                if (Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8)
                {
                    Console.WriteLine();  // Start a new row
                    previousY = cell.CellRect.Y;
                }

                // Print the cell text followed by a tab
                Console.Write($"{cell.CellText}\t");
            }

            Console.WriteLine("\n--- End of Table ---");  // End of a table
        }
    }

    // Method to extract a specific row by the given index
    public static List<CellInfo> ExtractRowByIndex(TableInfo table, int rowIndex)
    {
        if (table == null || table.CellInfos == null || !table.CellInfos.Any())
        {
            throw new ArgumentException("Table is empty or invalid.");
        }

        var sortedCells = OrganizeCellsByCoordinates(table.CellInfos);
        List<List<CellInfo>> rows = new List<List<CellInfo>>();

        // Group cells into rows based on Y coordinates
        int previousY = sortedCells.First().CellRect.Y;
        List<CellInfo> currentRow = new List<CellInfo>();

        foreach (var cell in sortedCells)
        {
            if (Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8)
            {
                // Store the completed row and start a new one
                rows.Add(new List<CellInfo>(currentRow));
                currentRow.Clear();

                previousY = cell.CellRect.Y;
            }

            currentRow.Add(cell);
        }

        // Add the last row if it wasn't added yet
        if (currentRow.Any())
        {
            rows.Add(currentRow);
        }

        // Retrieve the specified row
        if (rowIndex < 0 || rowIndex >= rows.Count)
        {
            throw new IndexOutOfRangeException($"Row index {rowIndex} is out of range.");
        }

        return rows[rowIndex];
    }
}
using System;
using System.Collections.Generic;
using System.Linq;

// A helper class to process table data by sorting cells based on coordinates
public static class TableProcessor
{
    // Method to organize cells by their coordinates (Y top to bottom, X left to right)
    public static List<CellInfo> OrganizeCellsByCoordinates(List<CellInfo> cells)
    {
        // Sort cells by Y (top to bottom), then by X (left to right)
        var sortedCells = cells
            .OrderBy(cell => cell.CellRect.Y)
            .ThenBy(cell => cell.CellRect.X)
            .ToList();

        return sortedCells;
    }

    // Example method demonstrating how to process multiple tables
    public static void ProcessTables(Tables tables)
    {
        foreach (var table in tables)
        {
            var sortedCells = OrganizeCellsByCoordinates(table.CellInfos);

            Console.WriteLine("Organized Table Cells:");

            // Initialize previous Y coordinate
            int previousY = sortedCells.Any() ? sortedCells.First().CellRect.Y : 0;

            foreach (var cell in sortedCells)
            {
                // Print a new line if the Y-coordinate changes, indicating a new row
                if (Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8)
                {
                    Console.WriteLine();  // Start a new row
                    previousY = cell.CellRect.Y;
                }

                // Print the cell text followed by a tab
                Console.Write($"{cell.CellText}\t");
            }

            Console.WriteLine("\n--- End of Table ---");  // End of a table
        }
    }

    // Method to extract a specific row by the given index
    public static List<CellInfo> ExtractRowByIndex(TableInfo table, int rowIndex)
    {
        if (table == null || table.CellInfos == null || !table.CellInfos.Any())
        {
            throw new ArgumentException("Table is empty or invalid.");
        }

        var sortedCells = OrganizeCellsByCoordinates(table.CellInfos);
        List<List<CellInfo>> rows = new List<List<CellInfo>>();

        // Group cells into rows based on Y coordinates
        int previousY = sortedCells.First().CellRect.Y;
        List<CellInfo> currentRow = new List<CellInfo>();

        foreach (var cell in sortedCells)
        {
            if (Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8)
            {
                // Store the completed row and start a new one
                rows.Add(new List<CellInfo>(currentRow));
                currentRow.Clear();

                previousY = cell.CellRect.Y;
            }

            currentRow.Add(cell);
        }

        // Add the last row if it wasn't added yet
        if (currentRow.Any())
        {
            rows.Add(currentRow);
        }

        // Retrieve the specified row
        if (rowIndex < 0 || rowIndex >= rows.Count)
        {
            throw new IndexOutOfRangeException($"Row index {rowIndex} is out of range.");
        }

        return rows[rowIndex];
    }
}
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Linq

' A helper class to process table data by sorting cells based on coordinates
Public Module TableProcessor
	' Method to organize cells by their coordinates (Y top to bottom, X left to right)
	Public Function OrganizeCellsByCoordinates(ByVal cells As List(Of CellInfo)) As List(Of CellInfo)
		' Sort cells by Y (top to bottom), then by X (left to right)
		Dim sortedCells = cells.OrderBy(Function(cell) cell.CellRect.Y).ThenBy(Function(cell) cell.CellRect.X).ToList()

		Return sortedCells
	End Function

	' Example method demonstrating how to process multiple tables
	Public Sub ProcessTables(ByVal tables As Tables)
		For Each table In tables
			Dim sortedCells = OrganizeCellsByCoordinates(table.CellInfos)

			Console.WriteLine("Organized Table Cells:")

			' Initialize previous Y coordinate
			Dim previousY As Integer = If(sortedCells.Any(), sortedCells.First().CellRect.Y, 0)

			For Each cell In sortedCells
				' Print a new line if the Y-coordinate changes, indicating a new row
				If Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8 Then
					Console.WriteLine() ' Start a new row
					previousY = cell.CellRect.Y
				End If

				' Print the cell text followed by a tab
				Console.Write($"{cell.CellText}" & vbTab)
			Next cell

			Console.WriteLine(vbLf & "--- End of Table ---") ' End of a table
		Next table
	End Sub

	' Method to extract a specific row by the given index
	Public Function ExtractRowByIndex(ByVal table As TableInfo, ByVal rowIndex As Integer) As List(Of CellInfo)
		If table Is Nothing OrElse table.CellInfos Is Nothing OrElse Not table.CellInfos.Any() Then
			Throw New ArgumentException("Table is empty or invalid.")
		End If

		Dim sortedCells = OrganizeCellsByCoordinates(table.CellInfos)
		Dim rows As New List(Of List(Of CellInfo))()

		' Group cells into rows based on Y coordinates
		Dim previousY As Integer = sortedCells.First().CellRect.Y
		Dim currentRow As New List(Of CellInfo)()

		For Each cell In sortedCells
			If Math.Abs(cell.CellRect.Y - previousY) > cell.CellRect.Height * 0.8 Then
				' Store the completed row and start a new one
				rows.Add(New List(Of CellInfo)(currentRow))
				currentRow.Clear()

				previousY = cell.CellRect.Y
			End If

			currentRow.Add(cell)
		Next cell

		' Add the last row if it wasn't added yet
		If currentRow.Any() Then
			rows.Add(currentRow)
		End If

		' Retrieve the specified row
		If rowIndex < 0 OrElse rowIndex >= rows.Count Then
			Throw New IndexOutOfRangeException($"Row index {rowIndex} is out of range.")
		End If

		Return rows(rowIndex)
	End Function
End Module
$vbLabelText   $csharpLabel

Mejores prácticas para la extracción de tablas

Cuando trabaje con la extracción de tablas en IronOCR, tenga en cuenta estas prácticas recomendadas:

  1. Calidad del documento: Los documentos de mayor resolución producen mejores resultados. Para los documentos escaneados, asegúrese de que tengan un mínimo de 300 DPI.

  2. Preprocesamiento: Para documentos de baja calidad o tablas sesgadas, considere el uso de las funciones de corrección de imágenes de IronOCR antes del procesamiento.

  3. Rendimiento: Para documentos grandes con múltiples tablas, considere el uso de multithreading y soporte async para procesar páginas en paralelo.

  4. Opciones de salida: Después de extraer los datos de la tabla, puedes exportar los resultados en varios formatos. Obtenga más información sobre opciones de salida de datos y sobre cómo crear PDF con capacidad de búsqueda a partir de los documentos procesados.

  5. Stream Processing: Para aplicaciones web o escenarios que trabajan con documentos en memoria, considere el uso de OCR para flujos PDF para evitar las operaciones del sistema de archivos.

Resumen

IronOCR ofrece potentes funciones de extracción de tablas mediante la detección estándar basada en Tesseract y métodos avanzados de aprendizaje automático. El método estándar funciona bien para tablas sencillas, mientras que el método ReadDocumentAdvanced destaca en documentos complejos como facturas. Con los métodos de ayuda proporcionados, puede organizar y procesar los datos extraídos para adaptarlos a sus necesidades específicas.

Explore más características de IronOCR para mejorar sus flujos de trabajo de procesamiento de documentos y aprovechar todo el potencial del reconocimiento óptico de caracteres en sus aplicaciones .NET.

Preguntas Frecuentes

¿Cómo puedo extraer datos de tablas de PDF e imágenes en C#?

IronOCR permite a los desarrolladores de C# extraer datos de tablas de PDF e imágenes utilizando modelos avanzados de aprendizaje automático. Para tablas simples, utilice la clase OcrInput con la propiedad ReadDataTables establecida en true. Para tablas complejas con celdas combinadas, utilice el método ReadDocumentAdvanced para obtener resultados más precisos.

¿Cuál es la diferencia entre extracción de tablas simple y compleja?

La extracción simple de tablas en IronOCR utiliza la propiedad ReadDataTables con Tesseract y funciona bien para tablas básicas con límites de celda claros. La extracción de tablas complejas requiere el método ReadDocumentAdvanced, que utiliza el aprendizaje automático para gestionar celdas combinadas, facturas y formatos complejos.

¿Cómo puedo extraer rápidamente datos de tablas complejas?

Utilice el método ReadDocumentAdvanced de IronOCR en una sola llamada: var cells = new IronTesseract().ReadDocumentAdvanced(new OcrInput().LoadPdf('invoiceTable.pdf')).Tables.First().CellInfos; Esto aprovecha el aprendizaje automático para comprender la disposición de las tablas y el formato complejo.

¿Qué tipos de documentos funcionan mejor con la detección simple de tablas?

El sencillo método de detección de tablas de IronOCR funciona especialmente bien con exportaciones de hojas de cálculo, tablas de datos básicas con una estructura coherente de filas y columnas, informes con datos tabulares y listas de inventario sencillas sin celdas combinadas.

¿Cómo puedo activar la detección de tablas básicas?

Para activar la detección de tablas en IronOCR para tablas básicas, establezca la propiedad ReadDataTables en true. Esto utiliza las capacidades de detección de tablas de Tesseract y funciona bien para tablas con límites de celda claros y sin celdas fusionadas.

¿Puede la biblioteca manejar facturas e informes financieros con diseños complejos?

Sí, el método ReadDocumentAdvanced de IronOCR está diseñado específicamente para manejar documentos complejos como facturas e informes financieros. Utiliza modelos de aprendizaje automático entrenados para detectar y extraer datos de tablas con celdas combinadas y formato complejo.

Curtis Chau
Escritor Técnico

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien ...

Leer más
Revisado por
Jeff Fritz
Jeffrey T. Fritz
Gerente Principal de Programas - Equipo de la Comunidad .NET
Jeff también es Gerente Principal de Programas para los equipos de .NET y Visual Studio. Es el productor ejecutivo de la serie de conferencias virtuales .NET Conf y anfitrión de 'Fritz and Friends', una transmisión en vivo para desarrolladores que se emite dos veces a la semana donde habla sobre tecnología y escribe código junto con la audiencia. Jeff escribe talleres, presentaciones, y planifica contenido para los eventos de desarrolladores más importantes de Microsoft, incluyendo Microsoft Build, Microsoft Ignite, .NET Conf y la Cumbre de Microsoft MVP.
¿Listo para empezar?
Nuget Descargas 5,246,844 | Versión: 2025.12 recién lanzado