invoice-recognizer 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +232 -0
- package/package.json +4 -7
package/README.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Invoice Recognizer
|
|
2
|
+
|
|
3
|
+
纯前端发票识别库 —— 输入图片或 PDF,输出结构化发票字段。基于 **PaddleOCR (PP-OCRv6 Tiny) + ONNX Runtime WebAssembly**,所有数据在浏览器本地处理,**不上传任何图片或文本到服务器**。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install invoice-recognizer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 快速使用
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import { InvoiceRecognizer } from 'invoice-recognizer'
|
|
15
|
+
|
|
16
|
+
const recognizer = new InvoiceRecognizer({
|
|
17
|
+
onProgress: (percent, message) => {
|
|
18
|
+
console.log(`${percent}% - ${message}`)
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
// 支持 JPG/PNG/WEBP 图片和 PDF
|
|
23
|
+
const result = await recognizer.recognize(file)
|
|
24
|
+
|
|
25
|
+
console.log(result)
|
|
26
|
+
// {
|
|
27
|
+
// invoiceType: '电子发票(普通发票)',
|
|
28
|
+
// invoiceNumber: '26537000000323134919',
|
|
29
|
+
// invoiceDate: '2026-06-24',
|
|
30
|
+
// buyerName: '杭州屹道科技有限公司',
|
|
31
|
+
// buyerTaxId: '91330109MA2CE7K12U',
|
|
32
|
+
// sellerName: '昆明盛智易联科技有限公司',
|
|
33
|
+
// sellerTaxId: '91530121MA6N3KEW02',
|
|
34
|
+
// totalAmount: '109.71',
|
|
35
|
+
// taxAmount: '3.29',
|
|
36
|
+
// taxRate: '3%',
|
|
37
|
+
// totalWithTax: '113.00',
|
|
38
|
+
// items: [],
|
|
39
|
+
// rawText: '...'
|
|
40
|
+
// }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## API
|
|
44
|
+
|
|
45
|
+
### `new InvoiceRecognizer(options)`
|
|
46
|
+
|
|
47
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
48
|
+
|------|------|--------|------|
|
|
49
|
+
| `onProgress` | `function(percent, message)` | `null` | 识别进度回调 |
|
|
50
|
+
| `assetsPath` | `string` | `''` | 模型文件所在路径前缀 |
|
|
51
|
+
| `wasmPath` | `string` | `'/ort/'` | ONNX Runtime WASM 路径 |
|
|
52
|
+
| `detModelFile` | `string` | `'PP-OCRv6_tiny_det_onnx_infer.tar'` | 检测模型文件名 |
|
|
53
|
+
| `recModelFile` | `string` | `'PP-OCRv6_tiny_rec_onnx_infer.tar'` | 识别模型文件名 |
|
|
54
|
+
| `pdfScale` | `number` | `1.5` | PDF 渲染缩放(1.5≈108 DPI) |
|
|
55
|
+
| `detLimitSideLen` | `number` | `480` | 检测模型最大边长,越小越快 |
|
|
56
|
+
|
|
57
|
+
### `recognizer.recognize(file)` → `InvoiceData`
|
|
58
|
+
|
|
59
|
+
输入 `File` 或 `Blob`,返回结构化发票对象。
|
|
60
|
+
|
|
61
|
+
### `InvoiceRecognizer.isValid(result)` → `boolean`
|
|
62
|
+
|
|
63
|
+
判断识别结果是否包含有效发票信息。
|
|
64
|
+
|
|
65
|
+
### `InvoiceRecognizer.dispose()`
|
|
66
|
+
|
|
67
|
+
销毁 OCR 实例,释放内存。
|
|
68
|
+
|
|
69
|
+
## 返回值 (InvoiceData)
|
|
70
|
+
|
|
71
|
+
| 字段 | 类型 | 提取方式 | 说明 |
|
|
72
|
+
|------|------|----------|------|
|
|
73
|
+
| `invoiceType` | `string` | 正则匹配 | 发票类型(增值税专用发票/电子发票等) |
|
|
74
|
+
| `invoiceCode` | `string` | 正则匹配 | 发票代码 |
|
|
75
|
+
| `invoiceNumber` | `string` | 正则匹配 | 发票号码 |
|
|
76
|
+
| `invoiceDate` | `string` | 正则匹配 | 开票日期(YYYY-MM-DD) |
|
|
77
|
+
| `checkCode` | `string` | 正则匹配 | 校验码 |
|
|
78
|
+
| `buyerName` | `string` | OCR 行解析 | 购买方名称 |
|
|
79
|
+
| `buyerTaxId` | `string` | 正则匹配 | 购买方税号 |
|
|
80
|
+
| `sellerName` | `string` | OCR 行解析 | 销售方名称 |
|
|
81
|
+
| `sellerTaxId` | `string` | 正则匹配 | 销售方税号 |
|
|
82
|
+
| `totalAmount` | `string` | 正则匹配 | 合计金额(不含税) |
|
|
83
|
+
| `taxAmount` | `string` | 正则匹配 | 税额 |
|
|
84
|
+
| `taxRate` | `string` | 多策略 + 交叉验证 | 税率(OCR 提取后自动用`税额÷金额`验证修正) |
|
|
85
|
+
| `totalWithTax` | `string` | 正则匹配 | 价税合计 |
|
|
86
|
+
| `items` | `array` | 保留字段 | 明细行信息 |
|
|
87
|
+
| `rawText` | `string` | 原始数据 | OCR 原始识别文本 |
|
|
88
|
+
|
|
89
|
+
> **税率校验**:如果 `taxRate` 与 `taxAmount / totalAmount` 的计算值偏差超过 0.5%,自动以计算值为准,避免 OCR 误判。
|
|
90
|
+
|
|
91
|
+
## 静态资源部署
|
|
92
|
+
|
|
93
|
+
所有模型和 WASM 文件需部署到 **同域路径** 下:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
public/
|
|
97
|
+
├── models/
|
|
98
|
+
│ ├── PP-OCRv6_tiny_det_onnx_infer.tar (1.7 MB)
|
|
99
|
+
│ └── PP-OCRv6_tiny_rec_onnx_infer.tar (4.3 MB)
|
|
100
|
+
├── ort/
|
|
101
|
+
│ ├── ort-wasm-simd-threaded.wasm (13 MB)
|
|
102
|
+
│ ├── ort-wasm-simd-threaded.mjs
|
|
103
|
+
│ ├── ort-wasm-simd-threaded.jsep.wasm (26 MB)
|
|
104
|
+
│ ├── ort-wasm-simd-threaded.jsep.mjs
|
|
105
|
+
│ └── ... (其他 WASM/MJS 文件)
|
|
106
|
+
└── pdf.worker.min.js (1 MB, PDF.js Worker)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
如果资源不在网站根目录,构造函数传入 `assetsPath`:
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
new InvoiceRecognizer({ assetsPath: '/my-app' })
|
|
113
|
+
// 会从 /my-app/models/... 查找模型
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Vue 2 插件
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
import Vue from 'vue'
|
|
120
|
+
import { InvoiceRecognizerPlugin } from 'invoice-recognizer'
|
|
121
|
+
|
|
122
|
+
Vue.use(InvoiceRecognizerPlugin, {
|
|
123
|
+
assetsPath: '',
|
|
124
|
+
wasmPath: '/ort/',
|
|
125
|
+
detLimitSideLen: 480,
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
// 组件内
|
|
129
|
+
this.$invoiceRecognizer.recognize(file).then(result => { ... })
|
|
130
|
+
|
|
131
|
+
// 或
|
|
132
|
+
this.$invoice.recognize(file).then(result => { ... })
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Vue 2 Demo
|
|
136
|
+
|
|
137
|
+
```vue
|
|
138
|
+
<template>
|
|
139
|
+
<div>
|
|
140
|
+
<input type="file" accept="image/*,.pdf" @change="onFile" />
|
|
141
|
+
<pre>{{ result }}</pre>
|
|
142
|
+
</div>
|
|
143
|
+
</template>
|
|
144
|
+
|
|
145
|
+
<script>
|
|
146
|
+
export default {
|
|
147
|
+
data: () => ({ result: null }),
|
|
148
|
+
methods: {
|
|
149
|
+
async onFile(e) {
|
|
150
|
+
this.result = await this.$invoiceRecognizer.recognize(e.target.files[0])
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
}
|
|
154
|
+
</script>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## webpack 4 / 旧版构建工具
|
|
158
|
+
|
|
159
|
+
该库内部包含动态加载的 WASM 和 MJS 文件,webpack 4 无法直接打包。
|
|
160
|
+
|
|
161
|
+
### 方案 A:纯静态引入(推荐)
|
|
162
|
+
|
|
163
|
+
```html
|
|
164
|
+
<!-- 1. 复制 node_modules/invoice-recognizer/* 到你的静态目录 -->
|
|
165
|
+
<!-- 2. 引入 UMD 文件 -->
|
|
166
|
+
<script src="/InvoiceRecognizer.umd.min.js"></script>
|
|
167
|
+
<script>
|
|
168
|
+
const r = new InvoiceRecognizer({
|
|
169
|
+
onProgress: (p, m) => console.log(`${p}% ${m}`)
|
|
170
|
+
})
|
|
171
|
+
r.recognize(file).then(console.log)
|
|
172
|
+
</script>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 方案 B:webpack 4 配合
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
// webpack.config.js
|
|
179
|
+
const CopyPlugin = require('copy-webpack-plugin')
|
|
180
|
+
|
|
181
|
+
module.exports = {
|
|
182
|
+
externals: { 'invoice-recognizer': 'InvoiceRecognizer' },
|
|
183
|
+
plugins: [
|
|
184
|
+
new CopyPlugin({
|
|
185
|
+
patterns: [
|
|
186
|
+
{ from: 'node_modules/invoice-recognizer/*.{js,mjs,wasm}', to: '[name][ext]' }
|
|
187
|
+
]
|
|
188
|
+
})
|
|
189
|
+
]
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## UMD / CDN
|
|
194
|
+
|
|
195
|
+
```html
|
|
196
|
+
<script src="https://unpkg.com/invoice-recognizer/InvoiceRecognizer.umd.min.js"></script>
|
|
197
|
+
<script>
|
|
198
|
+
const r = new InvoiceRecognizer()
|
|
199
|
+
</script>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
> 注意:CDN 方式仍需要自行部署模型文件和 WASM 运行时(见"静态资源部署")。
|
|
203
|
+
|
|
204
|
+
## 浏览器兼容性
|
|
205
|
+
|
|
206
|
+
需要支持 `WebAssembly` 和 `SharedArrayBuffer`。常见浏览器:
|
|
207
|
+
|
|
208
|
+
| 浏览器 | 支持情况 |
|
|
209
|
+
|--------|----------|
|
|
210
|
+
| Chrome 57+ | ✅ 支持 |
|
|
211
|
+
| Edge 79+ | ✅ 支持 |
|
|
212
|
+
| Firefox 52+ | ⚠️ WASM 正常,但部分后端需要 Chrome |
|
|
213
|
+
| Safari 15+ | ✅ 支持 |
|
|
214
|
+
| IE | ❌ 不支持 |
|
|
215
|
+
|
|
216
|
+
部署时需在响应头中添加(仅在 `devServer` 开发时需要,生产环境由服务器配置):
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
Cross-Origin-Opener-Policy: same-origin
|
|
220
|
+
Cross-Origin-Embedder-Policy: require-corp
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## 技术栈
|
|
224
|
+
|
|
225
|
+
- **OCR 引擎**: [PaddleOCR.js](https://www.npmjs.com/package/@paddleocr/paddleocr-js) (PP-OCRv6 Tiny)
|
|
226
|
+
- **深度学习运行时**: [ONNX Runtime Web](https://www.npmjs.com/package/onnxruntime-web)
|
|
227
|
+
- **PDF 渲染**: [pdfjs-dist](https://www.npmjs.com/package/pdfjs-dist)
|
|
228
|
+
- **后端**: WASM (自动降级),WebGPU (可用时自动启用)
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "invoice-recognizer",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "纯前端发票识别库 —— 输入图片/PDF
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "纯前端发票识别库 —— 输入图片/PDF,输出结构化发票字段",
|
|
5
5
|
"main": "InvoiceRecognizer.common.js",
|
|
6
6
|
"module": "InvoiceRecognizer.common.js",
|
|
7
7
|
"unpkg": "InvoiceRecognizer.umd.min.js",
|
|
8
8
|
"jsdelivr": "InvoiceRecognizer.umd.min.js",
|
|
9
9
|
"files": [
|
|
10
|
-
"InvoiceRecognizer.common.js",
|
|
11
|
-
"InvoiceRecognizer.umd.js",
|
|
12
|
-
"InvoiceRecognizer.umd.min.js",
|
|
13
|
-
"*.wasm",
|
|
14
|
-
"*.mjs",
|
|
15
10
|
"*.js",
|
|
11
|
+
"*.mjs",
|
|
12
|
+
"*.wasm",
|
|
16
13
|
"README.md"
|
|
17
14
|
],
|
|
18
15
|
"keywords": ["invoice","ocr","paddleocr","发票识别","frontend","browser"],
|