8
n8n 中文网amn8n.com

使用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)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量26
分类3
节点类型10
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
PDF Vector

PDF Vector

@pdfvector

A 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 查看

分享此工作流