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

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

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

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

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

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


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

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

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


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

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

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

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

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

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

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

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

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

  2. Открываем поток для чтения из двоичных данных.

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

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

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

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

    Метод Прочитать() загрузит все содержимое PDF из потока в наш объект ДокументПДФ.

  4. Отображаем PDF-документ.

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

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

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


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

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

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

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

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

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

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

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

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

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

Этот код является наиболее правильным и эффективным способом для просмотра PDF-файлов, хранящихся в виде двоичных данных в 1С.

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

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

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


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

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

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

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

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

Мы видим, что этот подход более прост, если PDF-файл уже находится на диске. Однако, если данные хранятся в базе 1С, сначала потребуется сохранить их во временный файл, а затем уже использовать этот метод.

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

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

← К списку