8
n8n 中文网amn8n.com

使用CustomJS API生成PDF发票

初级

这是一个Finance领域的自动化工作流,包含 5 个节点。主要使用 Set, Code, Webhook, RespondToWebhook, Html2Pdf 等节点。 使用CustomJS API生成PDF发票

前置要求
  • HTTP Webhook 端点(n8n 会自动生成)

分类

工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "fcf18fc485cc336a31bc65574fd28e124660f468281b7aad773616b17903afe6",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "de602925-4d9d-4045-9d9d-ed37dfb65490",
      "name": "HTML 转 PDF",
      "type": "@custom-js/n8n-nodes-pdf-toolkit.html2Pdf",
      "position": [
        460,
        -20
      ],
      "parameters": {
        "htmlInput": "=<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Invoice</title>\n    <style>\n        /* Global Reset */\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n\n        /* Body and Container */\n        body {\n            font-family: 'Roboto', sans-serif;\n            background: #f4f7fc;\n            display: flex;\n            justify-content: center;\n            padding: 30px;\n        }\n\n        .invoice-wrapper {\n            width: 100%;\n            max-width: 900px;\n            background: linear-gradient(145deg, #ffffff, #e6f7ff);\n            border-radius: 10px;\n            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);\n            padding: 40px;\n            margin-top: 50px;\n        }\n\n        /* Header */\n        .header {\n            background: linear-gradient(145deg, #3f51b5, #2196f3);\n            text-align: center;\n            color: #fff;\n            padding: 30px;\n            border-radius: 8px;\n        }\n\n        .header h1 {\n            font-size: 40px;\n            margin-bottom: 10px;\n        }\n\n        .header p {\n            font-size: 18px;\n            font-weight: 400;\n        }\n\n        /* Invoice Details Section */\n        .invoice-details {\n            display: flex;\n            justify-content: space-between;\n            margin-top: 30px;\n            border-top: 2px solid #eee;\n            padding-top: 30px;\n        }\n\n        .invoice-details div {\n            width: 48%;\n        }\n\n        .invoice-details h3 {\n            color: #3f51b5;\n            font-size: 20px;\n            margin-bottom: 15px;\n        }\n\n        .invoice-details p {\n            font-size: 15px;\n            color: #555;\n            line-height: 1.6;\n        }\n\n        /* Table Styling */\n        .table {\n            width: 100%;\n            border-collapse: collapse;\n            margin-top: 30px;\n        }\n\n        .table th,\n        .table td {\n            padding: 16px;\n            text-align: left;\n            font-size: 15px;\n            color: #555;\n        }\n\n        .table th {\n            background-color: #f1f5fc;\n            color: #3f51b5;\n            font-weight: 500;\n        }\n\n        .table td {\n            background-color: #fff;\n            border-bottom: 1px solid #e6e9f1;\n        }\n\n        .table tr:last-child td {\n            border-bottom: none;\n        }\n\n        .table .total {\n            font-weight: 600;\n            font-size: 18px;\n            color: #333;\n            background-color: #f1f5fc;\n        }\n\n        .table .total td {\n            text-align: right;\n        }\n\n        .table tr:nth-child(even) {\n            background-color: #f9f9f9;\n        }\n\n        /* Footer */\n        .footer {\n            text-align: center;\n            margin-top: 30px;\n            font-size: 15px;\n            color: #777;\n        }\n\n        .footer a {\n            color: #2196f3;\n            text-decoration: none;\n            font-weight: 500;\n        }\n\n        .footer a:hover {\n            text-decoration: underline;\n        }\n\n        /* Button */\n        .btn {\n            display: inline-block;\n            background-color: #2196f3;\n            color: white !important;\n            font-size: 16px;\n            font-weight: 600;\n            padding: 12px 25px;\n            margin-top: 25px;\n            text-decoration: none;\n            border-radius: 5px;\n            transition: background-color 0.3s ease;\n            box-shadow: 0 6px 15px rgba(33, 150, 243, 0.2);\n        }\n\n        .btn:hover {\n            background-color: #1976d2;\n        }\n\n        .btn:active {\n            background-color: #1565c0;\n        }\n    </style>\n</head>\n<body>\n\n<div class=\"invoice-wrapper\">\n    <div class=\"header\">\n        <h1>Invoice</h1>\n        <p>Invoice #{{ $('Set data').item.json['Invoice No'] }}</p>\n    </div>\n\n    <div class=\"invoice-details\">\n        <div>\n            <h3>Billed To:</h3>\n            {{ $json.bill_to }}\n        </div>\n        <div>\n            <h3>From:</h3>\n            {{ $json.from }}\n            <p>Email: {{ $('Set data').item.json.Email }}</p>\n        </div>\n    </div>\n\n    <table class=\"table\">\n        <thead>\n            <tr>\n                <th>Description</th>\n                <th>Unit Price</th>\n                <th>Quantity</th>\n                <th>Total</th>\n            </tr>\n        </thead>\n        <tbody>\n            {{ $json.details }}\n            <tr class=\"total\">\n                <td colspan=\"3\">Total Amount</td>\n                <td>${{ $json.total }}</td>\n            </tr>\n        </tbody>\n    </table>\n\n    <div class=\"footer\">\n        <p>Thank you for doing business with us!</p>\n        <p>If you have any questions regarding this invoice, please contact us at <a href=\"mailto:contact@abccorp.com\">{{ $('Set data').item.json.Email }}</a>.</p>\n        <a href=\"mailto:{{ $('Set data').item.json.Email }}\" class=\"btn\">Contact Us</a>\n    </div>\n</div>\n\n</body>\n</html>"
      },
      "credentials": {
        "customJsApi": {
          "id": "SZkqeEHVYyWhaGem",
          "name": "CustomJS account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5a8efc8a-c60b-4616-a17a-6275cc326978",
      "name": "预处理",
      "type": "n8n-nodes-base.code",
      "position": [
        240,
        -20
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const input = $input.item.json\nconst bill_to = input['Bill To'].split('\\n').map(item => '<p>' + item + '</p>')\nconst from = input['From'].split('\\n').map(item => '<p>' + item + '</p>')\nconst details = input['Details'].map(item => {\n  const price = item.price*item.qty\n  return `\n  <tr>\n    <td>${item.description}</td>\n    <td>$${item.price}</td>\n    <td>${item.qty}</td>\n    <td>$${price}</td>\n  </tr>\n  `\n})\nconst total = input['Details'].reduce((val, next) => {\n\treturn val+next.price*next.qty\n}, 0)\nreturn {\n  bill_to: bill_to.join('\\n'),\n  from: from.join('\\n'),\n  details: details.join('\\n'),\n  total\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "7da4fb46-1f74-44d8-8392-16fc90f23928",
      "name": "设置数据",
      "type": "n8n-nodes-base.set",
      "position": [
        20,
        -20
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "5342001f-a513-46c3-b31f-4590e8514411",
              "name": "Invoice No",
              "type": "string",
              "value": "1"
            },
            {
              "id": "ec357d39-c697-4bb8-8d9d-1bc303352dd0",
              "name": "Bill To",
              "type": "string",
              "value": "John Doe\n1234 Elm St, Apt 567\nCity, Country, 12345"
            },
            {
              "id": "88d6b470-4075-43ec-a684-a4adfd889278",
              "name": "From",
              "type": "string",
              "value": "ABC Corporation\n789 Business Ave\nCity, Country, 67890"
            },
            {
              "id": "061a8020-644a-4cec-bade-3bcd7e15adee",
              "name": "Details",
              "type": "array",
              "value": "[     {         \"description\": \"Web Hosting\",         \"price\": 150,         \"qty\": 2     },     {         \"description\": \"Domain\",         \"price\": 15,         \"qty\": 5     } ]"
            },
            {
              "id": "1c2c6c4b-6aa5-4656-8cae-43ffac71d478",
              "name": "Email",
              "type": "string",
              "value": "support@mycompany.com"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a6d39cc4-b9c2-4eed-b4a6-46d622a87c14",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -200,
        -20
      ],
      "webhookId": "526fd864-6f85-4cde-97aa-39b61a3e5b83",
      "parameters": {
        "path": "526fd864-6f85-4cde-97aa-39b61a3e5b83",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "c7d1cc1d-88e3-463a-886f-182a2ba72b11",
      "name": "响应 Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        660,
        -20
      ],
      "parameters": {
        "options": {},
        "respondWith": "binary"
      },
      "typeVersion": 1.1
    }
  ],
  "pinData": {},
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Set data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set data": {
      "main": [
        [
          {
            "node": "Preprocess",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Preprocess": {
      "main": [
        [
          {
            "node": "HTML to PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTML to PDF": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

初级 - 财务

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
初级
节点数量5
分类1
节点类型5
难度说明

适合 n8n 新手,包含 1-5 个节点的简单工作流

外部链接
在 n8n.io 查看

分享此工作流