При работе с платформой 1С:Предприятие версии 8.3 и выше, особенно начиная с 8.3.21, работа с PDF файлами в 1С без внешних компонентов становится значительно проще благодаря штатному объекту ДокументPDF. Часто возникает задача отобразить PDF-файл, который хранится непосредственно в базе данных 1С, например, в реквизите типа ХранилищеЗначений или в виде двоичных данных — для этого пригодится мобильное сканирование и прикрепление PDF к карточкам 1С. Давайте вместе разберем, как эффективно решить эту задачу.
Многие разработчики, столкнувшись с необходимостью отобразить PDF, начинают экспериментировать с различными методами. Рассмотрим типичные ошибки, чтобы понять, почему они не работают, и избежать их в будущем.
Первая распространенная ошибка заключается в попытке передать в метод Прочитать() объекта ДокументPDF неверный тип данных. Например, можно попробовать передать ссылку на объект, содержащий двоичные данные, или сам объект ХранилищеЗначений:
// Неверный вариант 1: Попытка прочитать из ссылки или объекта
Поток = СсылкаНаСканОбраз.ОткрытьПотокДляЧтения(); // СсылкаНаСканОбраз - возможно, ссылка на объект ИБ
ДокументПДФ = Новый ДокументPDF();
ДокументПДФ.Прочитать(СсылкаНаСканОбраз); // Здесь СсылкаНаСканОбраз не является ни именем файла, ни потоком
СсылкаНаСканОбраз = ДокументПДФ;
ДокументПДФ.Показать(СсылкаНаСканОбраз); // Аргумент метода Показать() тоже неверный
Мы видим, что здесь происходит смешивание понятий. Объект ДокументPDF ожидает либо полный путь к файлу на диске, либо поток двоичных данных. Передача ссылки на объект информационной базы или самого объекта ХранилищеЗначений напрямую не соответствует сигнатуре метода Прочитать().
Вторая распространенная ошибка связана с излишним усложнением получения двоичных данных, используя методы, предназначенные для других целей:
// Неверный вариант 2: Использование ПолучитьНавигационнуюСсылку и ПолучитьИзВременногоХранилища
СсылкаНаСканОбраз = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "СканОбразДоговора");
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(СсылкаНаСканОбраз);
Поток = ДвоичныеДанныеФайла.ОткрытьПотокДляЧтения();
СсылкаНаСканОбраз.Прочитать(Поток); // Опять же, СсылкаНаСканОбраз - не объект ДокументPDF
В этом примере мы используем ПолучитьНавигационнуюСсылку() и ПолучитьИзВременногоХранилища(). Эти методы полезны, например, для передачи данных между клиентом и сервером или для работы с файлами, временно помещенными в хранилище. Однако для непосредственного чтения PDF-документа, когда двоичные данные уже доступны, такой подход является избыточным.
Правильный и наиболее универсальный способ работы с PDF-документами, хранящимися в 1С, заключается в использовании метода Прочитать() объекта ДокументPDF с передачей ему потока двоичных данных. Давайте разберем этот процесс по шагам.
Получаем двоичные данные PDF-файла.
Начнем с получения самих двоичных данных. Если PDF-файл хранится в реквизите объекта информационной базы типа ХранилищеЗначений, мы можем получить его содержимое с помощью метода Получить(). Результатом будет объект типа ДвоичныеДанные.
Предположим, у нас есть объект базы данных, и у него есть реквизит СканОбразДоговора. Мы можем получить их так:
// Получаем двоичные данные из ХранилищаЗначений
ДвоичныеДанныеФайла = Объект.Ссылка.СканОбразДоговора.Получить();
Открываем поток для чтения из двоичных данных.
Объект ДвоичныеДанные имеет полезный метод ОткрытьПотокДляЧтения(). Аналогичные низкоуровневые операции рассматриваются в статье распаковщик и запаковщик файлов, где автор подробно описывает работу с потоками и буферами. Именно этот поток мы и будем использовать для чтения содержимого PDF.
// Открываем поток для чтения из полученных двоичных данных
ПотокДляЧтения = ДвоичныеДанныеФайла.ОткрытьПотокДляЧтения();
Создаем объект ДокументPDF и считываем в него данные из потока.
Теперь, когда у нас есть поток, мы можем создать экземпляр объекта ДокументPDF и использовать его метод Прочитать(). Если PDF-документ защищен паролем, мы можем передать его вторым параметром.
// Создаем новый объект ДокументPDF
ДокументПДФ = Новый ДокументPDF();
// Считываем PDF-документ из потока
ДокументПДФ.Прочитать(ПотокДляЧтения);
Отображаем PDF-документ.
После успешного чтения, мы можем отобразить PDF-документ пользователю с помощью метода Показать(). Если же ваша задача требует модификации файла перед показом, например, добавление водяных знаков на pdf файлы, вам потребуются дополнительные инструменты обработки.
// Отображаем PDF-документ пользователю
ДокументПДФ.Показать();
Соберем все шаги в единый, рабочий пример кода:
&НаКлиенте
Процедура ПоказатьСканОбразДоговора()
// 1. Получаем двоичные данные из ХранилищаЗначений
ПеременнаяХранилища = Объект.Ссылка.СканОбразДоговора;
Если ПеременнаяХранилища = Неопределено Тогда
Сообщить("Скан-образ договора отсутствует.");
Возврат;
КонецЕсли;
Попытка
ДвоичныеДанныеФайла = ПеременнаяХранилища.Получить();
Если ДвоичныеДанныеФайла = Неопределено Тогда
Сообщить("Не удалось получить двоичные данные скан-образа.");
Возврат;
КонецЕсли;
// 2. Открываем поток для чтения из двоичных данных
ПотокДляЧтения = ДвоичныеДанныеФайла.ОткрытьПотокДляЧтения();
// 3. Создаем объект ДокументPDF и считываем в него данные из потока
ДокументПДФ = Новый ДокументPDF();
ДокументПДФ.Прочитать(ПотокДляЧтения);
// 4. Отображаем PDF-документ пользователю
ДокументПДФ.Показать();
Исключение
Сообщить("Ошибка при просмотре PDF-документа: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Объект ДокументPDF также позволяет читать файлы непосредственно с диска. Это полезно при использовании внешних утилит, когда выполняется программная конвертация отчетов 1С в графический формат или когда файл предварительно выгружен во временный каталог.
Метод Прочитать() имеет перегрузку, которая принимает в качестве первого параметра полный путь к файлу:
// Пример чтения PDF из файла на диске
&НаКлиенте
Процедура ПоказатьPDFИзФайла()
ИмяФайлаPDF = "C:\МоиДокументы\Договор.pdf";
Если Не ФайлСуществует(ИмяФайлаPDF) Тогда
Сообщить("Файл PDF не найден по указанному пути.");
Возврат;
КонецЕсли;
Попытка
ДокументПДФ = Новый ДокументPDF();
ДокументПДФ.Прочитать(ИмяФайлаPDF);
ДокументПДФ.Показать();
Исключение
Сообщить("Ошибка при просмотре PDF-документа: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
ДокументPDF доступен, начиная с версии платформы 8.3.21. Если же вам нужно работать на более ранних версиях, стоит изучить простое решение для сжатия и обработки PDF для 1С, которое использует внешние библиотеки вроде Poppler.Попытка...Исключение, чтобы корректно обрабатывать возможные ошибки.Прочитать().Теперь, когда мы подробно рассмотрели все аспекты и примеры, вы сможете уверенно работать с просмотром PDF-файлов средствами платформы 1С:Предприятие.