Как программно настроить формирование, сохранение и печать документов в формате PDF из 1С?

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

При автоматизации бизнес-процессов часто возникает задача формирования печатных форм в формате PDF. Это может быть отправка договоров клиентам по электронной почте, выгрузка закрывающих документов для личного кабинета или архивация отчетов. Часто разработчики сталкиваются с дилеммой: исходный макет разработан в формате Microsoft Word (DOC/DOCX), а на выходе требуется получить строго PDF, да еще и объединить несколько разных документов в один файл.

В этой статье мы подробно и по шагам разберем все основные способы решения этой задачи — от простых встроенных механизмов платформы «1С:Предприятие» до продвинутых кроссплатформенных методов конвертации шаблонов Word без использования COM-объектов, которые отлично работают в том числе на серверах под управлением ОС Linux.

Метод 1: Прямое сохранение табличного документа (ТабДок) в PDF

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

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


Процедура СформироватьИСохранитьТабДокВPDF(ДокументСсылка, ПутьДляСохранения)
    
    // Получаем заполненный табличный документ из функции печати вашей конфигурации
    ТабДок = ПолучитьПечатнуюФорму(ДокументСсылка);
    
    // Настраиваем автоматический масштаб, чтобы документ красиво укладывался по ширине страницы
    ТабДок.АвтоМасштаб = Истина;
    
    // Задаем ориентацию страницы (при необходимости)
    ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
    
    // Формируем уникальное имя файла
    ИмяФайла = "Договор_" + СокрЛП(ДокументСсылка.Номер) + ".pdf";
    ПолныйПуть = ПутьДляСохранения + "\" + ИмяФайла;
    
    // Записываем документ в формате PDF
    Попытка
        ТабДок.Записать(ПолныйПуть, ТипФайлаТабличногоДокумента.PDF);
        Сообщить("Документ успешно сохранен: " + ПолныйПуть);
    Исключение
        ЗаписьЖурналаРегистрации("Печать в PDF", УровеньЖурналаРегистрации.Ошибка, , , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        ВызватьИсключение "Не удалось сохранить файл PDF. Обратитесь к администратору.";
    КонецПопытки;
    
КонецПроцедуры

Обратите внимание на важную деталь: начиная с версии платформы 1С 8.3.16, при сохранении табличного документа разработчикам доступен выбор специализированных стандартов долгосрочного хранения PDF/A-2 и PDF/A-3. Это гарантирует, что все шрифты будут внедрены непосредственно в сам файл, и документ отобразится абсолютно идентично на любом компьютере, смартфоне или в веб-браузере.

Метод 2: Конвертация шаблонов MS Word (DOC/DOCX) в PDF через COM-объект

Если бизнес-логика вашей системы завязана на подготовленные пользователями шаблоны Microsoft Word (файлы .doc или .docx), в которые программно подставляются реквизиты, задача усложняется. Нам необходимо сначала заполнить файл Word, а затем перевести его в PDF.

Для операционных систем семейства Windows самым популярным методом является использование COM-соединения с установленным пакетом Microsoft Office. Давайте разберем этот процесс по шагам.

Проанализируем пример кода конвертации заполненного файла Word в PDF с помощью метода SaveAs:


Процедура КонвертироватьDocxВPdfЧерезCOM(ПутьКФайлуDocx, ПутьКФайлуPdf)
    
    Попытка
        // Инициализируем COM-объект MS Word
        MSWord = Новый COMОбъект("Word.Application");
    Исключение
        ВызватьИсключение "На компьютере/сервере не установлен Microsoft Word или отсутствуют права на его запуск.";
    КонецПопытки;
    
    // Скрываем окно приложения, чтобы пользователь не видел процесс конвертации
    MSWord.Visible = Ложь;
    MSWord.DisplayAlerts = 0; // Отключаем предупреждения и диалоговые окна
    
    Попытка
        // Открываем исходный документ DOCX
        Документ = MSWord.Documents.Open(ПутьКФайлуDocx);
        
        // Код формата 17 соответствует константе wdFormatPDF в объектной модели MS Word
        КодФорматаPDF = 17;
        
        // Сохраняем в PDF
        Документ.SaveAs(ПутьКФайлуPdf, КодФорматаPDF);
        
        // Закрываем документ без сохранения изменений в оригинальном docx
        Документ.Close(0); 
    Исключение
        // Обязательно корректно закрываем процесс Word в случае непредвиденной ошибки
        MSWord.Quit();
        ЗаписьЖурналаРегистрации("Конвертация DOCX в PDF", УровеньЖурналаРегистрации.Ошибка, , , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        ВызватьИсключение "Ошибка конвертации документа через MS Word.";
    КонецПопытки;
    
    // Завершаем работу с приложением Word
    MSWord.Quit();
    
КонецПроцедуры

Важное предупреждение для серверных решений: Использование COM-объектов MS Office (технология DCOM) крайне не рекомендуется компанией Microsoft для использования в фоновых заданиях, веб-сервисах и на стороне сервера 1С. Сессия пользователя winword.exe может зависнуть в памяти из-за скрытого диалогового окна (например, сообщения о проверке орфографии или активации лицензии), что приведет к утечке ресурсов и блокировке работы сервера.

Метод 3: Кроссплатформенная конвертация с помощью LibreOffice (Linux и Windows)

Если серверная часть вашей системы 1С работает под управлением операционной системы Linux или вы хотите отказаться от использования проприетарного MS Office на сервере Windows, идеальным решением станет использование бесплатного пакета LibreOffice.

Мы можем запустить LibreOffice в так называемом «безголовом» режиме (headless), передав ему параметры конвертации через командную строку. Для этого используется стандартный метод 1С ЗапуститьПриложение().

Рассмотрим, как выглядит этот кроссплатформенный вызов:


Процедура КонвертироватьЧерезLibreOffice(ПутьКФайлуDocx, КаталогНазначения)
    
    // Для Windows путь обычно выглядит так: "C:\Program Files\LibreOffice\program\soffice.exe"
    // Для Linux достаточно вызвать системную команду: "libreoffice"
    
    ИмяПриложения = ?(ПолучитьСистемнуюИнформацию().ТипПлатформы = ТипПлатформы.Windows_x86 
                      Или ПолучитьСистемнуюИнформацию().ТипПлатформы = ТипПлатформы.Windows_x86_64,
                      """C:\Program Files\LibreOffice\program\soffice.exe""", 
                      "libreoffice");
                      
    // Формируем параметры запуска для конвертации без графического интерфейса
    ПараметрыЗапуска = " --headless --convert-to pdf """ + ПутьКФайлуDocx + """ --outdir """ + КаталогНазначения + """";
    
    // Запускаем процесс в синхронном режиме (третий параметр = Истина), ожидания завершения конвертации
    Попытка
        ЗапуститьПриложение(ИмяПриложения + ПараметрыЗапуска, , Истина);
    Исключение
        ЗаписьЖурналаРегистрации("LibreOffice Конвертер", УровеньЖурналаРегистрации.Ошибка, , , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        ВызватьИсключение "Не удалось запустить конвертер LibreOffice. Проверьте правильность путей и права доступа.";
    КонецПопытки;
    
КонецПроцедуры

Этот способ отличается высочайшей стабильностью, производительностью и полной независимостью от лицензирования продуктов Microsoft.

Метод 4: Объединение нескольких печатных форм в один PDF-файл

В практике часто встречается ситуация, когда пользователю требуется распечатать комплект из нескольких документов (например: Договор, Счет, Акт и Спецификация). Если выводить их на печать по отдельности, откроется несколько окон или сформируется несколько файлов. Рассмотрим, как объединить их в один общий файл PDF.

Вариант А: Объединение табличных документов через встроенный пакет 1С

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

Разберем по шагам практический пример реализации:


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

Вариант Б: Внешнее объединение готовых PDF-файлов

Если файлы PDF уже сформированы из сторонних источников (например, сконвертированы из Word) и лежат на диске, объединить их средствами самой 1С напрямую не получится. В этом случае мы рекомендуем использовать консольные утилиты, такие как pdftk (PDF Toolkit) или Ghostscript.

Пример вызова утилиты pdftk из кода 1С для склеивания файлов:


Процедура СклеитьВнешниеPdfФайлы(МассивПутейКФайлам, ВыходнойФайл)
    
    // Формируем список файлов для передачи утилите
    СписокФайлов = "";
    Для Каждого ПутьКФайлу Из МассивПутейКФайлам Цикл
        СписокФайлов = СписокФайлов + """" + ПутьКФайлу + """ ";
    КонецЦикла;
    
    // Шаблон команды: pdftk файл1.pdf файл2.pdf cat output результат.pdf
    КомандаЗапуска = "pdftk " + СписокФайлов + "cat output """ + ВыходнойФайл + """";
    
    Попытка
        ЗапуститьПриложение(КомандаЗапуска, , Истина);
    Исключение
        ВызватьИсключение "Ошибка объединения PDF через pdftk: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
    КонецПопытки;
    
КонецПроцедуры

Метод 5: Использование виртуальных PDF-принтеров (Bullzip, PDFCreator)

Бывают ситуации, когда архитектура конфигурации 1С устарела или закрыта для редактирования кода формирования печатных форм, но при этом требуется автоматический вывод документов в PDF-файлы. В таких случаях на помощь приходят виртуальные принтеры, например, Bullzip PDF Printer или PDFCreator.

Эти программы устанавливаются в операционной системе Windows как обычные принтеры, но вместо физического вывода на бумагу они генерируют PDF-файл. Настройка выполняется следующим образом:

  1. В операционной системе устанавливается виртуальный принтер (например, Bullzip PDF Printer).
  2. В настройках принтера задается режим автоматического сохранения файлов без отображения диалоговых окон (режим «Auto-save»). Путь сохранения и маску имени файла можно настроить статически или динамически передавать через INI-файлы конфигурации принтера.
  3. Из кода 1С при выводе на печать мы принудительно задаем имя принтера.

Рассмотрим, как направить печатную форму на определенный виртуальный принтер из 1С:


Процедура НаправитьПечатьНаВиртуальныйПринтер(ТабДок)
    
    // Задаем имя принтера ровно так, как оно зарегистрировано в системе
    ТабДок.ИмяПринтера = "Bullzip PDF Printer";
    
    // Отправляем на печать без вывода диалога выбора принтера пользователю
    ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
    
КонецПроцедуры

Этот метод является отличным «обходным» решением в сложных инфраструктурных проектах, где отсутствует прямая возможность программного переопределения логики выгрузки документов.

Интерактивный просмотр документов PDF внутри 1С

Начиная с версии платформы 1С 8.3.22, разработчикам больше не требуется устанавливать на рабочие станции пользователей сторонний софт (Adobe Acrobat Reader или Foxit Reader) для визуализации PDF-файлов. В платформе появился встроенный объект просмотра.

Вы можете открыть сформированный PDF-файл прямо во встроенном окне просмотра 1С следующим образом:


Процедура ПоказатьPdfФайлПользователю(ПутьКФайлу)
    
    Попытка
        // Создаем встроенный объект PDF-документа
        ДокументPDF = Новый ДокументPDF;
        ДокументPDF.Прочитать(ПутьКФайлу);
        
        // Открываем интерактивное окно просмотра в интерфейсе платформы
        ДокументPDF.Показать();
    Исключение
        ВызватьИсключение "Не удалось прочитать или отобразить файл PDF.";
    КонецПопытки;
    
КонецПроцедуры

Этот инструмент предоставляет пользователям удобный интерфейс с возможностью масштабирования, поворота страниц, поиска текста и прямой печати на физический принтер.

Резюме и рекомендации по выбору решения

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

← На главную