В современных конфигурациях 1С, таких как «Комплексная автоматизация 2» или «ERP Управление предприятием», пользователи часто прикрепляют к документам (например, к «Заказу клиента») внешние файлы: сертификаты, спецификации или инструкции в формате PDF. Типовой функционал позволяет открывать их вручную, но когда возникает задача напечатать сразу весь пакет документов (счет, накладную и прикрепленные файлы) одной кнопкой, разработчик сталкивается с рядом технических сложностей. В этой статье мы подробно разберем, как интегрировать печать PDF-файлов в стандартный механизм «Печать комплекта».
Основная сложность заключается в том, что объект 1С ТабличныйДокумент не умеет напрямую отображать или печатать содержимое PDF-файлов с сохранением их верстки. Стандартные кнопки «Печать» и «Печать комплекта» работают именно с табличными документами. Следовательно, нам необходимо:
Рассмотрим пошагово реализацию этой задачи.
Поскольку файлы хранятся в базе данных или в томах на сервере, а печать инициируется на стороне пользователя, первым делом нам нужно получить двоичные данные файла и передать их на клиент. Проанализируем типичный алгоритм получения присоединенных файлов через подсистему «Работа с файлами» БСП.
На сервере мы находим файлы, связанные с владельцем (нашим документом), и помещаем их во временное хранилище или передаем как структуру двоичных данных.
// Функция получения списка двоичных данных PDF-файлов
Функция ПолучитьДанныеФайловЗаказа(СсылкаНаДокумент) Экспорт
МассивДанных = Новый Массив;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗаказКлиентаПрисоединенныеФайлы.Ссылка КАК ФайлСсылка
|ИЗ
| Справочник.ЗаказКлиентаПрисоединенныеФайлы КАК ЗаказКлиентаПрисоединенныеФайлы
|ГДЕ
| ЗаказКлиентаПрисоединенныеФайлы.ВладелецФайла = &Владелец
| И ЗаказКлиентаПрисоединенныеФайлы.Расширение = ""pdf""
| И НЕ ЗаказКлиентаПрисоединенныеФайлы.ПометкаУдаления";
Запрос.УстановитьПараметр("Владелец", СсылкаНаДокумент);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ДанныеФайла = РаботаСФайлами.ДвоичныеДанныеФайла(Выборка.ФайлСсылка);
МассивДанных.Добавить(ДанныеФайла);
КонецЦикла;
Возврат МассивДанных;
КонецФункции
Для печати PDF без участия пользователя (без открытия окна Acrobat Reader) лучше всего использовать утилиту SumatraPDF. Это легкое и бесплатное решение, которое поддерживает управление через командную строку. Разберем способ, при котором исполняемый файл утилиты хранится прямо в макете конфигурации (как двоичные данные).
Алгоритм на стороне клиента выглядит следующим образом:
SumatraPDF.exe из макета во временный каталог.
Процедура НапечататьPDFНаКлиенте(ДанныеФайла)
ИмяФайлаPDF = ПолучитьИмяВременногоФайла("pdf");
ДанныеФайла.Записать(ИмяФайлаPDF);
// Путь к исполняемому файлу SumatraPDF (предположим, он уже выгружен)
ПутьКПрограмме = КаталогВременныхФайлов() + "SumatraPDF.exe";
// Параметры: -print-to-default (печать на принтер по умолчанию)
// -exit-when-done (закрыть программу после отправки в очередь)
ПараметрыЗапуска = СтрШаблон("-print-to-default -exit-when-done ""%1""", ИмяФайлаPDF);
ЗапуститьПриложение(ПутьКПрограмме + " " + ПараметрыЗапуска, , Истина);
// Удаляем временный PDF файл после печати
Попытка
УдалитьФайлы(ИмяФайлаPDF);
Исключение
// Файл может быть занят процессом печати, можно обработать позже
КонецПопытки;
КонецПроцедуры
Чтобы наш пункт появился в форме «Печать комплекта документов», необходимо использовать механизм расширения для подсистемы «Управление печатью». Выясним, какие процедуры нужно переопределить.
В модуле менеджера документа (или через расширение в подписке на событие) необходимо добавить команду печати в процедуру ДобавитьКомандыПечати. Однако для «Комплекта» важно, чтобы система знала, что это именно комплектная составляющая.
Проанализируем ситуацию: в форме настройки комплекта список формируется на основании доступных команд печати объекта. Нам нужно добавить виртуальную команду, которая будет обрабатываться особым образом.
// В расширении модуля менеджера Заказа клиента
Процедура ДобавитьКомандыПечати(КомандыПечати) Экспорт
// Стандартные команды...
// Добавляем нашу команду для PDF
КомандаПечати = КомандыПечати.Добавить();
КомандаПечати.Идентификатор = "ПечатьПрисоединенныхФайловPDF";
КомандаПечати.Представление = НСтр("ru = 'Присоединенные файлы (PDF)'");
КомандаПечати.ПроверкаПроведенияПередПечатью = Ложь;
КомандаПечати.Порядок = 100; // Устанавливаем в конец списка
КонецПроцедуры
Когда пользователь нажимает «Печать» в форме комплекта, система вызывает обработчик. Если выбран наш идентификатор ПечатьПрисоединенныхФайловPDF, мы не должны возвращать ТабличныйДокумент. Вместо этого мы вызываем процедуру печати внешних файлов.
Важный нюанс: если мы печатаем «комплект», 1С собирает коллекцию печатных форм. Поскольку PDF — это не табличный документ, нам придется вмешаться в процесс формирования пакета на клиенте. В модуле формы печати (которую можно расширить) при выполнении команды «Печать» для нашего специфического идентификатора нужно запустить цикл по файлам, как описано в Шаге 2.
Рассмотрим альтернативный вариант: если мы хотим, чтобы PDF печатался в строгой последовательности с другими документами комплекта, можно воспользоваться объединением всех документов в один PDF на сервере (используя библиотеки типа PDFSharp через COM или .Net), а затем выводить этот единый файл на печать.
При реализации данного функционала следует учитывать среду исполнения:
SumatraPDF или Windows ShellExecute (глагол "print") работает идеально..exe файлов следует использовать системную команду lpr. Команда запуска будет выглядеть примерно так: lpr -P [ИмяПринтера] [ПутьКФайлу].Для успешной реализации печати прикрепленных файлов в «1С:Комплексная автоматизация» мы рекомендуем придерживаться следующего плана: использовать SumatraPDF для Windows-клиентов как наиболее стабильный способ «тихой» печати, внедрять команду печати через механизм БСП ДобавитьКомандыПечати и обеспечивать временное хранение файлов на стороне клиента перед отправкой в очередь принтера. Это позволит сделать работу пользователя бесшовной, а процесс формирования комплекта документов — по-настоящему полным.