AutomationFlowsGeneral › Process Multiple Files with Forms: a Tutorial on Binary Data and Loops

Process Multiple Files with Forms: a Tutorial on Binary Data and Loops

ByWyeth @wyeth on n8n.io

Let a user load multiple files with a Form node, and process the binary data. A very important workflow for many tools.

Event trigger★★★☆☆ complexity10 nodesRead Write FileForm Trigger
General Trigger: Event Nodes: 10 Complexity: ★★★☆☆ Added:

This workflow corresponds to n8n.io template #5419 — we link there as the canonical source.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "A2JB4uRp5waIV6yk",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "FormLoadFileExample",
  "tags": [],
  "nodes": [
    {
      "id": "be53d6d3-2416-482e-a714-4573fed4bfbb",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -440,
        -460
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "699f5089-7416-414a-8e95-3bdb8637a6d9",
      "name": "Save Each File",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        -240,
        -400
      ],
      "parameters": {
        "options": {
          "append": false
        },
        "fileName": "=out_{{ $json.files.filename }}",
        "operation": "write",
        "dataPropertyName": "=files_{{$runIndex}}"
      },
      "typeVersion": 1
    },
    {
      "id": "c8c5f9e6-670b-405b-af1d-72eeb372303e",
      "name": "Split Out Files",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -780,
        -460
      ],
      "parameters": {
        "options": {
          "includeBinary": true,
          "destinationFieldName": "=files"
        },
        "fieldToSplitOut": "=files"
      },
      "executeOnce": false,
      "typeVersion": 1
    },
    {
      "id": "8f7252ac-4082-49b8-9e56-9d14689ee864",
      "name": "Form - Load Multiple Files",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -1220,
        -460
      ],
      "parameters": {
        "options": {},
        "formTitle": "LOAD MULTIPLE FILES",
        "formFields": {
          "values": [
            {
              "fieldType": "file",
              "fieldLabel": "files",
              "requiredField": true,
              "acceptFileTypes": "*.json"
            }
          ]
        },
        "formDescription": "Select multiple json files to run this example."
      },
      "typeVersion": 2.2
    },
    {
      "id": "72ee0e48-9a75-4c7d-af09-bcd5bbc5b2ba",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1400,
        -760
      ],
      "parameters": {
        "width": 1740,
        "height": 140,
        "content": "## Learning n8n\n### Loops, Multiple Binary Files, {{$runIndex}}\n\nLoops are rarely needed in n8n, but here is one example of how to effectively use one to process multiple binary files."
      },
      "typeVersion": 1
    },
    {
      "id": "962e91d5-eb75-4245-9dfb-4b13c15cdb0a",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1400,
        -600
      ],
      "parameters": {
        "color": 6,
        "width": 480,
        "height": 400,
        "content": "Use a Form to load multiple files. \n\nThis is a case where n8n will NOT fire an event per file loaded, but instead a single event with all files nested into 1 array. \nHowever, we want to process the files one at a time..."
      },
      "typeVersion": 1
    },
    {
      "id": "2aee5134-abc4-45f9-a2db-cf205f18cff7",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -900,
        -600
      ],
      "parameters": {
        "color": 6,
        "width": 360,
        "height": 400,
        "content": "Split Out will fix this, firing one event for each file.\n\n*We must make sure to pass binary data along.*"
      },
      "typeVersion": 1
    },
    {
      "id": "1ec83469-5dcd-4beb-9414-7f75a0727ed3",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -520,
        -600
      ],
      "parameters": {
        "color": 6,
        "width": 460,
        "height": 400,
        "content": "Now we can use a Loop to handle each file, one at a time.\nWith this setup, the special {{$runIndex}} can be used to get our loop counter.\n\nWe use it to get the correct binary file, which has been inconveniently passed downstream as files_0, files_1, files_2... etc."
      },
      "typeVersion": 1
    },
    {
      "id": "2545fa3e-346b-4277-b494-f1c2d469dceb",
      "name": "Continue Once",
      "type": "n8n-nodes-base.noOp",
      "position": [
        60,
        -480
      ],
      "parameters": {},
      "executeOnce": true,
      "typeVersion": 1
    },
    {
      "id": "d1646761-2962-4afb-9033-d13f7d853290",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -40,
        -600
      ],
      "parameters": {
        "color": 6,
        "width": 380,
        "height": 400,
        "content": "We typically only want to proceed downstream with a single event, so this NOP set to \"run once\" will let us do that regardless of the file count."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "21acb21b-3bca-4279-9725-7d4fcd88b25f",
  "connections": {
    "Continue Once": {
      "main": [
        []
      ]
    },
    "Save Each File": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Continue Once",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Save Each File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out Files": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Form - Load Multiple Files": {
      "main": [
        [
          {
            "node": "Split Out Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Let a user load multiple files with a Form node, and process the binary data. A very important workflow for many tools.

Source: https://n8n.io/workflows/5419/ — original creator credit. Request a take-down →

More General workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

General

Credentials Transfer. Uses form, httpRequest, executeCommand, readWriteFile. Event-driven trigger; 22 nodes.

Form, HTTP Request, Execute Command +2
General

This workflow automatically extracts all files from an uploaded zip archive and uploads each file individually to Google Drive.

Form Trigger, Read Write File, Compression +1
General

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

Form Trigger, n8n, Form +2
General

CV_filter_worklow. Uses chainLlm, lmChatGoogleGemini, readWriteFile, formTrigger. Event-driven trigger; 9 nodes.

Chain Llm, Google Gemini Chat, Read Write File +1
General

AutoQoutesV2_template. Uses manualTrigger, httpRequest, stickyNote, googleSheets. Event-driven trigger; 28 nodes.

HTTP Request, Google Sheets, Google Drive +2