При работе в конфигурации 1С:Бухгалтерия 3.0 (и других современных решениях на управляемых формах) разработчики часто сталкиваются с необходимостью печати договоров контрагентов. В отличие от стандартных печатных форм, которые строятся на базе табличных документов, договоры обычно хранятся и редактируются в виде объектов типа ФорматированныйДокумент. Этот объект работает с разметкой HTML.
Основная сложность заключается в том, что у объекта ФорматированныйДокумент и у элемента формы ПолеHTMLДокумента полностью отсутствуют привычные программные свойства для настройки параметров страницы — такие как ПолеСлева, ПолеСправа, ОриентацияСтраницы или АвтоМасштаб. Попытки настроить поля через стандартный диалог «Параметры страницы» в режиме предприятия часто не дают стабильного результата, так как эти настройки могут сбрасываться при смене принтера или перезапуске сеанса.
В этой статье мы подробно разберем, как обойти это ограничение платформы и гарантированно установить нужные поля печати программным путем.
Для вывода на печать обычных документов (например, накладных или актов) используется ТабличныйДокумент. Платформа 1С предоставляет для него полноценный программный интерфейс управления печатью. Мы можем легко написать следующий код:
ТабДок = Новый ТабличныйДокумент;
ТабДок.ПолеСлева = 20; // Поле в миллиметрах
ТабДок.ПолеСправа = 10;
ТабДок.ПолеСверху = 15;
ТабДок.ПолеСнизу = 15;
Однако для объектов типа ФорматированныйДокумент этот механизм неприменим. Под капотом такого документа находится обычный HTML-код. Печать HTML выполняется встроенным в платформу браузерным движком. Начиная с версии платформы 1С 8.3.14, вместо устаревшего Internet Explorer используется современный движок WebKit. Именно особенности работы WebKit мы и будем использовать для решения нашей задачи.
Поскольку печатная форма представляет собой HTML-страницу, мы можем управлять параметрами печатного листа напрямую через каскадные таблицы стилей (CSS). Самым надежным и стандартизированным способом в движках на базе WebKit является использование специальной CSS-директивы @page.
Директива @page позволяет жестко задать физический размер бумаги и размеры всех полей (отступов) печатного листа. Рассмотрим пример CSS-кода, который необходимо внедрить в структуру нашего HTML-документа:
@page {
size: A4; /* Задаем формат листа */
margin-left: 20mm; /* Левое поле под подшивку */
margin-right: 10mm; /* Правое поле */
margin-top: 15mm; /* Верхнее поле */
margin-bottom: 15mm;/* Нижнее поле */
}
Разберем, как программно внедрить этот стиль в текст договора перед его выводом на печать. Нам нужно получить HTML-текст из форматированного документа, найти тег <head> и вставить туда наш блок стилей:
// Получаем HTML-код из форматированного документа договора
ТекстHTML = "";
ДоговорОбъект = Справочники.ДоговорыКонтрагентов.СоздатьЭлемент(); // Пример получения объекта
// Допустим, ФорматированныйДокумент получен из макета или реквизита
ФорматированныйДокумент.ПолучитьHTML(ТекстHTML, Новый Структура);
// Формируем строковую переменную со стилями
СтрокаСтилей = "
|<style>
|@page {
| size: A4;
| margin-left: 20mm;
| margin-right: 10mm;
| margin-top: 15mm;
| margin-bottom: 15mm;
|}
|</style>";
// Встраиваем стили в секцию заголовка HTML
Если Найти(ТекстHTML, "<head>") > 0 Тогда
ТекстHTML = СтрЗаменить(ТекстHTML, "<head>", "<head>" + СтрокаСтилей);
Иначе
// Если тег head отсутствует, добавляем стили в самое начало документа
ТекстHTML = СтрокаСтилей + ТекстHTML;
КонецЕсли;
// Записываем измененный HTML обратно в документ
ФорматированныйДокумент.УстановитьHTML(ТекстHTML, Новый Структура);
При таком подходе движок печати WebKit автоматически применит указанные миллиметровые отступы, игнорируя настройки по умолчанию в локальном принтере пользователя. Это решает проблему на любых компьютерах, даже там, где физический принтер вообще не установлен.
Если по каким-то причинам использование директивы @page не дает нужного результата (например, в старых релизах платформы), можно использовать альтернативный вариант управления стилями отображения при печати с помощью медиа-запроса @media print. Этот запрос сообщает рендереру, что правила внутри него нужно применять только в момент вывода документа на печать или в режиме предварительного просмотра.
Проанализируем пример внедрения стилей для тела документа body внутри медиа-запроса:
@media print {
body {
margin-left: 2cm; /* Отступ слева для печатной версии */
margin-right: 1cm; /* Отступ справа */
margin-top: 1.5cm; /* Отступ сверху */
margin-bottom: 1.5cm;/* Отступ снизу */
line-height: 1.2; /* Настройка межстрочного интервала */
font-size: 11pt; /* Жестко задаем размер шрифта для печати */
}
}
Важное примечание: При использовании этого метода физические границы страницы все еще могут определяться настройками принтера по умолчанию, но внутренний контент документа (содержимое тега body) будет смещен на величину указанных отступов. Результат применения стилей @media print можно увидеть только в режиме предварительного просмотра печати.
Стоит отметить развитие самой платформы 1С. В более ранних релизах (включая платформу 8.3.16, упомянутую в исходном обсуждении) существовала техническая проблема: параметры страницы, измененные пользователем вручную в окне предпросмотра HTML-документа, сбрасывались при закрытии формы и не сохранялись.
Начиная с версий 8.3.20, разработчики 1С доработали этот функционал:
Если специфика верстки договора очень сложная (например, требуются сложные таблицы с двухколоночным выводом реквизитов сторон на последней странице, точные колонтитулы с номерами страниц), программисты используют альтернативные архитектурные решения:
Рассмотрим пример реализации выгрузки во временный файл:
// Создаем уникальное имя для временного файла с расширением html
ПутьКФайлу = ПолучитьИмяВременногоФайла("html");
// Записываем HTML-код договора во временный файл
ТекстовыйДокумент = Новый ТекстовыйЗапись(ПутьКФайлу, КодировкаТекста.UTF8);
ТекстовыйДокумент.Записать(ТекстHTML);
ТекстовыйДокумент.Закрыть();
// Открываем файл в браузере по умолчанию для последующей печати
ЗапуститьПриложение(ПутьКФайлу);
Этот способ позволяет пользователю распечатать договор средствами привычного браузера (Google Chrome, Яндекс.Браузер, Mozilla Firefox), где управление полями, масштабированием и предварительный просмотр работают максимально стабильно и предсказуемо.
Подводя итог, можно сделать вывод: если вам необходимо программно управлять полями печати HTML-документов внутри интерфейса 1С без выгрузки во внешние приложения, лучшим техническим решением является внедрение CSS-директивы @page непосредственно в код заголовка HTML-шаблона.