n8n: распознавание чеков и счетов (PDF/фото) и занесение данных в таблицу

Ноутбук, док-станция и два монитора на рабочем столе n8n — автоматизация

Привет. Я бы тут делал так: n8n принимает PDF или фотку чека, гонит файл в OCR, вытаскивает продавца, дату, номер документа, валюту и сумму, потом нормализует поля и закидывает всё в Google Sheets. На практике это реально экономит часы ручной рутины, особенно когда чеки сыпятся из почты, мессенджера или общей папки.

В этой статье покажу рабочую схему, на каких нодах её собирать, как развести PDF и фото по разным веткам, где чаще всего всплывают косяки с OCR и что сделать, чтобы таблица не пухла от дублей. Плюс дам пример структуры полей, кусок кода для нормализации и чек-лист перед запуском.

Кому пригодится: мастерским, небольшим сервисам, бухгалтерам на потоке, продавцам на маркетплейсах и всем, кто устал копировать суммы руками из сканов и файлов.

Содержание

Ноутбук с таблицей расходов, бумажный счет и смартфон с фото кассового чека на столе

Что получится на выходе

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

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

Если уже работаешь с n8n, можешь заодно подсмотреть мой материал про вебхуки и защиту от дублей запросов. Там ровно тот участок, на котором новички чаще всего наступают на грабли при приёме файлов.

Как выглядит workflow в n8n

Я люблю простую, читаемую схему, чтобы потом не сидеть ночью и не вспоминать, где именно поломалась ветка с фотками. Каркас у меня обычно такой:

  1. Триггер: Webhook, Google Drive Trigger, Gmail Trigger, Telegram Trigger или папка на диске.
  2. Получение бинарного файла и служебных полей: имя, MIME-тип, размер, ссылка на исходник.
  3. Ветка по типу файла: PDF отправляю в одну сторону, JPG/PNG/HEIC — в другую.
  4. OCR или document AI: получаю текст или уже полуготовые поля.
  5. Нормализация через Edit Fields или Code.
  6. Проверка обязательных полей: дата, сумма, поставщик.
  7. Проверка дублей по своему ключу.
  8. Append row в Google Sheets.
  9. Логирование статуса и уведомление, если документ не распознался как надо.

Вот тут важный момент. Если PDF текстовый, иногда хватает простого извлечения текста и дальнейшего парсинга. Но если это скан, мятый чек с телефона или счёт в виде картинки внутри PDF, я сразу иду в OCR-сервис, а не пытаюсь выжать чудо из обычного чтения PDF. Так стабильнее.

Для развилки по файлам ставлю If или Switch: если MIME содержит pdf — маршрут на обработку документов; если image — на ветку фото. Это полезно ещё и потому, что разные OCR-движки по-разному едят входные данные. В одной ветке можно ждать многостраничный файл, в другой — одиночное фото с перспективой и тенями.

Логику записи в таблицу удобно сверять с материалом про обработку данных в Google Sheets через n8n. Там принцип тот же: сначала приводим поля к чистому виду, потом уже пишем строку, а не наоборот.

Какой OCR брать под чеки и счета

Тут я бы не женился на одном сервисе навсегда. Под разные задачи заходят разные варианты. Ниже короткая таблица, как я обычно выбираю движок.

ВариантКогда беруЧем нравитсяНа что смотрю внимательно
Mistral OCRСканы, фото, многостраничные PDFХорошо вытаскивает текст документа целикомПосле OCR всё равно прогоняю через схему полей
MindeeКогда нужен именно invoice/receipt OCRУмеет сразу отдавать поля документаПроверяю, все ли нужные поля есть в ответе
AWS TextractЕсли уже живёшь в экосистеме AWSНеплохо работает по счетамСхема становится тяжелее по настройке
OpenAI + схема полейКогда нужен гибкий разбор текста и фотоУдобно просить сразу JSON нужного форматаВажно жёстко задать структуру ответа
Google Drive OCR как запасной вариантКогда нужен бюджетный черновой проходБыстро проверить гипотезуНа таблицах и кривых сканах бывает капризным

Мой совет такой: если задача звучит как распознавание чеков по фото, OCR чеков PDF или извлечение данных из счета в таблицу, я сначала смотрю на Mistral OCR или Mindee. Они ближе к реальной задаче, чем голое выдёргивание текста. А уже потом поверх этого можно навесить Information Extractor, Structured Output Parser или обычную LLM-цепочку, чтобы привести ответ к единому JSON.

Если хочется стартануть быстрее, глянь подборку готовых шаблонов n8n. Часто проще взять каркас, чем собирать всё с нуля и потом искать потерявшийся бинарник между нодами.

Какие поля лучше сразу складывать в таблицу

Самая частая ошибка — тащить в таблицу весь распознанный хаос. Не надо. Таблица любит порядок. Я обычно держу такой набор колонок:

  • source_filename
  • source_url
  • document_type
  • vendor_name
  • document_number
  • document_date
  • currency
  • subtotal
  • tax
  • total
  • payment_method
  • items_json
  • ocr_text
  • dedupe_key
  • parse_status
  • review_comment
  • created_at

Зачем так много? Потому что через месяц ты сам себе скажешь спасибо. Когда OCR внезапно распознал общую сумму как номер счёта, поле review_comment спасает нервную систему. А items_json помогает не терять позиции товара, даже если в основную таблицу пишешь только одну строку на документ.

Для чеков я обычно добавляю ещё merchant_category или expense_type, если дальше нужен учёт расходов. Для счетов полезно поле due_date и отдельный статус: received, parsed, needs_review, approved. Тогда по таблице уже можно строить отчёты, напоминания и ежедневные сводки.

Как просить ИИ вернуть чистую структуру

Я формулирую задачу жёстко: верни JSON, где есть document_type, vendor_name, document_number, document_date, currency, total, tax и массив items. Если какого-то поля нет, верни null, а не фантазию. Это важнее, чем красивая формулировка промпта. Документный поток любит дисциплину.

Если потом захочешь на этой базе собирать уведомления, пригодится и схема про автосводку из Google Sheets в Telegram: там уже можно собрать ежедневный дайджест по новым чекам и счетам.

Как не словить дубли и кривые суммы

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

Самый практичный ключ — это склейка из названия продавца, номера документа, даты и нормализованной суммы. Если номер документа пустой, тогда беру vendor + дата + сумма + имя файла. Неидеально, но в бытовом потоке работает очень бодро.

return items.map(item => {
  const j = item.json;

  const total = Number(
    String(j.total ?? '')
      .replace(',', '.')
      .replace(/[^\d.]/g, '')
  );

  const dedupeKey = [
    (j.vendor_name || '').trim().toLowerCase(),
    (j.document_number || '').trim().toLowerCase(),
    (j.document_date || '').trim(),
    Number.isFinite(total) ? total.toFixed(2) : ''
  ].join('|');

  return {
    json: {
      ...j,
      total_normalized: Number.isFinite(total) ? total : null,
      dedupe_key: dedupeKey
    }
  };
});

Дальше этот ключ гоню в Remove Duplicates. Если поток идёт постоянно, очень удобно включать проверку не только внутри текущего запуска, но и между предыдущими исполнениями workflow. Так ты перестаёшь плодить повторные строки в таблице после случайных перезапусков.

Ещё один момент — формат суммы. OCR легко путается в запятых, пробелах и символах валюты. Поэтому на входе в Google Sheets я всегда держу отдельное число total_normalized и отдельно currency. Не надо складывать их в одну ячейку вида 1 250,50 руб., если потом хочешь что-то считать формулами.

Где чаще всего ломается схема

Я чаще всего вижу пять типовых проблем.

  1. Фото снято под углом, часть текста ушла в перспективу.
  2. На чеке бледная термопечать, и OCR съедает цифры.
  3. В PDF лежит картинка, а не текст, а человек думает, что это обычный PDF.
  4. ИИ выдумывает номер документа, когда его нет.
  5. Google Sheets получает поля в разном формате и строки едут криво.

Лечится это довольно приземлённо. Для фото — добавить шаг с проверкой качества или хотя бы отправлять такие документы в ручную проверку. Для бледных чеков — хранить сырой OCR-текст и ссылку на файл. Для фантазий модели — требовать null вместо догадок. Для таблицы — держать одну жёсткую схему колонок и не менять её на лету.

Отдельно советую собрать ветку ошибок с уведомлением. Очень выручает сценарий по контролю ошибок в n8n: retries, error workflow и нормальное оповещение экономят кучу времени, когда OCR-сервис внезапно отвечает не тем, что ты ждал.

Чек-лист перед запуском

  • Определи, откуда прилетает файл: папка, почта, форма, бот, webhook.
  • Разведи PDF и фото по разным веткам.
  • Выбери OCR-провайдера под свои документы, а не по красивому демо.
  • Задай жёсткую схему JSON-полей.
  • Нормализуй дату, сумму и валюту до записи в таблицу.
  • Сделай dedupe_key и включи проверку дублей.
  • Пиши в таблицу только чистые поля, сырой текст храни отдельно.
  • Добавь статус needs_review для сомнительных документов.
  • Настрой уведомление об ошибке и ручную точку контроля.

Итог

Если по-человечески, то n8n для распознавания счетов и чеков — это не какая-то космическая история. Рабочая связка давно понятна: приняли файл, прогнали через OCR, вытащили поля в единый JSON, проверили обязательные значения, убрали дубли и записали строку в таблицу. Самое важное тут не сам OCR, а аккуратная нормализация и дисциплина в структуре данных.

Я бы начинал с минимального конвейера на одну строку в таблице, а уже потом докручивал позиции товаров, категории расходов, сводки и уведомления. Так ты быстрее увидишь результат, поймаешь реальные ошибки на своих документах и не утонешь в лишней сложности на старте.

Когда эта схема завелась, она уже начинает работать как нормальный цех: документы заходят, данные падают в таблицу, а ты занимаешься делом, а не копипастой дат и сумм из сканов.

Оцените статью
Добавить комментарий

Мы используем cookie-файлы для наилучшего представления нашего сайта. Продолжая использовать этот сайт, вы соглашаетесь с использованием cookie-файлов.
Пофиг
Политика конфиденциальности