В процессе разработки часто возникает задача отправить документ на печать напрямую с сервера. Это особенно актуально при работе с HTTP-сервисами, мобильными приложениями или фоновыми заданиями, где нет клиентского контекста и возможности вызвать стандартный метод ТабличныйДокумент.Напечатать(). Рассмотрим подробно, как обойти это ограничение, какие инструменты использовать и с какими трудностями прав доступа придется столкнуться.
Начиная с современных версий платформы 8.3, в 1С появился механизм, позволяющий формировать очередь печати на стороне сервера без использования внешних библиотек. Основным инструментом здесь выступает объект ПакетОтображаемыхДокументов. Проанализируем пример кода, который позволяет отправить ТабличныйДокумент на конкретный принтер:
Пакет = Новый ПакетОтображаемыхДокументов;
Пакет.КоличествоЭкземпляров = 1;
ЭлементПакета = Пакет.Состав.Добавить();
ЭлементПакета.Данные = ПоместитьВоВременноеХранилище(ТабДокумент);
ЭлементПакета.Наименование = "ПечатнаяФорма_Накладная";
Пакет.ИмяПринтера = "\\ServerPrint\Kyocera_M2540dn";
Пакет.Заголовок = "Задание на печать из 1С";
// Метод Напечатать() на сервере отправит задание в системную очередь печати
Пакет.Напечатать();
Важное условие: Для успешной работы этого метода принтер должен быть установлен непосредственно на сервере 1С. При этом имя принтера в коде должно в точности совпадать с тем, как оно отображается в панели управления сервером. Если принтер сетевой, рекомендуется подключать его через локальный порт (Local Port) для обеспечения стабильности работы системной службы usr1cv8.
Если штатные средства платформы по какой-то причине не подходят, рассмотрим классический способ: сохранение документа в формат PDF и последующий вызов внешней программы для его печати в «невидимом» режиме. Чаще всего для этих целей используют Adobe Acrobat Reader.
Разберем по шагам реализацию этого метода. Сначала необходимо подготовить файл и определить путь к исполняемому файлу программы через реестр Windows:
ВремФайл = ПолучитьИмяВременногоФайла("pdf");
ТабДокумент.Записать(ВремФайл, ТипФайлаТабличногоДокумента.PDF);
WshShell = Новый COMОбъект("WScript.Shell");
Попытка
ПутьAdobeReader = WshShell.RegRead("HKCR\Software\Adobe\Acrobat\Exe\");
Исключение
Сообщить("Программа Adobe Reader не найдена в системе!");
Возврат;
КонецПопытки;
После получения пути к программе, необходимо сформировать строку запуска с правильными ключами. Для Adobe Reader это ключи /N (новый экземпляр), /T (печать на принтер и завершение), /s (скрыть заставку), /h (скрытое окно). Проанализируем структуру команды:
// Удаляем лишние кавычки, если они есть в пути из реестра
ПутьAdobeReader = СтрЗаменить(ПутьAdobeReader, """", "");
ИмяПринтера = "\\192.168.1.52\Printer_Labels";
// Формируем команду запуска
КомандаЗапуска = """" + ПутьAdobeReader + """ /N /T /s /h """ + ВремФайл + """ """ + ИмяПринтера + """";
// Запускаем приложение на сервере
ЗапуститьПриложение(КомандаЗапуска, , Истина); // Истина - ждать завершения
Существует альтернативный способ взаимодействия с Adobe Acrobat через COM-соединение. Это позволяет более тонко управлять процессом, не прибегая к формированию командных строк. Посмотрим на пример реализации:
Попытка
Acrobat = Новый COMОбъект("AcroPDF.PDF.1");
Acrobat.Visible = Ложь;
Если Acrobat.LoadFile(ПутьКФайлуPDF) Тогда
Acrobat.PrintAll(); // Отправка всех страниц на принтер по умолчанию
КонецЕсли;
Исключение
// Обработка ошибки инициализации COM
КонецПопытки;
Однако стоит помнить, что работа с COM-объектами на стороне сервера 1С часто сопряжена с утечками памяти, поэтому после выполнения операции объект необходимо принудительно обнулять.
Это самый частый вопрос при настройке серверной печати. Проанализируем основные причины:
rphost) работает в системной сессии, которая не имеет доступа к графическому интерфейсу и рабочему столу пользователя. Любые всплывающие окна «Сохранить как» или «Принять лицензионное соглашение» от Adobe Reader заблокируют процесс навсегда, так как их некому нажать.usr1cv8 и установить принтеры для него.\\Server\Printer, убедитесь, что у системной службы есть права доступа к этой шаре. Часто проще создать Local Port в настройках принтера и прописать туда UNC-путь.Для высоконагруженных систем (циклическая печать множества документов) использование Adobe Reader не является оптимальным из-за его «тяжеловесности». Проанализируем более профессиональные подходы:
1. Использование SumatraPDF: Это очень легкий просмотрщик PDF, который идеально подходит для командной строки. Он корректно завершает процессы и не требует сложной настройки. Команда будет выглядеть максимально просто: sumatrapdf.exe -print-to "ИмяПринтера" файл.pdf.
2. Использование PDFtoPrinter: Крошечная утилита, созданная специально для одной задачи — отправить PDF на принтер из консоли. Она лишена проблем с графическими окнами.
3. Логирование ошибок: Чтобы выяснить причину, по которой ЗапуститьПриложение не отрабатывает, перенаправьте поток вывода в текстовый файл. Это поможет увидеть системные сообщения об ошибках:
КомандаСЛогами = "cmd /c """ + КомандаЗапуска + " > C:\temp\print_log.txt 2>&1""";
ЗапуститьПриложение(КомандаСЛогами);
В завершение отметим, что наиболее стабильным решением для сервера 1С под Windows является использование SumatraPDF или штатного ПакетОтображаемыхДокументов при условии правильной настройки прав системного пользователя 1С на принтеры.