Как реализовать пакетную печать PDF-файлов из 1С:Предприятие?

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

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

Способ 1: Использование Adobe Reader через командную строку (COM-объект WScript.Shell)

Этот метод считается одним из самых доступных, так как Adobe Reader установлен на большинстве рабочих станций. Разберем ситуацию, когда нам необходимо отправить список файлов на конкретный принтер в фоновом режиме. Основная сложность здесь заключается в том, что Adobe Reader после печати часто остается открытым в процессах Windows, поэтому нам придется программно отслеживать завершение задания и закрывать приложение.

Проанализируем программный код, который позволяет автоматизировать этот процесс. Сначала мы определим путь к исполняемому файлу Adobe Reader через реестр Windows, затем отправим файлы на печать и проконтролируем очередь печати через WMI (Windows Management Instrumentation).


// Процедура выполняет попытку напечатать pdf-файлы из списка в фоновом режиме
Процедура ФоноваяПечатьPDFФайлов(МассивФайлов, ИмяПринтера = "") Экспорт
    
    WshShell = Новый COMОбъект("WScript.Shell");
    // Пытаемся найти путь к Adobe Reader в реестре
    Попытка
        ПутьAdobeReader = WshShell.RegRead("HKCR\Software\Adobe\Acrobat\Exe\");
    Исключение
        Сообщить("Программа Adobe Reader не найдена!", СтатусСообщения.Важное);
        Возврат;
    КонецПопытки;
    
    // Подключаемся к службе управления заданиями печати
    oLocator = Новый COMОбъект("WbemScripting.SWbemLocator");
    oService = oLocator.ConnectServer("", "", "", ""); 
    oService.Security_.impersonationlevel = 3; 
    oService.Security_.Privileges.AddAsString("SeLoadDriverPrivilege");
        
    Для каждого Файл Из МассивФайлов Цикл
        // Формируем команду: /N - новый экземпляр, /T - печать на принтер
        Команда = ПутьAdobeReader + " /N /T " + """" + Файл.ПолноеИмя + """" + ?(ЗначениеЗаполнено(ИмяПринтера), " " + """" + ИмяПринтера + """", "");
        WshShell.Run(Команда, 0); 
        
        // Мониторим добавление задания в очередь (ждем до 15 секунд)
        ЗаданиеДобавлено = Ложь;
        ТекущееВремя = ТекущаяДата();
        Пока Не ЗаданиеДобавлено И ТекущаяДата() < ТекущееВремя + 15 Цикл 
            ОбработкаПрерыванияПользователя();
            Для каждого ЗаданиеПечати Из oService.InstancesOf("Win32_PrintJob") Цикл
                ЗаданиеДобавлено = (ЗаданиеПечати.Document = Файл.Имя);
            КонецЦикла;     
        КонецЦикла;
    КонецЦикла; 
    
    // Ожидаем, пока очередь печати полностью очистится
    Пока (oService.InstancesOf("Win32_PrintJob").Count > 0) Цикл
        // Можно добавить ограничение по времени
    КонецЦикла;
    
    // Завершаем процесс Adobe Reader, чтобы он не висел в памяти
    ИмяПроцесса = "AcroRd32.exe"; // Или динамически извлечь из ПутьAdobeReader
    WshShell.Run("taskkill /f /im " + ИмяПроцесса, 0);
    
КонецПроцедуры

Важный момент: использование taskkill — это "жесткий" метод. В многопользовательской среде терминального сервера это может закрыть приложения у других пользователей, если не фильтровать процессы по ID или владельцу.

Способ 2: Использование объектной модели Adobe Acrobat Pro

Если на компьютере установлен Adobe Acrobat Professional, мы можем воспользоваться более элегантным способом — через специализированный COM-объект AcroExch. Это позволяет управлять параметрами печати напрямую, без использования командной строки.

Выясним, какие преимущества дает этот подход. Мы можем настроить "тихую" печать (silent mode), выбрать конкретный лоток принтера и масштабирование страницы. Рассмотрим пример кода:


Процедура ПечатьЧерезAcrobatPro(ПутьКФайлу, ИмяПринтера)
    Попытка
        App = Новый COMОбъект("AcroExch.App");
        PDDoc = Новый COMОбъект("AcroExch.PDDoc");
    Исключение
        Сообщить("Adobe Acrobat Pro не установлен");
        Возврат;
    КонецПопытки;
    
    App.Hide(); // Скрываем окно приложения
    Если PDDoc.Open(ПутьКФайлу) Тогда
        JSO = PDDoc.GetJSObject();
        PrintParams = JSO.GetPrintParams();
        
        // Настраиваем параметры: печать без диалогов
        PrintParams.interactive = PrintParams.constants.interactionLevel.silent;
        PrintParams.printerName = ИмяПринтера;
        
        // Установка масштабирования "По размеру области печати"
        PrintParams.pageHandling = PrintParams.constants.handling.shrink;
        
        JSO.print(PrintParams); // Отправка на печать
        
        PDDoc.Close();
    КонецЕсли;
    
    App.Exit();
    App = Неопределено;
КонецПроцедуры

Способ 3: Использование SumatraPDF (рекомендуемый "легкий" способ)

Рассмотрим альтернативу тяжелым продуктам Adobe. Программа SumatraPDF — это бесплатный и компактный просмотрщик, который идеально подходит для пакетной печати через командную строку. Она не требует установки (может работать как portable-версия) и корректно завершает работу после выполнения команды.

Алгоритм действий будет следующим:

  1. Размещаем SumatraPDF.exe в каталоге исполняемых файлов 1С или в общих ресурсах.
  2. Вызываем печать через метод ЗапуститьПриложение().

// Пример вызова SumatraPDF
ПутьКПрограмме = "C:\Utils\SumatraPDF.exe";
ПараметрыЗапуска = "-print-to """ + ИмяПринтера + """ -silent """ + ПолноеИмяФайла + """";
ЗапуститьПриложение(ПутьКПрограмме + " " + ПараметрыЗапуска, , Истина); // Истина - ждать завершения

Преимущества SumatraPDF: высокая скорость, отсутствие лишних процессов в памяти и стабильная работа с современными принтерами.

Способ 4: Современные возможности платформы (движок Chromium)

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

Разберем, как это работает. Мы можем загрузить файл в невидимое поле HTML и вызвать стандартную команду печати браузера. Однако стоит учитывать, что "тихая" печать без вывода окна выбора принтера в данном случае может потребовать специфических настроек операционной системы или ключей запуска платформы.

Способ 5: Объединение файлов перед печатью (объект PDFДокумент)

В последних релизах платформы (начиная с 8.3.16) появились мощные средства для работы с PDF — объект PDFДокумент. Если у вас 100 отдельных файлов, отправка их по одному может привести к тому, что документы разных пользователей перемешаются в лотке принтера.

Посмотрим на стратегию решения: объединяем все нужные PDF в один временный файл и печатаем его одним заданием.


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

Резюме и рекомендации

Выясним, какой метод выбрать в зависимости от условий:

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

← На главную