发票 OCR 识别 API 实战:自动提取发票信息(附完整接入示例:java\c#\PHP\Python))

39 阅读5分钟

在很多企业系统中,发票录入一直是一个高频但低效率的工作。本文从真实项目出发,讲解如何通过 OCR 技术实现发票信息自动识别,并给出完整 API 接入方案。


一、为什么企业需要发票 OCR?

在财务系统、报销系统、ERP 等场景中,发票数据录入通常需要人工完成:

  • 输入发票号码
  • 输入发票金额
  • 输入开票日期
  • 输入税额

如果每天处理几十甚至上百张发票,人工成本会非常高。

常见问题包括:

  • ❌ 人工录入效率低
  • ❌ 容易输入错误
  • ❌ 数据无法自动化

因此,越来越多系统开始使用 发票 OCR 自动识别


二、发票 OCR 能识别哪些信息?

一张发票通常包含很多结构化信息,例如:

  • 发票代码
  • 发票号码
  • 开票日期
  • 购买方名称
  • 销售方名称
  • 发票金额
  • 税额
  • 合计金额

OCR 系统不仅要识别文字,还需要:

  • 自动定位字段
  • 提取关键数据
  • 返回结构化 JSON

例如返回结果可能类似:

{
 "invoice_number": "12345678",
 "invoice_date": "2025-03-01",
 "total_amount": "1000.00",
 "tax_amount": "130.00"
}

三、发票 OCR 技术实现流程

完整流程通常包括以下步骤:

上传发票图片
      ↓
图像预处理
      ↓
文本检测
      ↓
文字识别
      ↓
字段结构化提取
      ↓
返回发票信息

其中最关键的是:

  • 文本检测
  • 文本识别
  • 结构化解析

如果全部自研,通常需要较长研发周期。


四、发票 OCR API 接入实战

为了快速实现自动识别,可以直接接入 OCR API。

接入流程通常很简单:

Step 1:上传发票图片

前端上传图片或PDF即可:

<input type="file" />

Step 2:调用 OCR API

如果你正在做系统集成,可以先参考接口文档(通常包含多语言示例):

image.png

下面是一个最小调用示例。


发票OCR识别 Python 示例

# Python 调用代码
# API 文档地址:https://market.shiliuai.com/doc/invoice-ocr
import requests
import base64
import json

# 请求接口
URL = "https://ocr-api.shiliuai.com/api/invoice_ocr/v1"

# 图片转base64
def get_base64(file_path):
    with open(file_path, 'rb') as f:
        data = f.read()
    b64 = base64.b64encode(data).decode('utf8')
    return b64

def demo(appcode, file_path):
    # 请求头
    headers = {
        'Authorization': 'APPCODE %s' % appcode,
        'Content-Type': 'application/json'
    }
    # 请求体
    b64 = get_base64(file_path)
    data = {"file_base64": b64}

    # 请求
    response = requests.post(url=URL, headers=headers, json=data)
    content = json.loads(response.content)
    print(content)

if __name__=="__main__":
    appcode = "你的APPCODE"
    file_path = "本地文件路径"
    demo(appcode, file_path)

发票OCR识别 Java 示例

// Java 示例
// API 文档地址:https://market.shiliuai.com/doc/invoice-ocr
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Base64;

public class Main {
    public static String get_base64(String path) {
        String b64 = "";
        try {
            // 使用Commons IO简化文件读取
            byte[] content = FileUtils.readFileToByteArray(new File(path));
            // 使用JDK自带的Base64
            b64 = Base64.getEncoder().encodeToString(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return b64;
    }

    public static void main(String[] args) {
        String url = "https://ocr-api.shiliuai.com/api/invoice_ocr/v1";// 请求接口
        String appcode = "你的APPCODE";
        String file_path = "本地文件路径";

        Map headers = new HashMap<>();
        headers.put("Authorization", "APPCODE " + appcode);
        headers.put("Content-Type", "application/json");

        // 请求体
        requestObj = new JSONObject();
        requestObj.put("file_base64", get_base64(file_path));
        String bodys = requestObj.toString();

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            for (Map.Entry entry : headers.entrySet()) {
                httpPost.addHeader(entry.getKey(), entry.getValue());
            }
            StringEntity entity = new StringEntity(bodys, "UTF-8");
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            int stat = response.getStatusLine().getStatusCode();
            if (stat != 200) {
                System.out.println("Http code: " + stat);
                return;
            }
            String res = EntityUtils.toString(response.getEntity());
            JSONObject res_obj = JSON.parseObject(res);
            System.out.println(res_obj.toJSONString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

PHP 示例

//  发票OCR识别 PHP 示例
//  API 文档:https://market.shiliuai.com/doc/invoice-ocr
function get_base64($path){
    if($fp = fopen($path, "rb", 0)) {
        $binary = fread($fp, filesize($path));// 文件读取
        fclose($fp);
        $b64 = base64_encode($binary);// 转base64
    }else{
        $b64="";
        printf("%s 文件不存在", $path);
    }
    return $b64;
}

$url = "https://ocr-api.shiliuai.com/api/invoice_ocr/v1";
$appcode = "你的appcode";
$file_path = "文件路径";
$method = "POST";

// 请求头
$headers = array();
array_push($headers, "Authorization:APPCODE " . $appcode);
array_push($headers, "Content-Type:application/json");

// 请求体
$b64 = get_base64($file_path);
$data = array(
    "file_base64" => $b64
);
$post_data = json_encode($data);

// 请求
$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_FAILONERROR, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);

$result = curl_exec($curl);
var_dump($result);

C# 示例

// 发票OCR识别 C# 示例
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace MyCSharpApp
{
    public class Program
    {
        public static string GetBase64(string path)
        {
            string b64 = "";
            try
            {
                // 读取文件内容
                byte[] content = File.ReadAllBytes(path);
                // 转换为Base64字符串
                b64 = Convert.ToBase64String(content);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return b64;
        }

        public static async Task Main(string[] args)
        {
            string url = "https://ocr-api.shiliuai.com/api/invoice_ocr/v1";// 请求接口
            string appcode = "你的APPCODE";
            string file_path = "本地文件路径";
            // 设置请求头 
            Dictionary headers = new Dictionary
            {
                { "Authorization", "APPCODE " + appcode }
                // Content-Type 将在创建 StringContent 时设置
            };
            // 请求体
            JObject requestObj = new JObject();
            requestObj["file_base64"] = GetBase64(file_path);
            string body = requestObj.ToString();

            try
            {
                using (HttpClient client = new HttpClient())
                {
                    // 设置请求头
                    foreach (var header in headers)
                    {
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                    }
                    // 创建请求内容 
                    StringContent content = new StringContent(body, Encoding.UTF8, "application/json");
                    // 发送请求并获取响应
                    HttpResponseMessage response = await client.PostAsync(url, content);
                    if (!response.IsSuccessStatusCode)
                    {
                        Console.WriteLine($"Http code: {(int)response.StatusCode}");
                        return;
                    }

                    // 读取响应内容
                    string responseContent = await response.Content.ReadAsStringAsync();
                    JObject resObj = JObject.Parse(responseContent);
                    Console.WriteLine(resObj.ToString(Formatting.Indented));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

五、识别结果如何使用?

识别成功后,系统可以自动完成:

  • 自动填充报销单
  • 自动录入财务系统
  • 自动归档发票数据

例如:

form.invoice_number = result.invoice_number
form.amount = result.total_amount

这样可以极大提升系统效率。


六、真实项目中的几个常见问题

在实际落地中,经常会遇到这些问题。

1️⃣ 发票图片不清晰

例如:

  • 手机拍摄模糊
  • 光线过暗
  • 图片压缩严重

建议:

  • 上传前压缩尺寸
  • 保持图片清晰

2️⃣ 发票版式不同

不同发票类型包括:

  • 增值税普通发票
  • 增值税专用发票
  • 电子发票

OCR 系统可以适配不同模板,基本全可以识别。


3️⃣ 批量处理需求

很多企业需要:

  • 批量上传发票
  • 自动识别
  • 自动归档

因此接口稳定性和并发能力非常重要。


七、在线工具 vs API 接入

不同场景适合不同方案。

在线工具

适合:

  • 临时识别
  • 手动使用
  • 少量图片

如果只是想快速测试效果,可以先在线识别一张发票看看(支持结构化导出发票内容为不同格式的文件,如ECXEL、WORD、PDF等)。

image.png


API 接入

适合:

  • 企业系统
  • 财务系统
  • 报销平台
  • 自动化流程

八、总结

发票 OCR 可以帮助企业实现:

  • 自动识别发票信息
  • 自动录入财务系统
  • 提高数据处理效率

随着 OCR 技术成熟,现在通过 API 接入即可快速实现自动化能力。

如果你的系统涉及:

  • 报销系统
  • 财务系统
  • ERP
  • RPA 自动化

发票 OCR 都是一个非常值得接入的基础能力。