使用PDF向量、Google Drive和数据库提取和存储发票数据
高级
这是一个Invoice Processing, AI Summarization, Multimodal AI领域的自动化工作流,包含 26 个节点。主要使用 If, Code, Slack, Webhook, Postgres 等节点。 使用PDF向量、Google Drive和数据库提取和存储发票数据
前置要求
- •Slack Bot Token 或 Webhook URL
- •HTTP Webhook 端点(n8n 会自动生成)
- •PostgreSQL 数据库连接信息
- •Google Drive API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "placeholder"
},
"nodes": [
{
"id": "overview-note",
"name": "工作流概览",
"type": "n8n-nodes-base.stickyNote",
"position": [
50,
50
],
"parameters": {
"color": 5,
"width": 350,
"height": 200,
"content": "## 📋 发票处理流水线"
},
"typeVersion": 1
},
{
"id": "setup-note",
"name": "设置指南",
"type": "n8n-nodes-base.stickyNote",
"position": [
50,
270
],
"parameters": {
"color": 4,
"width": 300,
"height": 180,
"content": "## ⚙️ 需要初始设置"
},
"typeVersion": 1
},
{
"id": "step1-note",
"name": "步骤1:收集",
"type": "n8n-nodes-base.stickyNote",
"position": [
250,
450
],
"parameters": {
"width": 280,
"height": 160,
"content": "## 1️⃣ 发票收集"
},
"typeVersion": 1
},
{
"id": "step2-note",
"name": "步骤2:提取",
"type": "n8n-nodes-base.stickyNote",
"position": [
1050,
450
],
"parameters": {
"width": 280,
"height": 180,
"content": "## 2️⃣ AI数据提取"
},
"typeVersion": 1
},
{
"id": "step3-note",
"name": "步骤3:供应商",
"type": "n8n-nodes-base.stickyNote",
"position": [
1550,
450
],
"parameters": {
"width": 280,
"height": 160,
"content": "## 3️⃣ 供应商管理"
},
"typeVersion": 1
},
{
"id": "step4-note",
"name": "步骤4:验证",
"type": "n8n-nodes-base.stickyNote",
"position": [
2050,
450
],
"parameters": {
"width": 280,
"height": 200,
"content": "## 4️⃣ 验证与审批"
},
"typeVersion": 1
},
{
"id": "step5-note",
"name": "步骤5:集成",
"type": "n8n-nodes-base.stickyNote",
"position": [
2550,
450
],
"parameters": {
"color": 6,
"width": 280,
"height": 160,
"content": "## 5️⃣ ERP集成"
},
"typeVersion": 1
},
{
"id": "schedule-trigger",
"name": "每5分钟检查",
"type": "n8n-nodes-base.scheduleTrigger",
"notes": "Monitor for new invoices",
"position": [
250,
300
],
"parameters": {
"unit": "minutes",
"value": 5,
"events": [
"workflowActivate"
]
},
"typeVersion": 1.1
},
{
"id": "google-drive-list",
"name": "列出新发票",
"type": "n8n-nodes-base.googleDrive",
"notes": "Get unprocessed invoices",
"position": [
450,
300
],
"parameters": {
"options": {
"fields": [
"id",
"name",
"mimeType",
"createdTime"
]
},
"folderId": "={{ $json.invoiceFolderId }}",
"resource": "file",
"operation": "list"
},
"typeVersion": 3
},
{
"id": "check-processed",
"name": "检查已处理",
"type": "n8n-nodes-base.postgres",
"notes": "Avoid reprocessing",
"position": [
650,
300
],
"parameters": {
"query": "SELECT file_id FROM processed_invoices WHERE file_id IN ({{ $json.files.map(f => `'${f.id}'`).join(',') }})",
"operation": "executeQuery"
},
"typeVersion": 2.4
},
{
"id": "filter-new",
"name": "筛选新文件",
"type": "n8n-nodes-base.code",
"position": [
850,
300
],
"parameters": {
"jsCode": "// Filter out already processed files\nconst files = $node['List New Invoices'].json.files;\nconst processedIds = $node['Check Already Processed'].json.map(row => row.file_id);\n\nconst newFiles = files.filter(file => !processedIds.includes(file.id));\n\nreturn newFiles.map(file => ({ json: file }));"
},
"typeVersion": 2
},
{
"id": "google-drive-download",
"name": "下载发票",
"type": "n8n-nodes-base.googleDrive",
"notes": "Get file content",
"position": [
1050,
300
],
"parameters": {
"fileId": "={{ $json.id }}",
"operation": "download"
},
"typeVersion": 3
},
{
"id": "pdfvector-extract",
"name": "提取发票数据",
"type": "n8n-nodes-pdfvector.pdfVector",
"notes": "AI extraction",
"position": [
1250,
300
],
"parameters": {
"prompt": "Extract comprehensive invoice details including invoice number, date, vendor details (name, address, tax ID, contact), customer info, PO number if present, all line items with item codes/SKUs, descriptions, quantities, unit prices, amounts, tax details by type, payment terms, bank details, and any special instructions. Handle multi-page invoices and various formats.",
"schema": "{\"type\":\"object\",\"properties\":{\"invoiceNumber\":{\"type\":\"string\"},\"invoiceDate\":{\"type\":\"string\"},\"dueDate\":{\"type\":\"string\"},\"poNumber\":{\"type\":\"string\"},\"vendor\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"},\"address\":{\"type\":\"string\"},\"city\":{\"type\":\"string\"},\"state\":{\"type\":\"string\"},\"postalCode\":{\"type\":\"string\"},\"country\":{\"type\":\"string\"},\"taxId\":{\"type\":\"string\"},\"email\":{\"type\":\"string\"},\"phone\":{\"type\":\"string\"}}},\"customer\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"},\"address\":{\"type\":\"string\"},\"department\":{\"type\":\"string\"}}},\"lineItems\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"itemCode\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"quantity\":{\"type\":\"number\"},\"unitPrice\":{\"type\":\"number\"},\"amount\":{\"type\":\"number\"},\"taxRate\":{\"type\":\"number\"}}}},\"subtotal\":{\"type\":\"number\"},\"taxDetails\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"type\":{\"type\":\"string\"},\"rate\":{\"type\":\"number\"},\"amount\":{\"type\":\"number\"}}}},\"total\":{\"type\":\"number\"},\"currency\":{\"type\":\"string\"},\"paymentTerms\":{\"type\":\"string\"},\"bankDetails\":{\"type\":\"object\",\"properties\":{\"bankName\":{\"type\":\"string\"},\"accountNumber\":{\"type\":\"string\"},\"routingNumber\":{\"type\":\"string\"}}},\"notes\":{\"type\":\"string\"}},\"required\":[\"invoiceNumber\",\"vendor\",\"total\"],\"additionalProperties\":false}",
"resource": "document",
"inputType": "file",
"operation": "extract",
"binaryPropertyName": "data"
},
"typeVersion": 1
},
{
"id": "lookup-vendor",
"name": "查找供应商",
"type": "n8n-nodes-base.postgres",
"notes": "Check vendor database",
"position": [
1450,
300
],
"parameters": {
"query": "SELECT * FROM vendor_master WHERE LOWER(name) = LOWER('{{ $json.data.vendor.name }}') OR tax_id = '{{ $json.data.vendor.taxId }}' LIMIT 1",
"operation": "executeQuery"
},
"typeVersion": 2.4
},
{
"id": "vendor-exists",
"name": "供应商存在?",
"type": "n8n-nodes-base.if",
"position": [
1650,
300
],
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json.length > 0 }}",
"value2": true
}
]
}
},
"typeVersion": 1
},
{
"id": "create-vendor",
"name": "创建新供应商",
"type": "n8n-nodes-base.postgres",
"notes": "Add to vendor master",
"position": [
1850,
400
],
"parameters": {
"query": "INSERT INTO vendor_master (name, address, city, state, postal_code, country, tax_id, email, phone, status, created_at) VALUES ('{{ $node['Extract Invoice Data'].json.data.vendor.name }}', '{{ $node['Extract Invoice Data'].json.data.vendor.address }}', '{{ $node['Extract Invoice Data'].json.data.vendor.city }}', '{{ $node['Extract Invoice Data'].json.data.vendor.state }}', '{{ $node['Extract Invoice Data'].json.data.vendor.postalCode }}', '{{ $node['Extract Invoice Data'].json.data.vendor.country }}', '{{ $node['Extract Invoice Data'].json.data.vendor.taxId }}', '{{ $node['Extract Invoice Data'].json.data.vendor.email }}', '{{ $node['Extract Invoice Data'].json.data.vendor.phone }}', 'pending_review', NOW()) RETURNING vendor_id",
"operation": "executeQuery"
},
"typeVersion": 2.4
},
{
"id": "validate-invoice",
"name": "验证并丰富发票",
"type": "n8n-nodes-base.code",
"notes": "Complex validation logic",
"position": [
2050,
300
],
"parameters": {
"jsCode": "// Comprehensive invoice validation\nconst invoice = $node['Extract Invoice Data'].json.data;\nconst vendor = $node['Lookup Vendor'].json[0] || $node['Create New Vendor'].json[0];\nlet validationResult = {\n invoice: invoice,\n vendorId: vendor.vendor_id,\n vendorStatus: vendor.status,\n errors: [],\n warnings: [],\n requiresApproval: false,\n approvalLevel: 0\n};\n\n// Validate calculations\nif (invoice.lineItems && invoice.lineItems.length > 0) {\n const calculatedSubtotal = invoice.lineItems.reduce((sum, item) => sum + (item.amount || 0), 0);\n if (Math.abs(calculatedSubtotal - invoice.subtotal) > 0.01) {\n validationResult.errors.push(`Line items total (${calculatedSubtotal}) doesn't match subtotal (${invoice.subtotal})`);\n }\n}\n\n// Validate tax calculations\nconst totalTax = invoice.taxDetails ? invoice.taxDetails.reduce((sum, tax) => sum + tax.amount, 0) : 0;\nconst calculatedTotal = (invoice.subtotal || 0) + totalTax;\nif (Math.abs(calculatedTotal - invoice.total) > 0.01) {\n validationResult.errors.push(`Calculated total (${calculatedTotal}) doesn't match invoice total (${invoice.total})`);\n}\n\n// Check duplicate invoice\nconst duplicateCheck = await $node['Check Duplicate'].json;\nif (duplicateCheck.length > 0) {\n validationResult.errors.push('Duplicate invoice detected');\n}\n\n// Determine approval requirements\nif (invoice.total > 10000) {\n validationResult.requiresApproval = true;\n validationResult.approvalLevel = 3; // CFO\n} else if (invoice.total > 5000) {\n validationResult.requiresApproval = true;\n validationResult.approvalLevel = 2; // Department Head\n} else if (invoice.total > 1000 || vendor.status === 'pending_review') {\n validationResult.requiresApproval = true;\n validationResult.approvalLevel = 1; // Manager\n}\n\n// Check PO if provided\nif (invoice.poNumber) {\n const poCheck = await $node['Check PO'].json;\n if (poCheck.length === 0) {\n validationResult.warnings.push('PO number not found in system');\n } else {\n const po = poCheck[0];\n if (invoice.total > po.remaining_amount) {\n validationResult.errors.push('Invoice amount exceeds PO remaining balance');\n }\n }\n}\n\nvalidationResult.isValid = validationResult.errors.length === 0;\n\nreturn [{ json: validationResult }];"
},
"typeVersion": 2
},
{
"id": "check-duplicate",
"name": "检查重复",
"type": "n8n-nodes-base.postgres",
"notes": "Prevent double payment",
"position": [
1850,
200
],
"parameters": {
"query": "SELECT invoice_id FROM invoices WHERE vendor_id = {{ $json.vendorId }} AND invoice_number = '{{ $json.invoice.invoiceNumber }}' LIMIT 1",
"operation": "executeQuery"
},
"typeVersion": 2.4
},
{
"id": "check-po",
"name": "检查采购订单",
"type": "n8n-nodes-base.postgres",
"notes": "3-way matching",
"position": [
1850,
100
],
"parameters": {
"query": "SELECT po_number, total_amount, used_amount, (total_amount - used_amount) as remaining_amount FROM purchase_orders WHERE po_number = '{{ $node['Extract Invoice Data'].json.data.poNumber }}' AND status = 'active'",
"operation": "executeQuery"
},
"typeVersion": 2.4
},
{
"id": "needs-approval",
"name": "需要审批?",
"type": "n8n-nodes-base.if",
"position": [
2250,
300
],
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json.requiresApproval }}",
"value2": true
}
]
}
},
"typeVersion": 1
},
{
"id": "send-approval",
"name": "发送审批请求",
"type": "n8n-nodes-base.slack",
"notes": "Notify approvers",
"position": [
2450,
400
],
"parameters": {
"text": "New invoice requires approval:\n*Vendor:* {{ $json.invoice.vendor.name }}\n*Invoice #:* {{ $json.invoice.invoiceNumber }}\n*Amount:* {{ $json.invoice.currency }} {{ $json.invoice.total }}\n*Approval Level:* {{ $json.approvalLevel }}\n\n<{{ $node['Generate Approval Link'].json.approvalUrl }}|Click here to review and approve>",
"channel": "#invoice-approvals",
"attachments": [
{
"color": "#ff6d5a",
"fields": {
"item": [
{
"short": true,
"title": "Due Date",
"value": "{{ $json.invoice.dueDate }}"
},
{
"short": true,
"title": "Payment Terms",
"value": "{{ $json.invoice.paymentTerms }}"
}
]
}
}
]
},
"typeVersion": 2.1
},
{
"id": "generate-approval-link",
"name": "生成审批链接",
"type": "n8n-nodes-base.code",
"notes": "Create secure link",
"position": [
2450,
500
],
"parameters": {
"jsCode": "// Generate secure approval link\nconst baseUrl = 'https://your-domain.com/approve';\nconst token = require('crypto').randomBytes(32).toString('hex');\nconst approvalData = {\n invoiceId: $json.invoice.invoiceNumber,\n vendorId: $json.vendorId,\n amount: $json.invoice.total,\n token: token,\n expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()\n};\n\n// Store approval token in DB (not shown)\nconst approvalUrl = `${baseUrl}?token=${token}`;\n\nreturn [{ json: { ...approvalData, approvalUrl } }];"
},
"typeVersion": 2
},
{
"id": "save-invoice",
"name": "保存发票",
"type": "n8n-nodes-base.postgres",
"notes": "Store in database",
"position": [
2650,
300
],
"parameters": {
"query": "INSERT INTO invoices (invoice_number, vendor_id, invoice_date, due_date, subtotal, tax_amount, total_amount, currency, status, po_number, raw_data, created_at) VALUES ('{{ $json.invoice.invoiceNumber }}', {{ $json.vendorId }}, '{{ $json.invoice.invoiceDate }}', '{{ $json.invoice.dueDate }}', {{ $json.invoice.subtotal }}, {{ $json.invoice.taxDetails.reduce((sum, t) => sum + t.amount, 0) }}, {{ $json.invoice.total }}, '{{ $json.invoice.currency }}', '{{ $json.requiresApproval ? \"pending_approval\" : \"approved\" }}', '{{ $json.invoice.poNumber }}', '{{ JSON.stringify($json.invoice) }}', NOW())",
"operation": "executeQuery"
},
"typeVersion": 2.4
},
{
"id": "quickbooks-create",
"name": "在QuickBooks中创建",
"type": "n8n-nodes-base.quickbooks",
"notes": "ERP integration",
"position": [
2650,
200
],
"parameters": {
"resource": "invoice",
"operation": "create",
"authentication": "oAuth2",
"additionalFields": {
"line": "={{ $json.invoice.lineItems }}",
"dueDate": "={{ $json.invoice.dueDate }}",
"txnDate": "={{ $json.invoice.invoiceDate }}",
"vendorRef": {
"value": "={{ $json.vendorId }}"
},
"customerMemo": "={{ $json.invoice.notes }}",
"invoiceNumber": "={{ $json.invoice.invoiceNumber }}"
}
},
"typeVersion": 1
},
{
"id": "mark-processed",
"name": "标记为已处理",
"type": "n8n-nodes-base.postgres",
"notes": "Track processed files",
"position": [
2850,
300
],
"parameters": {
"query": "INSERT INTO processed_invoices (file_id, invoice_id) VALUES ('{{ $node['Download Invoice'].json.id }}', '{{ $node['Save Invoice'].json.invoice_id }}')",
"operation": "executeQuery"
},
"typeVersion": 2.4
},
{
"id": "update-dashboard",
"name": "更新分析仪表板",
"type": "n8n-nodes-base.webhook",
"notes": "Real-time metrics",
"position": [
3050,
300
],
"parameters": {
"dashboardUrl": "https://your-analytics.com/embed",
"updateFrequency": "realtime"
},
"typeVersion": 1
}
],
"connections": {
"Save Invoice": {
"main": [
[
{
"node": "Create in QuickBooks",
"type": "main",
"index": 0
},
{
"node": "Mark as Processed",
"type": "main",
"index": 0
}
]
]
},
"Lookup Vendor": {
"main": [
[
{
"node": "Vendor Exists?",
"type": "main",
"index": 0
}
]
]
},
"Vendor Exists?": {
"main": [
[
{
"node": "Validate & Enrich Invoice",
"type": "main",
"index": 0
}
],
[
{
"node": "Create New Vendor",
"type": "main",
"index": 0
}
]
]
},
"Needs Approval?": {
"main": [
[
{
"node": "Generate Approval Link",
"type": "main",
"index": 0
},
{
"node": "Save Invoice",
"type": "main",
"index": 0
}
],
[
{
"node": "Save Invoice",
"type": "main",
"index": 0
}
]
]
},
"Download Invoice": {
"main": [
[
{
"node": "Extract Invoice Data",
"type": "main",
"index": 0
}
]
]
},
"Filter New Files": {
"main": [
[
{
"node": "Download Invoice",
"type": "main",
"index": 0
}
]
]
},
"Create New Vendor": {
"main": [
[
{
"node": "Validate & Enrich Invoice",
"type": "main",
"index": 0
}
]
]
},
"List New Invoices": {
"main": [
[
{
"node": "Check Already Processed",
"type": "main",
"index": 0
}
]
]
},
"Mark as Processed": {
"main": [
[
{
"node": "Update Analytics Dashboard",
"type": "main",
"index": 0
}
]
]
},
"Extract Invoice Data": {
"main": [
[
{
"node": "Lookup Vendor",
"type": "main",
"index": 0
}
]
]
},
"Check Every 5 Minutes": {
"main": [
[
{
"node": "List New Invoices",
"type": "main",
"index": 0
}
]
]
},
"Generate Approval Link": {
"main": [
[
{
"node": "Send Approval Request",
"type": "main",
"index": 0
}
]
]
},
"Check Already Processed": {
"main": [
[
{
"node": "Filter New Files",
"type": "main",
"index": 0
}
]
]
},
"Validate & Enrich Invoice": {
"main": [
[
{
"node": "Check Duplicate",
"type": "main",
"index": 0
},
{
"node": "Check PO",
"type": "main",
"index": 0
},
{
"node": "Needs Approval?",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 发票处理, AI 摘要总结, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
PDF报告监控器 - 含GPT-3.5洞察与Slack/邮件告警
PDF报告监控器 - 含GPT-3.5洞察与Slack/邮件告警
If
Ftp
Code
+7
10 节点PDF Vector
AI 摘要总结
使用PDF Vector和HIPAA合规从医疗文档提取临床数据
使用PDF Vector和HIPAA合规从医疗文档提取临床数据
If
Code
Postgres
+4
9 节点PDF Vector
文档提取
使用 PDF Vector 和 Google Drive 的自动化收据处理与税务分类
使用 PDF Vector 和 Google Drive 的自动化收据处理与税务分类
Code
Google Drive
Google Sheets
+3
9 节点PDF Vector
发票处理
企业合同生命周期管理与AI风险分析
企业合同生命周期管理与AI风险分析
If
Code
Merge
+8
20 节点PDF Vector
文档提取
批量PDF转Markdown转换(Google Drive与LLM解析)
使用Google Drive和LLM驱动的解析进行批量PDF转Markdown转换
If
Set
Code
+4
8 节点PDF Vector
内容创作
自动化客户培育邮件与Notion客户评价收集
使用WhatsApp、GPT-4V和Google Sheets提取并整理收据数据
If
Code
Notion
+7
18 节点Shelly-Ann Davy
发票处理
工作流信息
难度等级
高级
节点数量26
分类3
节点类型10
作者
PDF Vector
@pdfvectorA fully featured PDF APIs for developers - Parse any PDF or Word document, extract structured data, and access millions of academic papers - all through simple APIs.
外部链接
在 n8n.io 查看 →
分享此工作流