Как правильно просмотреть PDF-файл, сохраненный в 1С, используя встроенные средства платформы 8.3?

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

При работе с платформой 1С:Предприятие версии 8.3 и выше, особенно начиная с 8.3.21, работа с PDF файлами в 1С без внешних компонентов становится значительно проще благодаря штатному объекту ДокументPDF. Часто возникает задача отобразить PDF-файл, который хранится непосредственно в базе данных 1С, например, в реквизите типа ХранилищеЗначений или в виде двоичных данных — для этого пригодится мобильное сканирование и прикрепление PDF к карточкам 1С. Давайте вместе разберем, как эффективно решить эту задачу.

Понимание проблемы и анализ неверных подходов

Многие разработчики, столкнувшись с необходимостью отобразить PDF, начинают экспериментировать с различными методами. Рассмотрим типичные ошибки, чтобы понять, почему они не работают, и избежать их в будущем.

Первая распространенная ошибка заключается в попытке передать в метод Прочитать() объекта ДокументPDF неверный тип данных. Например, можно попробовать передать ссылку на объект, содержащий двоичные данные, или сам объект ХранилищеЗначений:


// Неверный вариант 1: Попытка прочитать из ссылки или объекта
Поток = СсылкаНаСканОбраз.ОткрытьПотокДляЧтения(); // СсылкаНаСканОбраз - возможно, ссылка на объект ИБ
ДокументПДФ = Новый ДокументPDF();
ДокументПДФ.Прочитать(СсылкаНаСканОбраз); // Здесь СсылкаНаСканОбраз не является ни именем файла, ни потоком
СсылкаНаСканОбраз = ДокументПДФ;
ДокументПДФ.Показать(СсылкаНаСканОбраз); // Аргумент метода Показать() тоже неверный

Мы видим, что здесь происходит смешивание понятий. Объект ДокументPDF ожидает либо полный путь к файлу на диске, либо поток двоичных данных. Передача ссылки на объект информационной базы или самого объекта ХранилищеЗначений напрямую не соответствует сигнатуре метода Прочитать().

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


// Неверный вариант 2: Использование ПолучитьНавигационнуюСсылку и ПолучитьИзВременногоХранилища
СсылкаНаСканОбраз = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "СканОбразДоговора");
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(СсылкаНаСканОбраз);
Поток = ДвоичныеДанныеФайла.ОткрытьПотокДляЧтения();
СсылкаНаСканОбраз.Прочитать(Поток); // Опять же, СсылкаНаСканОбраз - не объект ДокументPDF

В этом примере мы используем ПолучитьНавигационнуюСсылку() и ПолучитьИзВременногоХранилища(). Эти методы полезны, например, для передачи данных между клиентом и сервером или для работы с файлами, временно помещенными в хранилище. Однако для непосредственного чтения PDF-документа, когда двоичные данные уже доступны, такой подход является избыточным.

Решение: Чтение PDF из потока двоичных данных

Правильный и наиболее универсальный способ работы с PDF-документами, хранящимися в 1С, заключается в использовании метода Прочитать() объекта ДокументPDF с передачей ему потока двоичных данных. Давайте разберем этот процесс по шагам.

  1. Получаем двоичные данные PDF-файла.

    Начнем с получения самих двоичных данных. Если PDF-файл хранится в реквизите объекта информационной базы типа ХранилищеЗначений, мы можем получить его содержимое с помощью метода Получить(). Результатом будет объект типа ДвоичныеДанные.

    Предположим, у нас есть объект базы данных, и у него есть реквизит СканОбразДоговора. Мы можем получить их так:

    
    // Получаем двоичные данные из ХранилищаЗначений
    ДвоичныеДанныеФайла = Объект.Ссылка.СканОбразДоговора.Получить(); 
    
  2. Открываем поток для чтения из двоичных данных.

    Объект ДвоичныеДанные имеет полезный метод ОткрытьПотокДляЧтения(). Аналогичные низкоуровневые операции рассматриваются в статье распаковщик и запаковщик файлов, где автор подробно описывает работу с потоками и буферами. Именно этот поток мы и будем использовать для чтения содержимого PDF.

    
    // Открываем поток для чтения из полученных двоичных данных
    ПотокДляЧтения = ДвоичныеДанныеФайла.ОткрытьПотокДляЧтения();
    
  3. Создаем объект ДокументPDF и считываем в него данные из потока.

    Теперь, когда у нас есть поток, мы можем создать экземпляр объекта ДокументPDF и использовать его метод Прочитать(). Если PDF-документ защищен паролем, мы можем передать его вторым параметром.

    
    // Создаем новый объект ДокументPDF
    ДокументПДФ = Новый ДокументPDF();
    
    // Считываем PDF-документ из потока
    ДокументПДФ.Прочитать(ПотокДляЧтения);
    
  4. Отображаем PDF-документ.

    После успешного чтения, мы можем отобразить PDF-документ пользователю с помощью метода Показать(). Если же ваша задача требует модификации файла перед показом, например, добавление водяных знаков на pdf файлы, вам потребуются дополнительные инструменты обработки.

    
    // Отображаем PDF-документ пользователю
    ДокументПДФ.Показать();
    

Соберем все шаги в единый, рабочий пример кода:


&НаКлиенте
Процедура ПоказатьСканОбразДоговора()

    // 1. Получаем двоичные данные из ХранилищаЗначений
    ПеременнаяХранилища = Объект.Ссылка.СканОбразДоговора;

    Если ПеременнаяХранилища = Неопределено Тогда
        Сообщить("Скан-образ договора отсутствует.");
        Возврат;
    КонецЕсли;

    Попытка
        ДвоичныеДанныеФайла = ПеременнаяХранилища.Получить();

        Если ДвоичныеДанныеФайла = Неопределено Тогда
            Сообщить("Не удалось получить двоичные данные скан-образа.");
            Возврат;
        КонецЕсли;

        // 2. Открываем поток для чтения из двоичных данных
        ПотокДляЧтения = ДвоичныеДанныеФайла.ОткрытьПотокДляЧтения();

        // 3. Создаем объект ДокументPDF и считываем в него данные из потока
        ДокументПДФ = Новый ДокументPDF();
        ДокументПДФ.Прочитать(ПотокДляЧтения);

        // 4. Отображаем PDF-документ пользователю
        ДокументПДФ.Показать();

    Исключение
        Сообщить("Ошибка при просмотре PDF-документа: " + ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

Альтернативное решение: Чтение PDF из файла на диске

Объект ДокументPDF также позволяет читать файлы непосредственно с диска. Это полезно при использовании внешних утилит, когда выполняется программная конвертация отчетов 1С в графический формат или когда файл предварительно выгружен во временный каталог.

Метод Прочитать() имеет перегрузку, которая принимает в качестве первого параметра полный путь к файлу:


// Пример чтения PDF из файла на диске
&НаКлиенте
Процедура ПоказатьPDFИзФайла()

    ИмяФайлаPDF = "C:\МоиДокументы\Договор.pdf"; 

    Если Не ФайлСуществует(ИмяФайлаPDF) Тогда
        Сообщить("Файл PDF не найден по указанному пути.");
        Возврат;
    КонецЕсли;

    Попытка
        ДокументПДФ = Новый ДокументPDF();
        ДокументПДФ.Прочитать(ИмяФайлаPDF);
        ДокументПДФ.Показать();
    Исключение
        Сообщить("Ошибка при просмотре PDF-документа: " + ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

Важные замечания

Теперь, когда мы подробно рассмотрели все аспекты и примеры, вы сможете уверенно работать с просмотром PDF-файлов средствами платформы 1С:Предприятие.

← На главную