Почему возникает ошибка «Неправильный заголовок PDF файла» при открытии документа в 1С и как её исправить?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

При разработке подсистем предварительного просмотра документов на платформе 1С:Предприятие часто используется специализированный объект ДокументPDF совместно с элементом формы ПолеPDFДокумента. Однако на практике разработчики регулярно сталкиваются с ситуацией, когда большинство файлов открывается корректно, но отдельные PDF-документы вызывают исключение «Неправильный заголовок PDF файла» либо приводят к аварийному завершению работы платформы. При этом внешние программы просмотра (например, Adobe Acrobat Reader или веб-браузеры) открывают те же самые файлы без каких-либо нареканий.

Проанализируем типовой фрагмент клиентского кода, приводящий к ошибке:


ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(ТекущиеДанные.АдресФайла);
Поток = ДвоичныеДанныеФайла.ОткрытьПотокДляЧтения();
ПросмотрPDF.Прочитать(Поток);

Выясним причину такого поведения встроенного механизма платформы и рассмотрим по шагам, как обойти эту проблему или устранить её корень.

Причины сбоя встроенного парсера 1С

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

  1. Строгие требования платформы к сигнатуре файла. По стандарту формат PDF должен начинаться с сигнатуры %PDF- (шестнадцатеричные байты 25 50 44 46 2D). Внешние ридеры обладают высокой отказоустойчивостью: они могут просканировать первые сотни байт файла, пропуская пустые строки, пробелы, метку порядка байтов UTF-8 BOM (EF BB BF) или служебный мусор, оставленный веб-серверами и сканерами. Встроенный парсер платформы 1С требует, чтобы сигнатура находилась строго со смещения 0. Любой байт перед ней воспринимается как повреждение заголовка.
  2. Неподдерживаемые элементы спецификаций. Файлы версии PDF 2.0, документы с нестандартным сжатием потоков объектов (ObjStm), специфические линейные структуры (Fast Web View) или нестандартное шифрование часто не могут быть обработаны подмножеством стандарта, реализованным в объекте ДокументPDF.
  3. Ошибки платформы конкретных релизов. В некоторых версиях (в частности, ветки 8.3.25) парсинг сложных или слегка отклоняющихся от стандарта файлов содержит ошибки, которые в критических случаях приводят к аварийному падению процесса 1cv8c.exe.

Способ 1. Обновление версии платформы 1С:Предприятие

Рассмотрим самое простое и прямое решение проблемы. Ошибки разбора бинарных данных и нестандартных заголовков регулярно исправляются разработчиками платформы. Если в используемой версии (например, 8.3.25.1445) парсер завершает работу аварийно или не распознает документ, рекомендуется обновить платформу на актуальный релиз ветки 8.3.26 или 8.3.27, где механизмы работы с объектом ДокументPDF были существенно доработаны.

Способ 2. Чтение из временного файла вместо потока в памяти

Посмотрим на практическую особенность реализации методов Прочитать(). В ряде релизов поведение платформы различается в зависимости от того, передается ли в метод интерфейс ПотокВПамяти или путь к файлу на диске. Чтение из физического файла на клиенте отрабатывает более стабильно.

Перепишем исходный код с сохранением двоичных данных во временный каталог:


ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(ТекущиеДанные.АдресФайла);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("pdf");
ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);

Попытка
    ПросмотрPDF.Прочитать(ИмяВременногоФайла);
Исключение
    ВызватьИсключение;
Финально
    УдалитьФайлы(ИмяВременногоФайла);
КонецПопытки;

Способ 3. Очистка мусора и смещения перед заголовком %PDF-

Проанализируем ситуацию, когда сторонний источник (веб-сервер или МФУ) добавил перед заголовком документа лишние символы или байты BOM. В этом случае мы можем нормализовать двоичные данные перед открытием: найти позицию сигнатуры %PDF- и отсечь всё, что находится перед ней.

Разберем алгоритм исправления двоичных данных:

  1. Открываем двоичные данные и считываем первые байты (например, первые 1024 байта).
  2. Находим индекс вхождения последовательности %PDF-.
  3. Если сигнатура найдена со смещением больше 0, создаем новый поток или буфер, копируя данные начиная с найденной позиции до конца файла.
  4. Передаем очищенные данные в ПросмотрPDF.Прочитать().

Способ 4. Нормализация файла внешними утилитами на сервере

Если входящие PDF-файлы формируются внешними системами с систематическими ошибками в структуре (например, поврежденными таблицами перекрестных ссылок xref), целесообразно выполнять их предварительную нормализацию на стороне сервера при загрузке. Для этого подходят консольные утилиты вроде qpdf, Ghostscript или pdfcpu. Вызов утилиты с ключом линейной пересборки файла перезаписывает заголовок со смещения 0 и исправляет смещения всех внутренних объектов, делая файл абсолютно валидным для 1С.

Способ 5. Использование альтернативных вариантов отображения

Если специфика документов не позволяет отобразить их через встроенный ДокументPDF, а обновить платформу нет возможности, рассмотрим альтернативные механизмы просмотра внутри формы:

  1. Отображение через ПолеHTMLДокумента и PDF.js. В форму помещается элемент ПолеHTMLДокумента, куда внедряется библиотека PDF.js. Этот движок рендеринга полностью независим от багов платформы 1С и справляется практически с любыми поврежденными или нестандартными PDF-файлами.
  2. Открытие в ассоциированном внешнем приложении. Если встроенный предпросмотр не критичен, двоичные данные выгружаются во временный каталог через КаталогВременныхФайлов(), после чего вызывается команда ЗапуститьПриложение() или ЗапуститьПриложениеАсинх(). Документ откроется в установленном у пользователя Acrobat Reader или браузере без каких-либо ошибок.
← На главную