В практической работе часто возникает задача массовой отправки на печать пакетов документов, прикрепленных к учетным объектам 1С: счетов, актов, накладных, сканов договоров и сертификатов. Файлы хранятся в базе в виде двоичных данных (в реквизитах типа ХранилищеЗначения или регистрах сведений) и могут иметь самые разные форматы: PDF, DOCX, XLSX, JPG, PNG и другие. Рассмотрим, как правильно организовать пакетную печать таких документов, обойти ограничения платформы и настроить взаимодействие с операционной системой.
Разберем типичное заблуждение относительно объекта платформы ПакетОтображаемыхДокументов. Данный объект появился в платформе 1С:Предприятие начиная с версии 8.3.10 и предназначен для объединения нескольких внутренних документов системы (табличных документов ТабличныйДокумент или текстовых документов) в одно печатное задание. Отправить через него на печать внешний файл PDF, Word или растровое изображение напрямую нельзя, так как объект работает исключительно с внутренними типами платформы.
Для печати произвольных файлов требуется предварительно выгрузить двоичные данные во временный файл на клиенте и передать задачу операционной системе или внешним приложениям.
Проанализируем первый шаг: перед отправкой любого файла на печать необходимо сохранить его из хранилища на диск. Рекомендуется использовать методы ПолучитьИмяВременногоФайла() и Записать() объекта ДвоичныеДанные.
Если расширение файла неизвестно, его можно определить по сигнатуре («магическим байтам») в начале двоичных данных. Например, файлы формата PNG всегда начинаются с последовательности байтов ‰PNG, PDF — с %PDF, а документы MS Office (форматов DOCX/XLSX) представляют собой ZIP-архивы с сигнатурой PK.
// Пример сохранения данных во временный файл
ДвоичныеДанныеФайла = ХранилищеФайла.Получить();
ВременныйПуть = ПолучитьИмяВременногоФайла(РасширениеФайла);
ДвоичныеДанныеФайла.Записать(ВременныйПуть);
Рассмотрим наиболее универсальный способ, не требующий явного запуска отдельных офисных приложений для каждого типа файла. В операционной системе Windows для зарегистрированных типов файлов определено системное действие print. Вызвать его можно через интерфейс проводника:
Шелл = Новый COMОбъект("Shell.Application");
ФайловаяСистема = Новый Файл(ВременныйПуть);
Каталог = Шелл.Namespace(ФайловаяСистема.Путь);
ФайлДляПечати = Каталог.ParseName(ФайловаяСистема.Имя);
// Выполняем команду печати по умолчанию
ФайлДляПечати.InvokeVerb("print");
Посмотрим на особенности этого метода: он использует приложение, назначенное в Windows по умолчанию для каждого конкретного расширения, и отправляет файл на принтер по умолчанию без открытия диалоговых окон.
Если требуется контролировать параметры печати документов Word или таблиц Excel (например, выбирать принтер, количество копий или масштаб), целесообразно использовать прямое обращение к COM-объектам соответствующих приложений:
// Печать документа Microsoft Word
Ворд = Новый COMОбъект("Word.Application");
Ворд.Visible = Ложь;
Документ = Ворд.Documents.Open(ВременныйПуть);
Документ.PrintOut();
Документ.Close(0); // Закрыть без сохранения изменений
Ворд.Quit();
// Печать документа Microsoft Excel
Эксель = Новый COMОбъект("Excel.Application");
Эксель.Visible = Ложь;
Книга = Эксель.Workbooks.Open(ВременныйПуть);
Книга.PrintOut();
Книга.Close(Ложь);
Эксель.Quit();
Для файлов PDF и графических изображений использование тяжелых COM-объектов часто приводит к зависанию фоновых процессов. Разберем эффективные консольные альтернативы:
Команда = СтрШаблон("rundll32.exe shimgvw.dll,ImageView_PrintTo /pt ""%1"" ""%2""", ПутьКФайлу, ИмяПринтера);
ЗапуститьПриложение(Команда, , Истина);
-print-to "ИмяПринтера" -silent).
КомандаPS = СтрШаблон("powershell -Command ""Start-Process -FilePath '%1' -Verb Print -PassThru | Wait-Process""", ПутьКФайлу);
ЗапуститьПриложение(КомандаPS, , Истина);
Выясним основные причины сбоев при групповой печати сотен файлов подряд: