跳至頁尾內容
USING IRONOCR

發票 OCR API 開發者教學

發票OCR API使用機器學習自動化發票資料提取,消除手動輸入錯誤,同時準確捕捉供應商詳細資訊、發票號碼和價格,適用於數位和掃描文件。 本教程展示了如何使用IronOCR建立發票OCR解決方案。

透過利用機器學習和電腦視覺,發票OCR技術將發票資料轉換為可自動化處理的格式。 您將學習如何解決常見挑戰,如手動資料輸入延遲、成本和錯誤,同時從任何發票格式中準確提取供應商資訊、發票號碼和價格。

本文使用IronOCR,這是.NET開發者首選的發票OCR API。

什麼是IronOCR?

由Iron Software開發的IronOCR為開發者提供全面的OCR工具。 其利用機器學習和電腦視覺從掃描文件、圖像和PDF中提取文字,實現自動化處理。 其API無縫整合多種語言和平台,減少人工資料輸入錯誤並提高效率。 提取的資料直接流入現有系統,用於分析和決策。 如圖像預處理條碼識別及靈活的文件解析等功能增強了其多功能性。 IronOCR使開發者能夠將強大的文字識別功能整合到他們的應用中。

該程式庫透過專用的語言包支持125種國際語言,使其成為全球發票處理的理想選擇。 進階功能包括自動找到文字的電腦視覺,特別適合布局多變的發票。 此外,IronOCR提供多執行緒處理能力,以高效處理大批量發票處理。

為什麼我應該選擇IronOCR進行發票處理?

IronOCR為發票處理應用提供了引人注目的優勢。 首先,通過優化的Tesseract 5 引擎,它提供了卓越的準確性,專門針對.NET應用改進。 該程式庫處理各種發票格式,從掃描文件PDF文件,甚至是低質量掃描

內建的圖像優化過濾器在處理前自動增強圖像質量,從而獲得更準確的文字提取。 對於有特定需求的發票,IronOCR支持自定義語言訓練,允許對常見於您發票型別的特殊字體或格式進行優化。

IronOCR與其他OCR程式庫有什麼不同?

IronOCR通過簡單的一行OCR功能而保持企業級的功能從而區分於其他程式庫。 與原始Tesseract實現不同,IronOCR提供了一個託管的.NET API,可無縫處理複雜操作。 該程式庫針對各種文件型別提供專用的文件閱讀方法,包括專門支持閱讀文件中的表格,對於發票行項目至關重要。

過濾精靈自動確定最佳的預處理設置,消除此類圖像優化上的猜測工作。 IronOCR還提供全面的除錯功能,允許開發者可視化OCR引擎所見,並有效排除提取問題。

我需要哪些先決條件?

在使用IronOCR之前,請確保這些先決條件已到位:

  1. 配備一個適宜的開發環境,如安裝了Visual Studio的IDE
  2. 對C#程式設計有基本了解以有效理解和修改程式碼範例
  3. 通過NuGet Package Manager或命令行將IronOCR程式庫安裝到您的專案中

滿足這些先決條件後,您將能順利進行IronOCR的工作。

IronOCR提供了WindowsLinuxmacOS的全面設置指南。 該程式庫支持雲端部署,具備具體的AWS LambdaAzure Functions教程。

我應該使用哪個版本的Visual Studio?

IronOCR支持從2017到最新版本的Visual Studio。 為了實現最佳相容性及使用最新的C#功能,建議使用Visual Studio 2019或2022。 該程式庫完全相容於.NET Framework, .NET Core, 和.NET 5+,確保了您的開發環境靈活性。

對於跨平台開發,帶有C#擴展的Visual Studio Code效果良好。 移動開發者可以利用IronOCR提供的AndroidiOS實現指南,使其適合於.NET MAUI 應用

我需要什麼樣的C#知識水平?

中級C#知識足以進行基本的發票OCR實施。 您應該對以下內容感到舒適:

IronOCR的直觀API設計意味著不需要對圖像處理或機器學習有深厚的專業知識。 該程式庫內部處理複雜的操作,讓您可以專注於業務邏輯。 初學者可以從簡單的OCR範例開始。

我如何建立一個新Visual Studio專案?

要開始使用IronOCR,首先建立一個新的Visual Studio專案。

打開Visual Studio,進入文件,停留在"新建",然後點擊"專案"。

 Visual Studio IDE顯示檔案選單打開,突出顯示 新项目

在新窗口中,選擇控制台應用程式並點擊下一步。

 Visual Studio的 控制台應用

出現新窗口。 輸入您的專案名稱及位置,然後點擊下一步。

 Visual Studio新的專案配置窗口,顯示為控制台應用名為 專案配置

最後,選擇目標框架並點擊建立。

 Visual Studio專案建立向導顯示 目標框架

您新的Visual Studio專案已準備就緒。 讓我們安裝IronOCR。

哪種專案型別最適合OCR應用?

雖然本教程為簡化使用了一個控制台應用程式,但IronOCR支持多種專案型別:

  • 控制台應用程式:理想的批處理或命令行工具
  • Web 應用程式:完美用于構建API或基於Web的服務
  • Windows表單/WPF:適合具有GUI的桌面應用程式
  • .NET MAUI應用:適合跨平台解決方案

對於大批量處理,考慮在Windows服務或微服務架構中實現IronOCR。 該程式庫的進度追踪能力使得監控長時間運行的操作變得簡單。

我應該目標於哪個.NET框架版本?

IronOCR在.NET版本中提供了廣泛的相容性。 對於新專案,目標於.NET 6.0或更高版本以獲得最佳的性能及最新功能。 該程式庫保持極好的向後相容性:

  • .NET Framework 4.6.2+:適合於傳統企業應用程式
  • .NET Core 3.1:長期支持和穩定部署的選擇
  • .NET 5.0+:具有性能改進的現代框架
  • .NET標準2.0:跨平台最大的相容性

Docker容器中部署時,.NET 6.0或更高版本提供更小的映像大小和更好的性能。 對於Azure函式,.NET 6.0和.NET Framework都得到支持。

我如何安裝IronOCR?

下載和安裝IronOCR有兩個簡單的方法:

  1. Using Visual Studio NuGet Package Manager
  2. 使用Visual Studio命令行

我應該什麼時候使用NuGet Package Manager與命令行?

根據您的工作流程,在NuGet Package Manager GUI和命令行之間進行選擇:

NuGet Package Manager GUI最佳使用時間:

  • 您是NuGet套件新手
  • 您希望瀏覽IronOCR 語言包
  • 您偏好視覺確認
  • 正在管理多個包

命令行 (Package Manager Console)優勢:

  • 您習慣於命令介面
  • 您遵循腳本部署
  • 您需要快速獲取特定版本
  • 使用高級安裝選項

這兩個方法實現相同的結果——根據舒適度和要求進行選擇。

我可能需要哪些其他語言包?

IronOCR透過專用的包支持125種國際語言。 對於發票處理,考慮以下選項:

  • 商業專用包金融語言包,用於金融文件
  • 區域語言:基於發票來源(例如西班牙語、法語、德語)
  • 多語支持:用於多語發票
  • 自定義語言:用於專用字體或自定義訓練資料

語言包隨IronOCR主包一起安裝,並大幅提高對非英語文字的準確性。

使用Visual Studio NuGet Package Manager

使用Visual Studio NuGet Package Manager將IronOCR包含於您的C#專案中。

導航到工具 > NuGet套件管理器 > 為解決方案管理NuGet包

 Visual Studio IDE顯示NuGet包管理介面,IronOCR包搜索結果顯示安裝選項和包詳細資訊,用於設置發票OCR功能 NuGet套件管理器

在您的專案中搜索IronOCR並安裝包。

 NuGet包管理介面顯示IronOCR v2022.1.0及相關語言包,如阿拉伯語、希伯來語和西班牙語OCR功能,顯示每個專用識別包的版本號及描述 在NuGet套件管理器UI中選擇IronOCR包

使用相同的方法安裝額外的語言包。

使用Visual Studio命令行

  1. 在Visual Studio中,轉到工具 > NuGet套件管理器 > 套件管理器控制台
  2. 在套件管理器控制台中輸入以下命令:

    Install-Package IronOcr

 Visual Studio的Package Manager Console顯示'`Install-Package IronOcr`'命令的成功執行,演示了OCR庫的命令行安裝方法 套件管理器控制台

包將被下載並安裝到您的當前專案中,準備好使用。

我如何使用IronOCR從發票中提取資料?

使用IronOCR只需幾行程式碼即可輕鬆提取發票資料。 這取代了手工資料輸入並使您的工作流程更加流暢。

以下是用於文字提取的發票範例:

Sample invoice document displaying customer details, invoice number INV/2023/00039, three line items for cleaning services totaling $80.50, demonstrating a typical invoice format for OCR extraction 範例發票

讓我們從這張發票中提取所有資料:

using IronOcr;
using System;

// Initialize a new instance of the IronTesseract class
// This is the main OCR engine that will process our invoice
var ocr = new IronTesseract();

// Configure OCR settings for better invoice processing
ocr.Configuration.BlackListCharacters = "~`$#^*_}{]___PROTECTED_LINK_48___ method from ___PROTECTED_LINK_49___ class. Key enhancements include:

- **Image preprocessing**: ___PROTECTED_LINK_50___ corrects tilted scans; ___PROTECTED_LINK_51___ removes artifacts
- **Resolution enhancement**: Setting ___PROTECTED_LINK_52___ improves recognition
- **Character blacklisting**: Prevents common OCR misinterpretations
- **Confidence scoring**: Assesses extraction reliability

!___PROTECTED_LINK_53___
**Invoice Parser**

### How Do I Handle Different Invoice Formats?

Invoice formats vary between vendors, but IronOCR provides flexible solutions:

1. **Template-based**: Define ___PROTECTED_LINK_54___
2. **Computer vision**: Use ___PROTECTED_LINK_55___ to locate text
3. **Table extraction**: Leverage ___PROTECTED_LINK_56___ for line items
4. **Multi-format**: Process ___PROTECTED_LINK_57___, ___PROTECTED_LINK_58___, and ___PROTECTED_LINK_59___

For complex layouts, implement the ___PROTECTED_LINK_60___ which uses machine learning to identify structures automatically.

### What Are Common Extraction Patterns for Invoice Data?

Invoice data follows recognizable patterns extractable using regular expressions with OCR results:

```C#
using IronOCR;
using System;
using System.Text. `RegularExpressions`;
using System.Collections.Generic;

public class `InvoiceDataExtractor`
{
    private readonly `IronTesseract` ocr;

    public `InvoiceDataExtractor`()
    {
        ocr = new `IronTesseract`();
        // Configure for optimal invoice reading
        `ocr.Configuration`.`ReadBarcodes` = true; // Many invoices include barcodes
        `ocr.Configuration`.`TesseractVersion` = `TesseractVersion`.Tesseract5;
    }

    public `InvoiceData` `ExtractInvoiceData`(string imagePath)
    {
        var invoiceData = new `InvoiceData`();

        using (var input = new `OcrInput`(imagePath/))
        {
            // Apply filters for better accuracy
            input.`EnhanceResolution`(300/);
            `input.Sharpen`();

            var result = `ocr.Read`(input/);
            var text = `result.Text`;

            // Extract invoice number
            invoiceData.`InvoiceNumber` = `ExtractPattern`(text,
                @"INV[/-]?\d{4}[/-]?\d{5}|Invoice\s*#?\s*:?\s*(\d+)");

            // Extract dates
            invoiceData.`InvoiceDate` = `ExtractDate`(text,
                @"Invoice\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})");
            invoiceData.`DueDate` = `ExtractDate`(text,
                @"Due\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})");

            // Extract amounts
            `invoiceData.Total` = `ExtractAmount`(text,
                @"Total\s*:?\s*\$?\s*([\d,]+\.?\d*)");
            `invoiceData.Tax` = `ExtractAmount`(text,
                @"Tax\s*:?\s*\$?\s*([\d,]+\.?\d*)");

            // Extract vendor information
            invoiceData.`VendorName` = `ExtractVendorName`(text/);

            // Extract line items using table detection
            invoiceData.`LineItems` = `ExtractLineItems`(result/);

            // Extract any barcodes found
            if (`result.Barcodes`.Length > 0)
            {
                invoiceData.`BarcodeValues` = new List<string>();
                foreach (var barcode in `result.Barcodes`)
                {
                    invoiceData.`BarcodeValues`.Add(`barcode.Value`);
                }
            }
        }

        return invoiceData;
    }

    private string `ExtractPattern`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        return `match.Success` ? `match.Value` : `string.Empty`;
    }

    private `DateTime`? `ExtractDate`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        if (`match.Success` && `match.Groups`.Count > 1)
        {
            if (`DateTime`.`TryParse`(`match.Groups`[1].Value, out `DateTime` date))
                return date;
        }
        return null;
    }

    private decimal `ExtractAmount`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        if (`match.Success` && `match.Groups`.Count > 1)
        {
            var amountStr = `match.Groups`[1].Value.Replace(",", "");
            if (decimal.`TryParse`(amountStr, out decimal amount))
                return amount;
        }
        return 0;
    }

    private string `ExtractVendorName`(string text)
    {
        // Usually the vendor name appears in the first few lines
        var lines = `text.Split`('\n'/);
        if (`lines.Length` > 0)
        {
            // Simple heuristic: first non-empty line that's not a common header
            foreach (var line in lines)
            {
                var trimmed = `line.Trim`();
                if (!string.`IsNullOrEmpty`(trimmed/) &&
                    !trimmed.`ToLower`().Contains("invoice") &&
                    `trimmed.Length` > 3)
                {
                    return trimmed;
                }
            }
        }
        return `string.Empty`;
    }

    private List<`LineItem`> `ExtractLineItems`(`OcrResult` result)
    {
        var lineItems = new List<`LineItem`>();

        // Use IronOCR's table detection capabilities
        if (`result.Tables` != null && `result.Tables`.Count > 0)
        {
            foreach (var table in `result.Tables`)
            {
                // Process each row as a potential line item
                for (int i = 1; i < table.`RowCount`; i++) // Skip header row
                {
                    var item = new `LineItem`
                    {
                        Description = table[i, 0]?.Text ?? "",
                        Quantity = `ParseQuantity`(table[i, 1]?.Text),
                        `UnitPrice` = `ParseAmount`(table[i, 2]?.Text),
                        Total = `ParseAmount`(table[i, 3]?.Text)
                    };

                    if (!string.`IsNullOrEmpty`(`item.Description`/))
                        `lineItems.Add`(item/);
                }
            }
        }

        return lineItems;
    }

    private int `ParseQuantity`(string text)
    {
        if (string.`IsNullOrEmpty`(text/)) return 0;
        var cleaned = Regex.Replace(text, @"[^\d]", "");
        return int.`TryParse`(cleaned, out int qty) ? qty : 0;
    }

    private decimal `ParseAmount`(string text)
    {
        if (string.`IsNullOrEmpty`(text/)) return 0;
        var cleaned = Regex.Replace(text, @"[^\d.]", "");
        return decimal.`TryParse`(cleaned, out decimal amt) ? amt : 0;
    }
}

// Data classes for structured invoice information
public class `InvoiceData`
{
    public string `InvoiceNumber` { get; set; }
    public `DateTime`? `InvoiceDate` { get; set; }
    public `DateTime`? `DueDate` { get; set; }
    public string `VendorName` { get; set; }
    public decimal Total { get; set; }
    public decimal Tax { get; set; }
    public List<`LineItem`> `LineItems` { get; set; }
    public List<string> `BarcodeValues` { get; set; }
}

public class `LineItem`
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal `UnitPrice` { get; set; }
    public decimal Total { get; set; }
}
using IronOcr;
using System;

// Initialize a new instance of the IronTesseract class
// This is the main OCR engine that will process our invoice
var ocr = new IronTesseract();

// Configure OCR settings for better invoice processing
ocr.Configuration.BlackListCharacters = "~`$#^*_}{]___PROTECTED_LINK_48___ method from ___PROTECTED_LINK_49___ class. Key enhancements include:

- **Image preprocessing**: ___PROTECTED_LINK_50___ corrects tilted scans; ___PROTECTED_LINK_51___ removes artifacts
- **Resolution enhancement**: Setting ___PROTECTED_LINK_52___ improves recognition
- **Character blacklisting**: Prevents common OCR misinterpretations
- **Confidence scoring**: Assesses extraction reliability

!___PROTECTED_LINK_53___
**Invoice Parser**

### How Do I Handle Different Invoice Formats?

Invoice formats vary between vendors, but IronOCR provides flexible solutions:

1. **Template-based**: Define ___PROTECTED_LINK_54___
2. **Computer vision**: Use ___PROTECTED_LINK_55___ to locate text
3. **Table extraction**: Leverage ___PROTECTED_LINK_56___ for line items
4. **Multi-format**: Process ___PROTECTED_LINK_57___, ___PROTECTED_LINK_58___, and ___PROTECTED_LINK_59___

For complex layouts, implement the ___PROTECTED_LINK_60___ which uses machine learning to identify structures automatically.

### What Are Common Extraction Patterns for Invoice Data?

Invoice data follows recognizable patterns extractable using regular expressions with OCR results:

```C#
using IronOCR;
using System;
using System.Text. `RegularExpressions`;
using System.Collections.Generic;

public class `InvoiceDataExtractor`
{
    private readonly `IronTesseract` ocr;

    public `InvoiceDataExtractor`()
    {
        ocr = new `IronTesseract`();
        // Configure for optimal invoice reading
        `ocr.Configuration`.`ReadBarcodes` = true; // Many invoices include barcodes
        `ocr.Configuration`.`TesseractVersion` = `TesseractVersion`.Tesseract5;
    }

    public `InvoiceData` `ExtractInvoiceData`(string imagePath)
    {
        var invoiceData = new `InvoiceData`();

        using (var input = new `OcrInput`(imagePath/))
        {
            // Apply filters for better accuracy
            input.`EnhanceResolution`(300/);
            `input.Sharpen`();

            var result = `ocr.Read`(input/);
            var text = `result.Text`;

            // Extract invoice number
            invoiceData.`InvoiceNumber` = `ExtractPattern`(text,
                @"INV[/-]?\d{4}[/-]?\d{5}|Invoice\s*#?\s*:?\s*(\d+)");

            // Extract dates
            invoiceData.`InvoiceDate` = `ExtractDate`(text,
                @"Invoice\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})");
            invoiceData.`DueDate` = `ExtractDate`(text,
                @"Due\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})");

            // Extract amounts
            `invoiceData.Total` = `ExtractAmount`(text,
                @"Total\s*:?\s*\$?\s*([\d,]+\.?\d*)");
            `invoiceData.Tax` = `ExtractAmount`(text,
                @"Tax\s*:?\s*\$?\s*([\d,]+\.?\d*)");

            // Extract vendor information
            invoiceData.`VendorName` = `ExtractVendorName`(text/);

            // Extract line items using table detection
            invoiceData.`LineItems` = `ExtractLineItems`(result/);

            // Extract any barcodes found
            if (`result.Barcodes`.Length > 0)
            {
                invoiceData.`BarcodeValues` = new List<string>();
                foreach (var barcode in `result.Barcodes`)
                {
                    invoiceData.`BarcodeValues`.Add(`barcode.Value`);
                }
            }
        }

        return invoiceData;
    }

    private string `ExtractPattern`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        return `match.Success` ? `match.Value` : `string.Empty`;
    }

    private `DateTime`? `ExtractDate`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        if (`match.Success` && `match.Groups`.Count > 1)
        {
            if (`DateTime`.`TryParse`(`match.Groups`[1].Value, out `DateTime` date))
                return date;
        }
        return null;
    }

    private decimal `ExtractAmount`(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, `RegexOptions`.`IgnoreCase`);
        if (`match.Success` && `match.Groups`.Count > 1)
        {
            var amountStr = `match.Groups`[1].Value.Replace(",", "");
            if (decimal.`TryParse`(amountStr, out decimal amount))
                return amount;
        }
        return 0;
    }

    private string `ExtractVendorName`(string text)
    {
        // Usually the vendor name appears in the first few lines
        var lines = `text.Split`('\n'/);
        if (`lines.Length` > 0)
        {
            // Simple heuristic: first non-empty line that's not a common header
            foreach (var line in lines)
            {
                var trimmed = `line.Trim`();
                if (!string.`IsNullOrEmpty`(trimmed/) &&
                    !trimmed.`ToLower`().Contains("invoice") &&
                    `trimmed.Length` > 3)
                {
                    return trimmed;
                }
            }
        }
        return `string.Empty`;
    }

    private List<`LineItem`> `ExtractLineItems`(`OcrResult` result)
    {
        var lineItems = new List<`LineItem`>();

        // Use IronOCR's table detection capabilities
        if (`result.Tables` != null && `result.Tables`.Count > 0)
        {
            foreach (var table in `result.Tables`)
            {
                // Process each row as a potential line item
                for (int i = 1; i < table.`RowCount`; i++) // Skip header row
                {
                    var item = new `LineItem`
                    {
                        Description = table[i, 0]?.Text ?? "",
                        Quantity = `ParseQuantity`(table[i, 1]?.Text),
                        `UnitPrice` = `ParseAmount`(table[i, 2]?.Text),
                        Total = `ParseAmount`(table[i, 3]?.Text)
                    };

                    if (!string.`IsNullOrEmpty`(`item.Description`/))
                        `lineItems.Add`(item/);
                }
            }
        }

        return lineItems;
    }

    private int `ParseQuantity`(string text)
    {
        if (string.`IsNullOrEmpty`(text/)) return 0;
        var cleaned = Regex.Replace(text, @"[^\d]", "");
        return int.`TryParse`(cleaned, out int qty) ? qty : 0;
    }

    private decimal `ParseAmount`(string text)
    {
        if (string.`IsNullOrEmpty`(text/)) return 0;
        var cleaned = Regex.Replace(text, @"[^\d.]", "");
        return decimal.`TryParse`(cleaned, out decimal amt) ? amt : 0;
    }
}

// Data classes for structured invoice information
public class `InvoiceData`
{
    public string `InvoiceNumber` { get; set; }
    public `DateTime`? `InvoiceDate` { get; set; }
    public `DateTime`? `DueDate` { get; set; }
    public string `VendorName` { get; set; }
    public decimal Total { get; set; }
    public decimal Tax { get; set; }
    public List<`LineItem`> `LineItems` { get; set; }
    public List<string> `BarcodeValues` { get; set; }
}

public class `LineItem`
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal `UnitPrice` { get; set; }
    public decimal Total { get; set; }
}
Imports IronOcr
Imports System
Imports System.Text.RegularExpressions
Imports System.Collections.Generic

Public Class InvoiceDataExtractor
    Private ReadOnly ocr As IronTesseract

    Public Sub New()
        ocr = New IronTesseract()
        ' Configure for optimal invoice reading
        ocr.Configuration.ReadBarcodes = True ' Many invoices include barcodes
        ocr.Configuration.TesseractVersion = TesseractVersion.Tesseract5
    End Sub

    Public Function ExtractInvoiceData(imagePath As String) As InvoiceData
        Dim invoiceData As New InvoiceData()

        Using input As New OcrInput(imagePath)
            ' Apply filters for better accuracy
            input.EnhanceResolution(300)
            input.Sharpen()

            Dim result = ocr.Read(input)
            Dim text = result.Text

            ' Extract invoice number
            invoiceData.InvoiceNumber = ExtractPattern(text, "INV[/-]?\d{4}[/-]?\d{5}|Invoice\s*#?\s*:?\s*(\d+)")

            ' Extract dates
            invoiceData.InvoiceDate = ExtractDate(text, "Invoice\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})")
            invoiceData.DueDate = ExtractDate(text, "Due\s*Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})")

            ' Extract amounts
            invoiceData.Total = ExtractAmount(text, "Total\s*:?\s*\$?\s*([\d,]+\.?\d*)")
            invoiceData.Tax = ExtractAmount(text, "Tax\s*:?\s*\$?\s*([\d,]+\.?\d*)")

            ' Extract vendor information
            invoiceData.VendorName = ExtractVendorName(text)

            ' Extract line items using table detection
            invoiceData.LineItems = ExtractLineItems(result)

            ' Extract any barcodes found
            If result.Barcodes.Length > 0 Then
                invoiceData.BarcodeValues = New List(Of String)()
                For Each barcode In result.Barcodes
                    invoiceData.BarcodeValues.Add(barcode.Value)
                Next
            End If
        End Using

        Return invoiceData
    End Function

    Private Function ExtractPattern(text As String, pattern As String) As String
        Dim match = Regex.Match(text, pattern, RegexOptions.IgnoreCase)
        Return If(match.Success, match.Value, String.Empty)
    End Function

    Private Function ExtractDate(text As String, pattern As String) As DateTime?
        Dim match = Regex.Match(text, pattern, RegexOptions.IgnoreCase)
        If match.Success AndAlso match.Groups.Count > 1 Then
            Dim dateValue As DateTime
            If DateTime.TryParse(match.Groups(1).Value, dateValue) Then
                Return dateValue
            End If
        End If
        Return Nothing
    End Function

    Private Function ExtractAmount(text As String, pattern As String) As Decimal
        Dim match = Regex.Match(text, pattern, RegexOptions.IgnoreCase)
        If match.Success AndAlso match.Groups.Count > 1 Then
            Dim amountStr = match.Groups(1).Value.Replace(",", "")
            Dim amount As Decimal
            If Decimal.TryParse(amountStr, amount) Then
                Return amount
            End If
        End If
        Return 0
    End Function

    Private Function ExtractVendorName(text As String) As String
        ' Usually the vendor name appears in the first few lines
        Dim lines = text.Split(ControlChars.Lf)
        If lines.Length > 0 Then
            ' Simple heuristic: first non-empty line that's not a common header
            For Each line In lines
                Dim trimmed = line.Trim()
                If Not String.IsNullOrEmpty(trimmed) AndAlso
                   Not trimmed.ToLower().Contains("invoice") AndAlso
                   trimmed.Length > 3 Then
                    Return trimmed
                End If
            Next
        End If
        Return String.Empty
    End Function

    Private Function ExtractLineItems(result As OcrResult) As List(Of LineItem)
        Dim lineItems As New List(Of LineItem)()

        ' Use IronOCR's table detection capabilities
        If result.Tables IsNot Nothing AndAlso result.Tables.Count > 0 Then
            For Each table In result.Tables
                ' Process each row as a potential line item
                For i As Integer = 1 To table.RowCount - 1 ' Skip header row
                    Dim item As New LineItem With {
                        .Description = If(table(i, 0)?.Text, ""),
                        .Quantity = ParseQuantity(table(i, 1)?.Text),
                        .UnitPrice = ParseAmount(table(i, 2)?.Text),
                        .Total = ParseAmount(table(i, 3)?.Text)
                    }

                    If Not String.IsNullOrEmpty(item.Description) Then
                        lineItems.Add(item)
                    End If
                Next
            Next
        End If

        Return lineItems
    End Function

    Private Function ParseQuantity(text As String) As Integer
        If String.IsNullOrEmpty(text) Then Return 0
        Dim cleaned = Regex.Replace(text, "[^\d]", "")
        Dim qty As Integer
        Return If(Integer.TryParse(cleaned, qty), qty, 0)
    End Function

    Private Function ParseAmount(text As String) As Decimal
        If String.IsNullOrEmpty(text) Then Return 0
        Dim cleaned = Regex.Replace(text, "[^\d.]", "")
        Dim amt As Decimal
        Return If(Decimal.TryParse(cleaned, amt), amt, 0)
    End Function
End Class

' Data classes for structured invoice information
Public Class InvoiceData
    Public Property InvoiceNumber As String
    Public Property InvoiceDate As DateTime?
    Public Property DueDate As DateTime?
    Public Property VendorName As String
    Public Property Total As Decimal
    Public Property Tax As Decimal
    Public Property LineItems As List(Of LineItem)
    Public Property BarcodeValues As List(Of String)
End Class

Public Class LineItem
    Public Property Description As String
    Public Property Quantity As Integer
    Public Property UnitPrice As Decimal
    Public Property Total As Decimal
End Class
$vbLabelText   $csharpLabel

通過發票處理從發票中提取特定數據

使用此代碼提取特定的發票數據,如客戶發票號碼:

``C# using IronOCR; using System; using System.Text.RegularExpressions`;

// 初始化IronTesseract類的一個新實例 var ocr = new IronTesseract();

// 使用OcrInput物件載入圖像文件 using (var input = new OcrInput(@"r2.png"/)) { // 對圖像執行OCR var result = ocr.Read(input/);

// 定義用於發票號碼的正則表達式模式
var linePattern = @"INV\/\d{4}\/\d{5}";

// 在提取的文字中匹配該模式
var lineMatch = Regex.Match(`result.Text`, linePattern);

// 檢查該模式是否與文字的任何部分匹配
if (`lineMatch.Success`)
{
    // 如果發現匹配,則列印發票號碼
    var lineValue = `lineMatch.Value`;
    Console. `WriteLine`("客戶發票號碼: " + lineValue);
}

}



![ Visual Studio除錯控制台顯示使用IronOCR提取的客戶發票號碼INV/2023/00039成功生成PDF,確認OCR流程無錯誤完成 ](/static-assets/ocr/blog/invoice-ocr-api-tutorial/invoice-ocr-api-tutorial-10.webp)
**發票掃描**

對於複雜的提取情境,使用[專用的OCR配置](/csharp/ocr/examples/csharp-configure-setup-tesseract/)以針對您的發票型別進行優化。[OcrResult類](/csharp/ocr/examples/results-objects/)提供有關每個識別元素的詳細資訊,包括驗證的坐標和信心分數。

## 發票OCR API的主要優勢是什麼?

IronOCR的發票OCR API通過機器學習和電腦視覺改變了發票處理。 這項技術將發票文字轉化為機器可讀格式,簡化了用於分析、整合和流程改進的資料提取。 它為發票處理提供強大的自動化,提高了準確性並優化了工作流程,如應付賬款。

IronOCR使用優化的Tesseract結果,不需額外配置即可提供卓越的準確性。 它支持[多頁框架TIFF](/csharp/ocr/how-to/input-tiff-gif/)、[PDF文件](/csharp/ocr/how-to/input-pdfs/)和所有流行的圖像格式。 [圖像條碼閱讀](/csharp/ocr/how-to/barcodes/)增加了另一種提取維度。

發票處理的主要優勢:

1. **節省時間**:從幾小時縮短為幾秒
2. **準確性**:通過[信心評分](/csharp/ocr/how-to/tesseract-result-confidence/)最大程度減少錯誤
3. **可擴展性**:通過[多執行緒](/csharp/ocr/how-to/async/)處理數千條記錄
4. **整合**:導出為可搜尋的PDF或[結構化格式](/csharp/ocr/how-to/read-results/)
5. **降低成本**:降低運營成本

該程式庫的[部署靈活性](/csharp/ocr/features/languages/)可整合於在本地、雲端或混合系統中。 通過支持[Docker](/csharp/ocr/get-started/docker/)、[Azure](/csharp/ocr/get-started/azure/)和[AWS](/csharp/ocr/get-started/aws/),IronOCR可隨需求擴展。

生產環境從IronOCR的[許可選項](/csharp/ocr/licensing/)中獲益,包括專用支持和[定期更新](/csharp/ocr/product-updates/changelog/)。 該程式庫的[疑難解答指南](/csharp/ocr/troubleshooting/general-troubleshooting-ocr/)和[工程支持](/csharp/ocr/troubleshooting/engineering-request-ocr/)確保順利實施。

存取[主頁](/csharp/ocr/)以獲取IronOCR的更多資訊。 有關其他發票OCR教程,請參見這份[詳細的發票OCR指南](/csharp/ocr/blog/using-ironocr/invoice-ocr-csharp-tutorial/)。 要了解如何使用電腦視覺進行發票欄位檢查,請查看這份[電腦視覺教程](/csharp/ocr/how-to/computer-vision/)。

常見問題

如何使用OCR自動化發票資料處理?

您可以使用IronOCR通過利用其機器學習演算法自動化發票資料處理。IronOCR提取的細節包括供應商資訊、發票編號和價格,減少手動輸入錯誤並提高效率。

設置發票OCR API涉及哪些步驟?

要使用IronOCR設置發票OCR API,首先要通過Visual Studio的NuGet套件管理器下載並安裝程式庫。接著,建立一個新的C#專案,整合IronOCR,並使用其方法載入和讀取圖片檔案以進行文字提取。

IronOCR可以提取特定資料,比如發票編號嗎?

可以,IronOCR可以提取如發票編號等特定資料。它利用正則表達式來匹配提取文字中的模式,使您能從發票中獲取特定資訊。

IronOCR有哪些功能可以使發票處理受益?

IronOCR包括圖像預處理、條碼識別和檔案解析等功能。這些功能增強了其準確地從各種發票格式中提取和處理文字的能力,提高了資料捕獲和工作流程的效率。

圖像預處理如何提高OCR結果?

IronOCR中的圖像預處理通過在文字提取前優化圖片品質來提高OCR結果。這包括對比度調整和降噪操作,這可以提高從發票中提取的資料的準確性。

有可能同時處理數位和掃描的發票嗎?

是的,IronOCR能夠處理數位和掃描的發票。它使用先進的機器學習和計算機視覺技術,從不同的格式和圖片品質中準確提取文字。

IronOCR如何處理多頁格式和檔案型別?

IronOCR支持多頁格式以及流行的圖片和PDF檔案型別。它能有效地從複雜的文件中提取文字,使其在各種發票處理應用中具有多功能性。

開發者可以在哪裡找到使用IronOCR的教程?

開發者可以在IronOCR網站上找到教程和其他資源。該網站提供一系列學習材料,包括如何指導和部落格文章,以便在不同的情境下應用IronOCR。

Kannaopat Udonpant
軟體工程師
在成為軟體工程師之前,Kannapat在日本北海道大學完成了環境資源博士學位。在攻讀學位期間,Kannapat還成為車輛機器人實驗室的一員,該實驗室隸屬於生產工程系。在2022年,他憑藉C#技能加入了Iron Software的工程團隊,專注於IronPDF。Kannapat珍視他的工作,因為他能直接向撰寫大部分IronPDF程式碼的開發者學習。除了同儕學習,Kannapat還喜歡在Iron Software工作的社交方面。不寫程式碼或文件時,Kannapat通常在他的PS5上玩遊戲或重看The Last of Us。

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話