Пошаговые инструкции Для начинающих 13 мин

Как выгрузить данные из n8n в Excel (XLSX)

Создайте настоящий XLSX из заказов и проверьте обратным чтением. 12 шагов, готовый workflow, учебный Excel-файл и проверка номеров, чисел и нулей.

n8n Excel XLSX

Соберём в n8n файл Excel из трёх учебных заказов. Не CSV с переименованным расширением, а XLSX с листом Orders. Затем прочитаем его обратно и проверим каждое значение: номера 0001 и 0002 должны остаться строками, а количество и цена — числами, включая нули.

Результат инструкции

На выходе будет orders-demo.xlsx в binary.export и короткий отчёт: три записи, исходные номера, roundtrip: true. Файл можно скачать из результата узла. Workflow работает локально, не пишет в CRM и не отправляет выгрузку наружу. Нейросеть для этой операции не нужна.

Это выгрузка данных без формул, диаграмм, нескольких листов и сложного оформления. Она не редактирует существующую книгу и не обновляет её ячейки: при запуске создаётся новый файл. Все заказы, товары и цены вымышленные.

Что понадобится

  • Локальный n8n и отдельный новый workflow. Проверено на n8n 2.42.4, Convert to File 1.1, Extract from File 1.1 и Code 2.
  • Скачиваемая JSON-схема из статьи. Microsoft Excel для самого экспорта не требуется.
  • Для ручного просмотра готового файла подойдёт установленный Excel или другой совместимый редактор. Проверка данных в инструкции выполняется внутри n8n.

Установить n8n локально через Docker

Шаг 1. Импортируйте учебный workflow

Скачать n8n-xlsx-export-roundtrip.json

Создайте новый workflow и выберите Import from File. Загрузите JSON, сохраните схему под именем «Учебный экспорт XLSX». Должны появиться семь соединённых узлов:

text
Manual Trigger → Sample Orders → Check Rows → Make XLSX → Check File → Read XLSX → Verify Export

Sample Orders, Check Rows, Check File и Verify Export — Code. Make XLSX — Convert to File, Read XLSX — Extract from File. Публиковать workflow не нужно: запуск будет ручным. Не заменяйте узлы в рабочей автоматизации.

Шаг 2. Проверьте исходные заказы

Откройте Sample Orders, выберите Run Once for All Items, JavaScript. Код уже есть в схеме:

javascript
return [
  {
    "order_id": "0001",
    "product": "Кофе",
    "quantity": 2,
    "price_rub": 1499.9
  },
  {
    "order_id": "0002",
    "product": "Чай",
    "quantity": 0,
    "price_rub": 0
  },
  {
    "order_id": "0003",
    "product": "Кружка",
    "quantity": 1,
    "price_rub": 350
  }
].map(json => ({ json }));
Поле Тип Пример
order_id Строка из четырёх цифр 0001, не число 1
product Непустая строка Кофе
quantity Целое неотрицательное число 2 или 0
price_rub Неотрицательное число 1499.9 или 0

Каждый объект становится отдельным item, а не лежит внутри общего массива orders. Кавычки вокруг "0001" обязательны: ведущие нули относятся к идентификатору. Если передать число 1, экспорт не сможет догадаться, сколько нулей вы потеряли. quantity и price_rub, наоборот, не заключайте в кавычки.

Шаг 3. Проверьте строки до экспорта

В Check Rows оставьте Run Once for All Items и JavaScript. При ручной сборке вставьте:

javascript
const items = $input.all();
if (items.length < 1 || items.length > 20) throw new Error('Expected 1-20 rows');
const seen = new Set();
return items.map(({ json: row }) => {
  if (Object.keys(row).sort().join('|') !== 'order_id|price_rub|product|quantity') {
    throw new Error('Unexpected or missing columns');
  }
  if (typeof row.order_id !== 'string' || !/^[0-9]{4}$/.test(row.order_id) || seen.has(row.order_id)) {
    throw new Error('Expected unique four-digit text ID');
  }
  seen.add(row.order_id);
  if (typeof row.product !== 'string' || !row.product.trim() || row.product.length > 80 || row.product.includes('\u0000')) {
    throw new Error('Invalid product');
  }
  if (!Number.isSafeInteger(row.quantity) || row.quantity < 0 || row.quantity > 1000000) {
    throw new Error('Quantity must be a nonnegative integer');
  }
  if (typeof row.price_rub !== 'number' || !Number.isFinite(row.price_rub) || row.price_rub < 0 || row.price_rub > 1000000) {
    throw new Error('Price must be a nonnegative number');
  }
  return { json: {
    order_id: row.order_id, product: row.product,
    quantity: row.quantity, price_rub: row.price_rub,
  } };
});

Проверка принимает от 1 до 20 строк, запрещает повторяющиеся номера, пропущенные и лишние поля. Количество ограничено целыми числами от 0 до 1000000, цена — конечным числом в том же диапазоне. Пустые названия и NUL тоже не проходят. Это учебные ограничения, не бизнес-правила для всех каталогов.

В конце код явно возвращает четыре поля в нужном порядке. Так случайная служебная заметка не попадёт в выгрузку. Не используйте проверку if (!row.quantity): она ошибочно отвергнет допустимый ноль. Здесь проверяются тип и диапазон.

Шаг 4. Настройте Convert to File на XLSX

В Make XLSX выберите Operation: Convert to XLSX. Сверьте параметры:

Поле Make XLSX Значение Назначение
Put Output File in Field export Файл в binary.export
File Name orders-demo.xlsx Имя создаваемого файла
Sheet Name Orders Название листа
Header Row Включено Первая строка с именами полей

Compression включите. Узел соберёт все входящие items в одну таблицу: первая строка — заголовки, следующие три — заказы. Режим XLSX задаётся операцией, а не одним расширением имени. Выбор CSV с именем orders-demo.xlsx не создаст книгу Excel.

В проверенной версии Make XLSX возвращает один item с файлом и пустым JSON. Это нормально: сам XLSX находится во вкладке Binary. Поля заказов не обязаны оставаться в JSON этого item, потому что они уже записаны в таблицу.

Шаг 5. Проверьте наличие файла

В Check File выберите Run Once for All Items, JavaScript и проверьте код:

javascript
const items = $input.all();
if (items.length !== 1 || Object.keys(items[0].binary ?? {}).join('|') !== 'export') {
  throw new Error('Expected one file in binary.export');
}
const item = items[0];
const file = item.binary.export;
if (file.fileName !== 'orders-demo.xlsx' || file.mimeType !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
  throw new Error('Expected orders-demo.xlsx');
}
const buffer = await this.helpers.getBinaryDataBuffer(0, 'export');
if (buffer.length < 4 || buffer.length > 100000 || buffer.readUInt32LE(0) !== 0x04034b50) {
  throw new Error('Expected a small XLSX ZIP package');
}
return [{ json: {}, binary: { export: file } }];

Он проверяет один файл, binary-поле, имя, MIME и небольшой размер. Начальные байты должны соответствовать ZIP-пакету, внутри которого хранится XLSX. Одна сигнатура ZIP ещё не доказывает правильность таблицы, поэтому следующий узел действительно прочитает книгу.

Используется getBinaryDataBuffer: при хранении binary на диске это правильный способ получить байты. Не интерпретируйте binary.export.data как текст Excel. XLSX не является обычным UTF-8 документом, его нельзя исправить заменой кодировки строки.

Шаг 6. Прочитайте лист обратно

Откройте Read XLSX. Выберите Operation: Extract From XLSX, Input Binary Field: export. В Options задайте Sheet Name: Orders, Header Row: включено и Include Empty Cells: включено. Range оставьте пустым, чтобы прочитать весь лист. Остальные параметры оставьте по умолчанию.

На выходе ожидаются три items с полями order_id, product, quantity и price_rub. Не задавайте другое имя листа: в этой книге он называется Orders, с заглавной O. При отключённом Header Row узел вернёт другую структуру, а имена колонок перестанут работать как ключи.

Параметры кодировки и разделителя из инструкции CSV сюда не переносятся. Для XLSX лист и ячейки уже находятся внутри книги. Include Empty Cells не превращает пустую ячейку в ноль: оно включает её в результат как пустую строку, которую наша строгая проверка не примет вместо числа.

Шаг 7. Сравните выгрузку с исходными данными

В Verify Export используйте Run Once for All Items, JavaScript:

javascript
const actual = $input.all().map(item => item.json);
const expected = $('Check Rows').all().map(item => item.json);
const columns = ['order_id', 'product', 'quantity', 'price_rub'];
if (actual.length !== expected.length) throw new Error('Row count changed');
for (let i = 0; i < expected.length; i++) {
  if (Object.keys(actual[i]).sort().join('|') !== [...columns].sort().join('|')) {
    throw new Error('Column names changed');
  }
  for (const key of columns) {
    if (actual[i][key] !== expected[i][key]) {
      throw new Error('Value or type changed: ' + key + ', row ' + (i + 1));
    }
  }
}
const file = $('Check File').first().binary.export;
return [{
  json: {
    file_name: 'orders-demo.xlsx', sheet: 'Orders', rows: actual.length,
    ids: actual.map(row => row.order_id), roundtrip: true, action: false,
  },
  binary: { export: file },
}];

Код сравнивает количество записей, названия полей, порядок строк, каждое значение и его тип с выходом Check Rows. Строка "0001" и число 1 не равны, строка "0" и число 0 тоже. Так ошибка не спрячется за одинаковым отображением в таблице.

Read XLSX возвращает строки без исходного binary. Поэтому Verify Export явно берёт файл из Check File и возвращает его рядом с отчётом. Скачать итог можно и из Make XLSX, и из Verify Export. Не переименовывайте Check Rows и Check File отдельно от ссылок на них в коде.

Шаг 8. Запустите всю цепочку

Сохраните workflow и нажмите Execute workflow от Manual Trigger. Не запускайте отдельно Verify Export без предыдущих узлов: ему нужны исходные строки и файл из текущего выполнения. Все семь узлов должны завершиться успешно.

Откройте JSON последнего узла. Для неизменённого примера ожидается один item:

json
{
  "file_name": "orders-demo.xlsx",
  "sheet": "Orders",
  "rows": 3,
  "ids": [
    "0001",
    "0002",
    "0003"
  ],
  "roundtrip": true,
  "action": false
}

roundtrip: true появляется после сравнения с обратным чтением. Это не статус от Microsoft Excel и не гарантия расчёта формул. В нашей книге формул нет. action: false означает отсутствие внешней отправки или бизнес-действия, а создание файла уже выполнено.

Шаг 9. Скачайте созданную книгу

Откройте выход Verify Export, перейдите во вкладку Binary и найдите поле export. Используйте кнопку Download для orders-demo.xlsx. Если Binary не видно, проверьте, что выбран Output последнего успешного выполнения, а не вход или только JSON.

Ниже доступен файл, полученный редакцией из этой же схемы. Он нужен для сравнения данных, но не заменяет ваш собственный запуск. В публичной ссылке имя дополнено префиксом n8n; внутри workflow создаётся orders-demo.xlsx.

Скачать учебный результат n8n-orders-demo.xlsx

Шаг 10. Проверьте данные в редакторе таблиц

Откройте скачанную книгу локально. Должен быть один лист Orders и диапазон A1:D4: четыре заголовка и три строки заказов. Номера — 0001, 0002, 0003. У Чая quantity и price_rub равны числовому нулю. У Кофе цена 1499.9: отображение десятичного разделителя зависит от локали редактора.

Это простая таблица без автофильтра, цветной шапки, заданной ширины колонок и формата валюты. При необходимости расширьте колонки в своём редакторе. Не заменяйте исходные числа строками "1 499,90 руб.", чтобы добиться оформления: числа перестанут быть числами. Для оформления нужен отдельный этап, а не подмена данных.

Редакционная проверка подтвердила значения и типы обратным чтением n8n и независимым импортом, а текстовые ID — также в XML ячеек самого XLSX. Клики скачивания в редакторе n8n и открытие в настольном Excel не тестировались.

Шаг 11. Проверьте отказ при дубликате

В Sample Orders временно замените номер второго заказа с 0002 на 0001, сохранив кавычки. Запустите workflow целиком. Check Rows должен остановиться с Expected unique four-digit text ID. Make XLSX не должен создать новую книгу в этом выполнении.

Теперь верните номер 0002 и выполните схему заново. Должны снова появиться файл и roundtrip: true. Не включайте Continue On Fail и Always Output Data, чтобы протащить неверные строки дальше. On Error оставьте Stop Workflow.

Шаг 12. Проверьте нули и пустой источник

Для короткой проверки замените quantity и price_rub первой записи на числовые 0 и снова запустите workflow. Обратное чтение должно сохранить оба нуля, проверка — пройти. После теста верните исходный пример, если хотите получить основной результат статьи.

Если источник вернул ноль items, n8n обычно не запускает последующие узлы. В нашем тесте Make XLSX не выполнился и файл не появился. Поэтому отсутствие ошибки у workflow не доказывает создание выгрузки. Пустой отчёт с одними заголовками требует отдельной ветки; в этой схеме она не реализована.

Если результат отличается

Симптом Причина Что проверить
ID стал числом Исходный номер передан числом Кавычки и проверку Check Rows
Нет binary export Другое поле или неверный узел Put Output File in Field: export
Лист не найден Не совпадает название Orders в записи и чтении
Не совпали строки или ключи Заголовки выключены или Range обрезан Header Row и пустой Range
Workflow успешен, файла нет Ноль входных items Данные источника и запуск Make XLSX

Границы примера

Проверка рассчитана на небольшую таблицу с четырьмя обязательными полями. Даты, пустые значения, формулы, денежные расчёты и преобразование единиц здесь не реализованы. Число в price_rub — учебная цена, не рассчитанная сумма заказа. Не добавляйте итоговые суммы, не определив правила округления.

Проверенный XLSX хранит строки, но это не общий аудит безопасности любых таблиц. Для чужих файлов и внешней отправки нужны отдельные проверки. В истории n8n могут сохраняться строки и binary; не используйте реальные клиентские данные, пока не настроены доступ и сроки хранения.

Отправить созданный файл через HTTP Request

Что проверено редакцией

17 октября 2026 года схема проверена на n8n 2.42.4 в отдельном Docker-экземпляре с binary на диске. Все 30 тестов прошли: основной пример, одна и двадцать записей, обратный порядок, Unicode, нули и строка с символом равенства; дубли, неверный ID, пустой товар, числовые поля строками, отрицательные значения, дробное количество, пропущенное или лишнее поле, превышение числа строк; неверное binary-поле, имя, CSV вместо XLSX, лист, заголовки, поле чтения, обрезанный диапазон и изменённые данные. Ноль items не создаёт файл. Скачиваемая книга получена штатным Convert to File и проверена обратным чтением, независимым импортом и XML ячеек. Файл не переоформлялся после экспорта. Визуальный предпросмотр независимого импортера отображал текстовые ID без нулей, хотя значения импорта и XML сохраняли 0001–0003; этот предпросмотр не используется как доказательство отображения Excel. Контейнер остановлен, существующие workflows не менялись. Cloud, клики редактора, настольный Excel, формулы и большие выгрузки не тестировались. Обложка — редакционная AI-иллюстрация.

Частые вопросы

Нужен установленный Excel, чтобы n8n создал XLSX?

Нет. Convert to File создаёт книгу внутри n8n. Редактор таблиц понадобится только для ручного просмотра или доработки оформления.

Почему номер 0001 нужно передавать строкой?

Это идентификатор, а не количество. У числа 1 нет ведущих нулей. В примере строковый тип проверяется до экспорта и после обратного чтения.

Почему в JSON Make XLSX нет заказов?

В проверенной версии узел возвращает один item с пустым JSON и готовым binary.export. Для чтения содержимого используется Extract from File.

Можно так дописать строки в существующий файл?

Не этой схемой. Она создаёт новую книгу из входящих items. Для обновления существующего документа нужен другой сценарий с явными правилами сохранения листов и данных.

Почему при пустом источнике нет даже файла с заголовками?

При нуле входных items последующие узлы в нашем тесте не выполнялись. Обработку пустой выгрузки нужно реализовать отдельной веткой, а не считать успешный статус доказательством наличия файла.

Дальше по теме

Похожие материалы