Извлекаем текст из PDF средствами 1С:Предприятия 8.3 — от IFilter до OCR

· 10 мин

Содержание

Встроенного парсера PDF в платформе 1С 8.3 нет: табличный документ умеет сохранять в PDF, но не открывать его. Прочитать PDF файл в 1С можно тремя путями: объектом ИзвлечениеТекста (работает через установленный в Windows фильтр PDF), вызовом внешней утилиты pdftotext с последующим чтением текстового файла или через COM-объект программы, которая понимает PDF. Для сканов без текстового слоя нужен отдельный шаг распознавания.

Типичная ситуация: поставщик присылает счета в PDF, и бухгалтер просит «чтобы 1С сама вытаскивала ИНН и сумму». Задача решается, но сначала надо понять, какой перед вами PDF и где будет выполняться код — на клиенте или на сервере.

Что внутри PDF и почему 1С не читает его напрямую

PDF — это не текстовый файл, а описание страницы для печати. Внутри лежат объекты: шрифты, картинки и потоки команд «нарисуй такие символы в такой точке листа».

Что мешает прочитать его как обычный файл:

  • 🗜️ Сжатие. Потоки содержимого почти всегда упакованы алгоритмом FlateDecode. Средствами 1С распаковать такой поток напрямую нельзя: ЧтениеZipФайла работает с zip-архивами, а не с отдельными сжатыми потоками.
  • 🔤 Кодировки шрифтов. Символы часто хранятся как номера глифов. Чтобы превратить их в буквы, нужна таблица ToUnicode. Если создатель файла её не встроил, даже профессиональные утилиты выдают «кракозябры».
  • 📐 Порядок текста. Строки в файле идут в том порядке, в каком их нарисовал генератор, а не в порядке чтения. Таблица может превратиться в столбик слов.
  • 🖼️ Сканы. Отсканированный документ — это картинка, завёрнутая в PDF. Текста там нет вообще.

Отсюда практичный вывод: не пишите свой разбор PDF на встроенном языке. Отдайте извлечение текста готовому инструменту, а в 1С обрабатывайте уже обычную строку.

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

Способы прочитать PDF в 1С 8.3: сравнение

СпособЧто нужно установитьГде работаетПлюсыМинусы
ИзвлечениеТекстаPDF IFilter (Adobe, Foxit и др.)WindowsДве строки кодаЗависит от фильтра, порядок текста не управляется
pdftotext (Poppler или Xpdf)Утилита, без регистрации в системеWindows и Linux, клиент и серверБесплатно, режим -layout сохраняет колонкиНужен временный файл и запуск процесса
COM Adobe AcrobatПлатный Acrobat (не Reader)WindowsТочное извлечениеЛицензия, только клиент или сервер с GUI
COM Microsoft WordWord 2013 и новееWindowsЕсть почти у всехМедленно, ломает вёрстку таблиц
Внешняя компонентаСвоя DLL или готовая компонентаЗависит от сборкиРаботает без внешних программНужна разработка на C++
OCR (Tesseract)Tesseract + pdftoppmWindows и LinuxЧитает сканыОшибки распознавания, нужна проверка
Какой у вас PDF и где работает база?

Чтение PDF через объект ИзвлечениеТекста и COM-объекты

Платформенный объект ИзвлечениеТекста

В платформе есть объект ИзвлечениеТекста. Он отдаёт файл системным фильтрам Windows (IFilter) — тем же, через которые работает поиск Windows по содержимому файлов. На этом механизме построено извлечение текста для полнотекстового поиска в БСП.

&НаСервере
Функция ТекстИзPDFЧерезФильтр(ПутьКФайлу)

    Извлечение = Новый ИзвлечениеТекста(ПутьКФайлу);
    Возврат Извлечение.ПолучитьТекст();

КонецФункции

Код короткий, но есть условие: на компьютере, где он выполняется, должен быть установлен 64-битный или 32-битный PDF IFilter той же разрядности, что и процесс 1С. Без фильтра метод вернёт пустую строку или вызовет исключение. На сервере 1С фильтр ставят на машину с рабочими процессами, а не на компьютер пользователя.

Если код помечен &НаСервере, файл должен лежать там, где его видит сервер. Путь C:\Users\buh\Desktop\счёт.pdf с компьютера бухгалтера сервер не найдёт.

Adobe Acrobat через COM

Если в организации куплен Acrobat Pro или Standard, его COM-сервер умеет сохранить документ как простой текст. Бесплатный Acrobat Reader COM-объектов AcroExch не регистрирует — на нём этот код не заработает.

&НаКлиенте
Функция ТекстИзPDFЧерезAcrobat(ПутьКФайлу)

    ИмяТекста = ПолучитьИмяВременногоФайла("txt");
    Документ = Новый COMОбъект("AcroExch.PDDoc");
    Если Не Документ.Open(ПутьКФайлу) Тогда
        ВызватьИсключение "Acrobat не смог открыть файл " + ПутьКФайлу;
    КонецЕсли;

    JS = Документ.GetJSObject();
    JS.saveAs(ИмяТекста, "com.adobe.acrobat.plain-text");
    Документ.Close();

    Текст = Новый ТекстовыйДокумент;
    Текст.Прочитать(ИмяТекста);
    Результат = Текст.ПолучитьТекст();
    УдалитьФайлы(ИмяТекста);
    Возврат Результат;

КонецФункции

Кодировку текстового файла Acrobat выбирает сам, поэтому Прочитать вызван без явной кодировки: платформа определит её по метке BOM. Если кириллица побилась — укажите кодировку явно.

Microsoft Word через COM

Word начиная с версии 2013 открывает PDF и конвертирует его в редактируемый документ. Через COM это выглядит так: создаёте Word.Application, открываете файл методом Documents.Open с параметром ConfirmConversions = False, берёте Content.Text, закрываете документ без сохранения и вызываете Quit().

Подходит для разовых задач. Для потока документов — нет: конвертация занимает секунды на страницу, Word может показать диалог и «зависнуть» в фоне, а таблицы он раскладывает непредсказуемо. На сервере 1С офисные программы через COM запускать не стоит: Microsoft не поддерживает такой сценарий для служб.

Если Новый COMОбъект выдаёт ошибку создания объекта, первым делом проверьте разрядность. 64-битный клиент 1С не создаст in-process COM-объект, у которого есть только 32-битная регистрация.

Внешние компоненты и библиотеки для разбора PDF

Под «подключением dll» в 1С обычно понимают внешнюю компоненту. Это библиотека, написанная по технологии Native API (C++) или COM, которую подключают методом ПодключитьВнешнююКомпоненту и затем создают как объект AddIn.ИмяКомпоненты.

Варианты на практике:

  1. 🧩 Готовая компонента. Есть коммерческие и открытые компоненты для работы с PDF. Перед покупкой проверьте, что она поддерживает нужную разрядность клиента и сервера, Linux (если сервер на нём) и именно извлечение текста, а не только создание PDF.
  2. 🛠️ Своя Native API компонента. Внутри — любая C++ библиотека разбора PDF, снаружи — один метод «дай текст по пути к файлу». Требует программиста на C++ и сборки под каждую нужную разрядность и ОС.
  3. 🔗 .NET-сборка через COM. Библиотеку на C# с открытой лицензией регистрируют как COM-видимую сборку (regasm /codebase). В 1С её создают через Новый COMОбъект. Работает только на Windows.

Компоненту удобно хранить в общем макете с типом «Внешняя компонента» или «Двоичные данные» и подключать по адресу во временном хранилище. Тогда её не надо раскладывать по компьютерам вручную.

Компонента оправдана, когда документов тысячи и запуск внешней программы на каждый файл заметно тормозит. Для десятков файлов в день pdftotext проще и надёжнее.

Пошаговое чтение PDF во внешней обработке через pdftotext

Самый универсальный вариант. pdftotext входит в пакеты Poppler (Linux: пакет poppler-utils) и Xpdf (есть сборки для Windows). Утилита не требует установки в систему: достаточно распаковать архив.

Шаг 1. Установите утилиту на нужную машину

  • Файловая база или код &НаКлиенте — на компьютер пользователя.
  • Клиент-серверная база и код &НаСервере — на сервер 1С, где работают рабочие процессы.
  • Проверьте вручную в командной строке: pdftotext -enc UTF-8 -layout счёт.pdf счёт.txt. Если файл с текстом появился — утилита работает.

Шаг 2. Создайте внешнюю обработку

В Конфигураторе: Файл → Новый → Внешняя обработка. Добавьте реквизит ПутьКФайлу (строка) и Результат (строка неограниченной длины, на форме — многострочное поле). Команда формы вызывает серверную функцию.

Шаг 3. Напишите функцию извлечения

&НаСервереБезКонтекста
Функция ПрочитатьPDF(ПутьКФайлу, ПутьКУтилите = "C:\poppler\bin\pdftotext.exe")

    ИмяТекста = ПолучитьИмяВременногоФайла("txt");
    Команда = СтрШаблон("""%1"" -enc UTF-8 -layout ""%2"" ""%3""",
        ПутьКУтилите, ПутьКФайлу, ИмяТекста);

    КодВозврата = 0;
    ЗапуститьПриложение(Команда, , Истина, КодВозврата);

    ФайлТекста = Новый Файл(ИмяТекста);
    Если КодВозврата <> 0 Или Не ФайлТекста.Существует() Тогда
        ВызватьИсключение СтрШаблон("pdftotext завершился с кодом %1",
            Формат(КодВозврата, "ЧН=0; ЧГ=0"));
    КонецЕсли;

    Текст = Новый ТекстовыйДокумент;
    Текст.Прочитать(ИмяТекста, КодировкаТекста.UTF8);
    Результат = Текст.ПолучитьТекст();
    УдалитьФайлы(ИмяТекста);

    Возврат Результат;

КонецФункции

Ключи утилиты, которые пригодятся:

КлючЧто делает
-enc UTF-8Кодировка результата. Без него кириллица может прийти в другой кодировке
-layoutСохраняет расположение колонок — удобно для таблиц
-f 1 -l 1Читать только с первой по первую страницу
-upw парольПароль пользователя для защищённого файла

На Linux-сервере путь к утилите обычно /usr/bin/pdftotext, кавычки вокруг путей оставьте — они спасают от пробелов в именах.

Шаг 4. Передайте файл с клиента на сервер

Если пользователь выбирает файл на своём компьютере, а утилита стоит на сервере, файл нужно переслать. На клиенте поместите его во временное хранилище (НачатьПомещениеФайлаНаСервер в современных релизах платформы), на сервере получите ДвоичныеДанные через ПолучитьИзВременногоХранилища, запишите их во временный файл методом Записать и передайте этот путь в ПрочитатьPDF.

Шаг 5. Разберите текст

Извлечённый текст — обычная строка. Делите её на строки через СтрРазделить(Текст, Символы.ПС) и ищите нужные места. Пример: вытащить ИНН, который стоит после слова «ИНН».

Функция НайтиИНН(Текст)

    Позиция = СтрНайти(Текст, "ИНН");
    Если Позиция = 0 Тогда
        Возврат "";
    КонецЕсли;

    Результат = "";
    Граница = Мин(Позиция + 40, СтрДлина(Текст));
    Для Индекс = Позиция + 3 По Граница Цикл
        Символ = Сред(Текст, Индекс, 1);
        Если СтрНайти("0123456789", Символ) > 0 Тогда
            Результат = Результат + Символ;
        ИначеЕсли СтрДлина(Результат) > 0 Тогда
            Прервать;
        КонецЕсли;
    КонецЦикла;

    Возврат Результат;

КонецФункции

Для строки ИНН/КПП 7701234567/770101001 функция пропустит «/КПП », соберёт 7701234567 и остановится на косой черте. Проверяйте длину результата: 10 цифр у организации, 12 у ИП.

Не записывайте распознанные реквизиты сразу в проведённые документы. Создавайте документ без проведения или показывайте пользователю форму сверки. Одна смещённая колонка — и сумма попадёт в поле НДС.

Распознавание сканов: OCR для PDF без текстового слоя

Если pdftotext вернул пустую строку или несколько пробелов, в файле картинки. Тут нужен OCR. Бесплатная связка — Poppler и Tesseract.

  1. Превратите страницы в изображения: pdftoppm -r 300 -png скан.pdf стр. Появятся файлы стр-1.png, стр-2.png и так далее. При десяти и более страницах номера дополняются нулями, поэтому ищите их по маске НайтиФайлы(Каталог, "стр-*.png"), а не собирайте имена вручную.
  2. Распознайте каждую картинку: tesseract стр-1.png стр-1 -l rus+eng. Tesseract сам добавит расширение и создаст стр-1.txt в UTF-8.
  3. Прочитайте текстовые файлы тем же ТекстовыйДокумент.Прочитать(..., КодировкаТекста.UTF8) и склейте.
  4. Удалите временный каталог.

Для русского языка нужен файл языковых данных rus.traineddata. В установщике для Windows его отмечают галочкой, на Linux ставят отдельным пакетом языка.

Что влияет на качество распознавания:

  • 📏 Разрешение. Ниже 300 dpi мелкий шрифт в таблицах распознаётся плохо.
  • 📐 Перекос. Лист, отсканированный под углом, даёт перепутанные строки.
  • 🖊️ Печати и подписи поверх текста. Цифры под синей печатью — частый источник ошибок в суммах.

Альтернатива — утилита OCRmyPDF: она добавляет в скан невидимый текстовый слой, после чего файл читается обычным pdftotext. Для потоковой обработки первички есть и коммерческие сервисы распознавания, включая «1С:Распознавание первичных документов». Они понимают структуру счёта и УПД, а не только буквы, но работают по подписке.

Ошибки при чтении PDF в 1С и как их исправить

Диагностика: выберите симптом

Ещё две проблемы, которые не видны сразу:

  • 🔐 Файл защищён паролем. pdftotext без ключа -upw завершится с ненулевым кодом. Пароль хранят в настройках обработки, а не в коде.
  • 🧹 Мусор во временном каталоге. Если между созданием файла и УдалитьФайлы возникло исключение, файл останется. Оборачивайте чтение в Попытка … Исключение, а удаление вызывайте в обеих ветках.

Частые вопросы о чтении PDF в 1С

Можно ли открыть PDF в табличном документе 1С?
Нет. Табличный документ сохраняет в PDF, но не загружает из него. Текст получают одним из внешних способов и уже потом выводят в табличный документ.
Получится ли прочитать PDF в веб-клиенте?
Код на клиенте в браузере не может запускать программы и создавать COM-объекты. Передайте файл на сервер и извлекайте текст там.
Как вытащить из PDF таблицу с товарами?
Используйте pdftotext с ключом -layout: колонки останутся на своих позициях. Затем режьте каждую строку по позициям символов или по группам пробелов, начиная со строки заголовка таблицы.
Что быстрее на большом потоке: pdftotext или внешняя компонента?
Компонента не тратит время на запуск процесса, поэтому быстрее на тысячах файлов. На десятках документов в день разница незаметна.
Подойдёт ли этот подход для электронных документов из ЭДО?
Для формализованных документов ЭДО читать PDF не нужно: в них есть XML, который 1С загружает напрямую. PDF разбирают только тогда, когда контрагент прислал сканы или печатные формы по почте.