Cómo leer tablas en documentos con C

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

Hablemos sobre la lectura de tablas en documentos. Extraer datos de tablas usando Tesseract simple puede ser un desafío, ya que el texto a menudo reside en celdas y está disperso por todo el documento. Sin embargo, nuestra biblioteca está equipada con un modelo de aprendizaje automático que ha sido entrenado y ajustado para detectar y extraer datos de tablas con precisión.

Para tablas simples, puedes confiar en la detección de tablas sencilla, mientras que para estructuras más complejas, nuestro exclusivo método ReadDocumentAdvanced proporciona resultados robustos, analizando efectivamente la tabla y entregando datos.

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

Ponte en marcha en minutos—este ejemplo muestra cómo una sola llamada de IronOCR usando ReadDocumentAdvanced te brinda datos detallados de las celdas de la 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:


Ejemplo de tabla simple

Configurar la propiedad ReadDataTables en true habilita la detección de tablas utilizando Tesseract. 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, consulta el método descrito a continuación.

: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

Ejemplo de lectura de facturas

Una de las tablas complejas más comunes que se encuentran en entornos empresariales son las facturas. Las facturas en sí mismas son tablas complejas con filas y columnas de datos. Con IronOCR, utilizamos el método ReadDocumentAdvanced para manejarlas de manera excelente. El proceso implica escanear el documento, identificar la estructura de la tabla y extraer los datos. En este ejemplo, usaremos el archivo 'invoiceTable.pdf' para mostrar cómo IronOCR recupera toda la información de la factura.

El método ReadDocumentAdvanced requiere que el paquete IronOcr.Extensions.AdvancedScan esté instalado junto con el paquete base de IronOCR.

@@--SOPORTE-i-ABIERTO--@@ 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. Aprende más 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. Los resultados se muestran a continuación. Es importante señalar que, dado que este método se centra en la información delimitada por bordes, cualquier celda fusionada que abarque múltiples filas se tratará como una sola celda.

Resultado

Leer tabla en documento

Clase auxiliar

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. 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

Preguntas Frecuentes

¿Cómo puedo mejorar la extracción de datos de tablas en documentos usando C#?

Puede mejorar la extracción de datos de tablas en documentos usando C# al utilizar el modelo de aprendizaje automático de IronOCR, que está específicamente entrenado para detectar y extraer datos complejos de tablas con precisión. Este enfoque es más efectivo que usar herramientas estándar de OCR como Tesseract.

¿Cuál es el propósito del método `ReadDocumentAdvanced` en IronOCR?

El método `ReadDocumentAdvanced` en IronOCR está diseñado para manejar tablas complejas proporcionando resultados robustos a través de un análisis efectivo y extracción de datos. Es particularmente útil para tratar con tablas de estructuras intrincadas.

¿Cómo puedo comenzar con la extracción de tablas usando IronOCR?

Para comenzar a extraer tablas usando IronOCR, descargue la biblioteca de C#, prepare su documento, habilite la detección de tablas configurando la propiedad ReadDataTables y utilice el método ReadDocumentAdvanced para tablas complejas.

¿Qué paquete adicional se requiere para la extracción avanzada de tablas en IronOCR?

La extracción avanzada de tablas en IronOCR requiere el paquete `IronOcr.Extensions.AdvancedScan`, que es específico para Windows, para manejar de manera efectiva las estructuras complejas de tablas.

¿Cómo puedo organizar los datos extraídos de las tablas usando IronOCR?

IronOCR proporciona métodos auxiliares para organizar los datos extraídos de las tablas por coordenadas, permitiéndole procesar múltiples tablas y extraer filas específicas por índice para una mejor gestión de los datos.

¿Qué metadatos se incluyen en las celdas de tabla extraídas usando IronOCR?

Las celdas de tabla extraídas usando IronOCR incluyen metadatos como coordenadas X e Y, dimensiones de la celda y el contenido de texto dentro de cada celda, permitiendo un análisis y organización de datos detallados.

¿Cómo puedo asegurar la compatibilidad con .NET Framework al usar IronOCR para la extracción de tablas?

Para asegurar la compatibilidad con .NET Framework, asegúrese de que su proyecto se ejecute en la arquitectura x64 y desmarque la opción 'Preferir 32 bits' en la configuración del proyecto al usar IronOCR para la extracción de tablas.

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,167,857 | Version: 2025.11 recién lanzado