面向财务专业人士的自动化每日现金流与费用报告
这是一个Document Extraction领域的自动化工作流,包含 25 个节点。主要使用 Code, Merge, Slack, EmailSend, GoogleDrive 等节点。 使用Google表格、Slack和邮件为财务团队生成每日现金流报告
- •Slack Bot Token 或 Webhook URL
- •Google Drive API 凭证
- •可能需要目标 API 的认证凭证
- •Google Sheets API 凭证
使用的节点 (25)
分类
{
"id": "zfjbXMrH4jEkZcti",
"meta": {
"instanceId": "dd69efaf8212c74ad206700d104739d3329588a6f3f8381a46a481f34c9cc281",
"templateCredsSetupCompleted": true
},
"name": "面向财务专业人士的自动化每日现金流与费用报告",
"tags": [],
"nodes": [
{
"id": "906bf96e-e9fd-480d-850a-ea04667fba76",
"name": "每日下午 6 点",
"type": "n8n-nodes-base.scheduleTrigger",
"notes": "⏰ DAILY TRIGGER\nRuns every day at 6:00 PM\nGenerates end-of-day report",
"position": [
-928,
-208
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression"
}
]
}
},
"typeVersion": 1
},
{
"id": "13babc7a-eaef-4484-b2a7-a9d98a7c7936",
"name": "获取现金流入",
"type": "n8n-nodes-base.httpRequest",
"notes": "💵 FETCH INFLOWS\nRetrieves all incoming payments\nToday's deposits & revenue",
"position": [
-704,
-304
],
"parameters": {
"url": "https://api.accounting.com/transactions",
"options": {}
},
"typeVersion": 4.1
},
{
"id": "8c87a527-7f6a-4806-80a5-63cb76a755f4",
"name": "获取现金流出",
"type": "n8n-nodes-base.httpRequest",
"notes": "💸 FETCH OUTFLOWS\nRetrieves all outgoing payments\nToday's expenses & bills",
"position": [
-704,
0
],
"parameters": {
"url": "https://api.accounting.com/transactions",
"options": {}
},
"typeVersion": 4.1
},
{
"id": "4a48cf32-59d4-4048-ae7c-0134ee0f2663",
"name": "计算流入",
"type": "n8n-nodes-base.code",
"notes": "🧮 CALCULATE INFLOWS\nSums total incoming cash\nGroups by category\nCounts transactions",
"position": [
-480,
-304
],
"parameters": {
"jsCode": "// Process Inflows\nconst inflows = $input.first().json;\nlet totalInflow = 0;\nconst inflowsByCategory = {};\n\nif (Array.isArray(inflows)) {\n inflows.forEach(transaction => {\n totalInflow += parseFloat(transaction.amount || 0);\n const category = transaction.category || 'Other';\n if (!inflowsByCategory[category]) {\n inflowsByCategory[category] = 0;\n }\n inflowsByCategory[category] += parseFloat(transaction.amount || 0);\n });\n}\n\nreturn {\n total_inflow: totalInflow.toFixed(2),\n inflow_categories: inflowsByCategory,\n inflow_count: Array.isArray(inflows) ? inflows.length : 0,\n date: new Date().toISOString().split('T')[0]\n};"
},
"typeVersion": 2
},
{
"id": "47798a32-d2a6-4a71-b0fb-74c382417b45",
"name": "计算流出",
"type": "n8n-nodes-base.code",
"notes": "🧮 CALCULATE OUTFLOWS\nSums total outgoing cash\nGroups by expense category\nCounts transactions",
"position": [
-480,
-112
],
"parameters": {
"jsCode": "// Process Outflows\nconst outflows = $input.first().json;\nlet totalOutflow = 0;\nconst outflowsByCategory = {};\n\nif (Array.isArray(outflows)) {\n outflows.forEach(transaction => {\n totalOutflow += parseFloat(transaction.amount || 0);\n const category = transaction.category || 'Other';\n if (!outflowsByCategory[category]) {\n outflowsByCategory[category] = 0;\n }\n outflowsByCategory[category] += parseFloat(transaction.amount || 0);\n });\n}\n\nreturn {\n total_outflow: totalOutflow.toFixed(2),\n outflow_categories: outflowsByCategory,\n outflow_count: Array.isArray(outflows) ? outflows.length : 0,\n date: new Date().toISOString().split('T')[0]\n};"
},
"typeVersion": 2
},
{
"id": "a5ac7f5d-5c0e-4aa1-a0ea-924aba958ce2",
"name": "合并数据",
"type": "n8n-nodes-base.merge",
"notes": "🔀 COMBINE DATA\nMerges inflows + outflows\nPrepares for final report",
"position": [
-256,
-208
],
"parameters": {
"mode": "combine",
"options": {},
"combinationMode": "mergeByPosition"
},
"typeVersion": 2.1
},
{
"id": "cf3299a5-67c9-4970-948e-7613f2dfbd07",
"name": "计算净现金流",
"type": "n8n-nodes-base.code",
"notes": "📊 NET CALCULATION\nTotal Inflow - Total Outflow\nDetermines cash position\nPositive or Negative status",
"position": [
-32,
-208
],
"parameters": {
"jsCode": "const data = $input.all();\nconst inflow = data[0].json;\nconst outflow = data[1].json;\n\nconst totalInflow = parseFloat(inflow.total_inflow || 0);\nconst totalOutflow = parseFloat(outflow.total_outflow || 0);\nconst netCashFlow = totalInflow - totalOutflow;\n\nreturn {\n date: inflow.date,\n total_inflow: totalInflow.toFixed(2),\n total_outflow: totalOutflow.toFixed(2),\n net_cash_flow: netCashFlow.toFixed(2),\n inflow_categories: inflow.inflow_categories,\n outflow_categories: outflow.outflow_categories,\n inflow_count: inflow.inflow_count,\n outflow_count: outflow.outflow_count,\n cash_flow_status: netCashFlow >= 0 ? 'Positive' : 'Negative'\n};"
},
"typeVersion": 2
},
{
"id": "10370491-a9fb-4325-b6f0-4d81f071393a",
"name": "保存到 Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"notes": "💾 SAVE TO SHEETS\nSheet: Daily_Cash_Flow\nDoc ID: 9x8w7v6u5t4s3r2q\nHistorical tracking",
"position": [
192,
-304
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappings": [
{
"value": "={{ $json.date }}",
"column": "Date"
},
{
"value": "={{ $json.total_inflow }}",
"column": "Total_Inflow"
},
{
"value": "={{ $json.total_outflow }}",
"column": "Total_Outflow"
},
{
"value": "={{ $json.net_cash_flow }}",
"column": "Net_Cash_Flow"
},
{
"value": "={{ $json.cash_flow_status }}",
"column": "Status"
},
{
"value": "={{ $json.inflow_count }}",
"column": "Inflow_Count"
},
{
"value": "={{ $json.outflow_count }}",
"column": "Outflow_Count"
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": "Daily_Cash_Flow",
"documentId": "9x8w7v6u5t4s3r2q",
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"id": "ScSS2KxGQULuPtdy",
"name": "Google Sheets- test"
}
},
"typeVersion": 4
},
{
"id": "90770fcd-1953-46f9-872b-1da928eca718",
"name": "生成 HTML 报告",
"type": "n8n-nodes-base.code",
"notes": "📄 CREATE REPORT\nBuilds HTML formatted report\nIncludes all categories\nSummary + detailed breakdown",
"position": [
208,
48
],
"parameters": {
"jsCode": "const data = $input.first().json;\n\n// Build category breakdown HTML\nlet inflowHTML = '';\nfor (const [category, amount] of Object.entries(data.inflow_categories)) {\n inflowHTML += `<tr><td>${category}</td><td>$${parseFloat(amount).toFixed(2)}</td></tr>`;\n}\n\nlet outflowHTML = '';\nfor (const [category, amount] of Object.entries(data.outflow_categories)) {\n outflowHTML += `<tr><td>${category}</td><td>$${parseFloat(amount).toFixed(2)}</td></tr>`;\n}\n\nconst statusColor = data.cash_flow_status === 'Positive' ? 'green' : 'red';\n\nconst htmlReport = `\n<!DOCTYPE html>\n<html>\n<head>\n <style>\n body { font-family: Arial, sans-serif; max-width: 800px; margin: 20px auto; }\n h1 { color: #333; border-bottom: 3px solid #4CAF50; padding-bottom: 10px; }\n h2 { color: #666; margin-top: 30px; }\n table { width: 100%; border-collapse: collapse; margin: 20px 0; }\n th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }\n th { background-color: #4CAF50; color: white; }\n .summary { background: #f5f5f5; padding: 20px; border-radius: 8px; margin: 20px 0; }\n .positive { color: green; font-weight: bold; }\n .negative { color: red; font-weight: bold; }\n </style>\n</head>\n<body>\n <h1>Daily Cash Flow Report</h1>\n <p><strong>Date:</strong> ${data.date}</p>\n \n <div class=\"summary\">\n <h2>Summary</h2>\n <p><strong>Total Inflows:</strong> $${data.total_inflow} (${data.inflow_count} transactions)</p>\n <p><strong>Total Outflows:</strong> $${data.total_outflow} (${data.outflow_count} transactions)</p>\n <p><strong>Net Cash Flow:</strong> <span style=\"color: ${statusColor};\">$${data.net_cash_flow}</span></p>\n <p><strong>Status:</strong> <span style=\"color: ${statusColor};\">${data.cash_flow_status}</span></p>\n </div>\n \n <h2>Cash Inflows by Category</h2>\n <table>\n <tr><th>Category</th><th>Amount</th></tr>\n ${inflowHTML}\n <tr style=\"background: #f0f0f0; font-weight: bold;\"><td>Total</td><td>$${data.total_inflow}</td></tr>\n </table>\n \n <h2>Cash Outflows by Category</h2>\n <table>\n <tr><th>Category</th><th>Amount</th></tr>\n ${outflowHTML}\n <tr style=\"background: #f0f0f0; font-weight: bold;\"><td>Total</td><td>$${data.total_outflow}</td></tr>\n </table>\n</body>\n</html>\n`;\n\nreturn {\n html_report: htmlReport,\n ...data\n};"
},
"typeVersion": 2
},
{
"id": "0bcbdaaf-97ff-440a-b3d9-5f6978183791",
"name": "邮件报告",
"type": "n8n-nodes-base.emailSend",
"notes": "📧 EMAIL DELIVERY\nTo: finance@company.com, cfo@company.com\nCC: accounting@company.com\nPDF attachment included",
"position": [
640,
-304
],
"webhookId": "7424dadf-c7c3-45ef-ab94-afc139928921",
"parameters": {
"options": {
"ccEmail": "accounting@company.com",
"attachments": "data:application/pdf;base64,={{ $json.pdf_base64 }}"
},
"subject": "Daily Cash Flow Report - {{ $now.format('MMM dd, yyyy') }}",
"toEmail": "finance@company.com, cfo@company.com",
"fromEmail": "reports@company.com"
},
"credentials": {
"smtp": {
"id": "G1kyF8cSWTZ4vouN",
"name": "SMTP -test"
}
},
"typeVersion": 2
},
{
"id": "3b4e8178-5819-4299-a509-429cbdc09e7e",
"name": "备份到 Google Drive",
"type": "n8n-nodes-base.googleDrive",
"notes": "☁️ CLOUD BACKUP\nGoogle Drive storage\nFolder: /finance/reports/\nAutomatic archiving",
"position": [
704,
48
],
"parameters": {
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "MGnTMJvH7MB4xBS9",
"name": "Google Drive account - test"
}
},
"typeVersion": 3
},
{
"id": "f6b32c5f-8fcf-4896-9c45-53147eed217d",
"name": "发布到Slack",
"type": "n8n-nodes-base.slack",
"notes": "💬 SLACK NOTIFICATION\nChannel: #daily-reports\nChannel ID: C98765ZYXWV\nQuick summary for team",
"position": [
448,
48
],
"webhookId": "1af009f1-5a52-4ab9-bfc0-ccc771596ac6",
"parameters": {
"text": "📊 *Daily Cash Flow Report*\n\n*Date:* {{ $json.date }}\n\n💵 *Total Inflows:* ${{ $json.total_inflow }}\n💸 *Total Outflows:* ${{ $json.total_outflow }}\n📈 *Net Cash Flow:* ${{ $json.net_cash_flow }}\n\n*Status:* {{ $json.cash_flow_status }}\n\nFull report emailed to finance team.",
"user": {
"__rl": true,
"mode": "username",
"value": ""
},
"select": "user",
"otherOptions": {}
},
"credentials": {
"slackApi": {
"id": "MQ0fgwuS8AzfwFvy",
"name": "Slack account - test "
}
},
"typeVersion": 2.1
},
{
"id": "81ba9fe8-c157-4f81-a1ad-b5704b4b52c8",
"name": "转换为PDF",
"type": "n8n-nodes-pdfmonkey.pdfMonkey",
"position": [
416,
-304
],
"parameters": {
"documentTemplateId": "=mnhu765rfcxse456yuj"
},
"credentials": {
"pdfMonkeyApi": {
"id": "B6lNi5YDBkcut5uy",
"name": "PDFMonkey account - test"
}
},
"typeVersion": 1
},
{
"id": "5b07dccd-f3c4-49df-a158-5a7349d6a4cb",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-976,
-336
],
"parameters": {
"width": 160,
"height": 272,
"content": "⏰ 每日下午 6 点触发"
},
"typeVersion": 1
},
{
"id": "4576e612-833e-457e-9700-03453ab42433",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-736,
-400
],
"parameters": {
"width": 160,
"height": 240,
"content": "💵 获取现金流入(存款、收入)"
},
"typeVersion": 1
},
{
"id": "8f251823-583f-49f5-9d47-ef91165a33c5",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-736,
-96
],
"parameters": {
"width": 160,
"height": 240,
"content": "💸 获取现金流出(费用、账单)"
},
"typeVersion": 1
},
{
"id": "8ae88b52-3252-4f56-979a-2b731758521b",
"name": "便签4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-512,
-416
],
"parameters": {
"width": 160,
"height": 496,
"content": "🧮 按类别计算两者总计"
},
"typeVersion": 1
},
{
"id": "7bcaaee4-8a25-45f2-81c1-9e585fe57b20",
"name": "便签5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-288,
-320
],
"parameters": {
"width": 160,
"height": 272,
"content": "🔀 合并数据"
},
"typeVersion": 1
},
{
"id": "e238c7cd-1035-43eb-8479-4ce1dd7cd97b",
"name": "便签6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-80,
-320
],
"parameters": {
"width": 160,
"height": 272,
"content": "📊 计算净现金流(流入 - 流出)"
},
"typeVersion": 1
},
{
"id": "94c331d0-66f9-445e-82e3-6e135519abf7",
"name": "便签7",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
-432
],
"parameters": {
"width": 160,
"height": 272,
"content": "💾 保存到 Google Sheets 进行跟踪"
},
"typeVersion": 1
},
{
"id": "d40e3e31-de41-40ea-ba8f-1fe904f18d0a",
"name": "便签8",
"type": "n8n-nodes-base.stickyNote",
"position": [
608,
-432
],
"parameters": {
"width": 160,
"height": 272,
"content": "📧 发送邮件给财务团队并附上 PDF"
},
"typeVersion": 1
},
{
"id": "cf304fc3-f19f-4285-9f38-6fe0712ba9bb",
"name": "便签9",
"type": "n8n-nodes-base.stickyNote",
"position": [
176,
-112
],
"parameters": {
"width": 160,
"height": 272,
"content": "📄 生成格式化的 HTML 报告"
},
"typeVersion": 1
},
{
"id": "dcf2d893-d7a3-40d6-b39f-48d4692cfc23",
"name": "便签 10",
"type": "n8n-nodes-base.stickyNote",
"position": [
400,
-432
],
"parameters": {
"width": 160,
"height": 272,
"content": "📑 转换为专业的 PDF"
},
"typeVersion": 1
},
{
"id": "67edc76d-3a9a-4e0a-b7d0-9286151e0629",
"name": "便签 11",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
-112
],
"parameters": {
"width": 160,
"height": 272,
"content": "💬 将摘要发布到 Slack"
},
"typeVersion": 1
},
{
"id": "d62323f3-c4ca-4580-86a8-61e2a3dcd5e4",
"name": "便签12",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
-112
],
"parameters": {
"width": 160,
"height": 272,
"content": "☁️ 备份到 Google Drive"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "110ed3b3-c47a-4dc3-9557-960a5948cb40",
"connections": {
"Merge Data": {
"main": [
[
{
"node": "Calculate Net Cash Flow",
"type": "main",
"index": 0
}
]
]
},
"Daily at 6 PM": {
"main": [
[
{
"node": "Get Cash Inflows",
"type": "main",
"index": 0
},
{
"node": "Get Cash Outflows",
"type": "main",
"index": 0
}
]
]
},
"Post to Slack": {
"main": [
[
{
"node": "Backup to Google Drive",
"type": "main",
"index": 0
}
]
]
},
"Convert to PDF": {
"main": [
[
{
"node": "Email Report",
"type": "main",
"index": 0
}
]
]
},
"Get Cash Inflows": {
"main": [
[
{
"node": "Calculate Inflows",
"type": "main",
"index": 0
}
]
]
},
"Calculate Inflows": {
"main": [
[
{
"node": "Merge Data",
"type": "main",
"index": 0
}
]
]
},
"Get Cash Outflows": {
"main": [
[
{
"node": "Calculate Outflows",
"type": "main",
"index": 0
}
]
]
},
"Calculate Outflows": {
"main": [
[
{
"node": "Merge Data",
"type": "main",
"index": 1
}
]
]
},
"Generate HTML Report": {
"main": [
[
{
"node": "Post to Slack",
"type": "main",
"index": 0
}
]
]
},
"Save to Google Sheets": {
"main": [
[
{
"node": "Convert to PDF",
"type": "main",
"index": 0
}
]
]
},
"Calculate Net Cash Flow": {
"main": [
[
{
"node": "Save to Google Sheets",
"type": "main",
"index": 0
},
{
"node": "Generate HTML Report",
"type": "main",
"index": 0
}
]
]
}
}
}如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 文档提取
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
Oneclick AI Squad
@oneclick-aiThe AI Squad Initiative is a pioneering effort to build, automate and scale AI-powered workflows using n8n.io. Our mission is to help individuals and businesses integrate AI agents seamlessly into their daily operations from automating tasks and enhancing productivity to creating innovative, intelligent solutions. We design modular, reusable AI workflow templates that empower creators, developers and teams to supercharge their automation with minimal effort and maximum impact.
分享此工作流