Как формировать и показывать HTML-разметку в 1С 8.3
Содержание
HTML в 1С работает через три механизма: реквизит формы с видом «Поле HTML-документа» показывает разметку пользователю, встроенный язык собирает её как обычную строку, а табличный документ умеет сохраняться в HTML методом Записать() с типом ТипФайлаТабличногоДокумента.HTML5. Всё остальное — шаблоны, стили, печать, XSLT — надстройки над этими тремя вещами.
Разметку правят в конфигураторе как текст макета или прямо в модуле. Отдельного визуального редактора HTML-отчётов в платформе нет, поэтому сложные отчёты удобнее сначала сверстать в обычном редакторе, а потом перенести в макет.
Где HTML реально нужен в 1С
HTML — не замена табличному документу и СКД. Он выигрывает там, где нужна свободная вёрстка, ссылки и интерактив.
Типовые сценарии:
- 📊 Информационные панели на начальной странице: карточки с цифрами, цветные индикаторы, мини-графики на CSS.
- 📄 Справки и инструкции внутри формы: текст с заголовками, списками и ссылками.
- 🔗 Интерактивные отчёты: клик по строке открывает документ 1С через обработчик нажатия.
- 📧 Письма: тело HTML-письма для рассылки счетов и уведомлений.
- 🌐 HTTP-сервисы: простая веб-страница со статусом заказа или остатками, которую отдаёт сама база.
- 💾 Выгрузка отчёта в файл, который откроется в любом браузере без 1С.
Когда HTML не нужен:
| Задача | Чем лучше решать | Почему |
|---|---|---|
| Печатная форма документа | Табличный документ | Точная печать, поля страницы, привычный механизм |
| Отчёт с группировками и отборами | СКД | Пользователь сам меняет настройки |
| Форма ввода данных | Обычные элементы формы | Проверки, привязка к реквизитам |
| Дашборд, справка, письмо | HTML | Свободная вёрстка и стили |
Поле HTML-документа на управляемой форме
Это главный способ показать разметку пользователю. Настройка в конфигураторе:
- Откройте форму, на вкладке «Реквизиты» добавьте реквизит, например
ТекстHTML, типСтрока, длина 0 (неограниченная). - Перетащите реквизит в дерево элементов.
- В свойствах элемента установите
Вид= «Поле HTML-документа». - Для отчётов включите свойство
ТолькоПросмотр, чтобы пользователь не редактировал разметку. - Растяните поле: задайте
РастягиватьПоГоризонталииРастягиватьПоВертикали.
Заполнять реквизит можно на сервере — значение просто передаётся строкой:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ТекстHTML = "<html><head><meta charset=""utf-8""></head>"
+ "<body><h2>Остатки на складе</h2><p>Данные загружаются…</p></body></html>";
КонецПроцедуры
Как обработать клик по ссылке
У поля есть событие ПриНажатии. В него приходит объект ДанныеСобытия с адресом ссылки (Href) и элементом, по которому кликнули (Element). Приём практиков — кодировать команду в адресе и отменять стандартный переход:
&НаКлиенте
Процедура ТекстHTMLПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
Адрес = ДанныеСобытия.Href;
Если СтрНайти(Адрес, "#doc:") > 0 Тогда
СтандартнаяОбработка = Ложь;
ИдСтрокой = Сред(Адрес, СтрНайти(Адрес, "#doc:") + 5);
ОткрытьДокументПоИд(ИдСтрокой);
КонецЕсли;
КонецПроцедуры
В разметке ссылка выглядит так: <a href="#doc:5f2c...">Реализация №125</a>. Процедура ОткрытьДокументПоИд — ваша: на сервере она получает ссылку по Новый УникальныйИдентификатор(ИдСтрокой) и возвращает её на клиент для ПоказатьЗначение().
Не ставьте в href ссылки на внешние сайты без СтандартнаяОбработка = Ложь и явного ЗапуститьПриложение(): иначе страница откроется прямо внутри поля и пользователь потеряет отчёт.
Обращение к странице из кода
После загрузки страницы срабатывает событие ДокументСформирован. Только после него можно обращаться к DOM через свойство элемента Документ, например менять текст блока без перерисовки всего поля. До этого события объект документа может быть ещё не готов — частая причина ошибок «Значение не является значением объектного типа
».
Как собирать HTML кодом 1С
Разметка — обычная строка. Но сложение строк в цикле на тысячах записей работает медленно. Надёжнее копить фрагменты в массив и склеивать один раз через СтрСоединить() (есть с 8.3.6).
Экранирование данных
Главное правило: любое значение из базы перед вставкой в HTML экранируйте. Наименование контрагента ООО "Рога & Копыта" без экранирования сломает вёрстку, а текст со скобками < может превратиться в тег или скрипт.
Функция ЭкранироватьHTML(Знач Текст) Экспорт
Текст = СтрЗаменить(Текст, "&", "&"); // первым — амперсанд
Текст = СтрЗаменить(Текст, "<", "<");
Текст = СтрЗаменить(Текст, ">", ">");
Текст = СтрЗаменить(Текст, """", """);
Возврат Текст;
КонецФункции
Амперсанд заменяйте первым, иначе уже готовые < превратятся в &lt; и на экране появятся служебные символы.
Полный пример: таблица остатков
&НаСервере
Функция СформироватьHTMLОстатков()
Запрос = Новый Запрос(
"ВЫБРАТЬ
| Номенклатура.Наименование КАК Товар,
| Остатки.КоличествоОстаток КАК Количество
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
|УПОРЯДОЧИТЬ ПО
| Товар");
Выборка = Запрос.Выполнить().Выбрать();
Части = Новый Массив;
Части.Добавить("<html><head><meta charset=""utf-8"">");
Части.Добавить(СтилиОтчета());
Части.Добавить("</head><body><table><thead><tr><th>Товар</th><th>Количество</th></tr></thead><tbody>");
Пока Выборка.Следующий() Цикл
Класс = ?(Выборка.Количество <= 0, " class=""zero""", "");
Части.Добавить(СтрШаблон("<tr%1><td>%2</td><td class=""num"">%3</td></tr>",
Класс,
ЭкранироватьHTML(Выборка.Товар),
Формат(Выборка.Количество, "ЧДЦ=3; ЧН=0")));
КонецЦикла;
Части.Добавить("</tbody></table></body></html>");
Возврат СтрСоединить(Части, "");
КонецФункции
Имя регистра в запросе подставьте своё: в БП 3.0 остатки хранятся иначе, чем в УТ 11. Пример показывает приём, а не готовый отчёт под конфигурацию.
Что здесь важно:
- 🔢 Числа выводятся через
Формат(), а не склейкой — так не появятся неразрывные пробелы-разделители там, где они не нужны, и нули не превратятся в пустоту. - 🎨 Подсветка задаётся классом, а не встроенным
styleв каждой строке: разметка короче, стиль меняется в одном месте. - 🧩 Стили вынесены в отдельную функцию
СтилиОтчета()— о ней ниже.
Таблицы и CSS в HTML-отчётах 1С
Стили держите в одном блоке <style> в <head>. Пример, который хорошо смотрится и на экране, и при печати:
body { font-family: Arial, sans-serif; font-size: 13px; color: #222; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ccc; padding: 4px 8px; }
th { background: #f3f3f3; text-align: left; }
td.num { text-align: right; white-space: nowrap; }
tr.zero td { color: #b00; }
tbody tr:nth-child(even) { background: #fafafa; }
@media print {
thead { display: table-header-group; } /* шапка на каждой странице */
tr { page-break-inside: avoid; } /* строка не рвётся между листами */
.no-print { display: none; } /* кнопки и фильтры не печатаются */
}
Как вернуть этот CSS из кода — функция СтилиОтчета() просто возвращает строку "<style>…</style>". Если стилей много, храните их в макете (см. раздел про шаблоны).
Несколько практических наблюдений:
- 📏 Ширины колонок задавайте в процентах или через
<colgroup>, а не пикселями: поле на форме меняет размер вместе с окном. - 🧮 Итоговую строку кладите в
<tfoot>— при печати браузерный движок понимает её как подвал таблицы. - 🖼️ Внешние файлы картинок и стилей поле HTML не найдёт по относительному пути. Картинку встраивайте как
data:URI:"<img src=""data:image/png;base64," + Base64Строка(Данные) + """>". Из результатаBase64Строка()уберите переносы строк черезСтрЗаменить()поСимволы.ПСиСимволы.ВК. - 🧪 Современные CSS-возможности (flex, grid) работают, только если движок поля их поддерживает. В актуальных версиях 8.3 поле использует движок на основе WebKit, но на старых платформах в Windows встраивался Internet Explorer — проверяйте вёрстку на той версии, что стоит у пользователей.
Экспорт HTML-отчёта в PDF и Excel
Здесь главное решение — откуда экспортировать: из готовой HTML-строки или из табличного документа.
| Способ | Что получится | Когда выбирать |
|---|---|---|
Табличный документ → Записать() с типом PDF | Точный PDF с полями страницы | Нужен печатный документ для отправки |
Табличный документ → Записать() с типом XLSX | Настоящая книга Excel с числами | Пользователь будет считать в Excel |
Табличный документ → Записать() с типом HTML5 | Страница для браузера | Нужен лёгкий файл без 1С |
HTML-строка → файл .html | Ваша вёрстка как есть | Отчёт целиком на HTML |
| HTML-строка → печать из поля | PDF через виртуальный принтер | Разовый вывод, без автоматизации |
Платформа не умеет конвертировать произвольный HTML в PDF или XLSX штатными средствами. Поэтому для отчётов, которые регулярно уходят в PDF или Excel, практичнее строить табличный документ (или СКД) и уже его сохранять в нужный формат. HTML оставьте для экрана.
Запись HTML-строки в файл с правильной кодировкой:
Текст = Новый ТекстовыйДокумент;
Текст.УстановитьТекст(СтрокаHTML);
Текст.Записать(ИмяФайла, КодировкаТекста.UTF8);
Старый приём «сохранить HTML-таблицу с расширением .xls» Excel откроет, но с предупреждением о несоответствии формата и расширения. Числа при этом часто становятся текстом. Для обмена с бухгалтерией используйте XLSX из табличного документа.
Шаблоны, XSLT и связь с вебом
Когда отчётов становится больше двух-трёх, держать разметку в строках модуля неудобно. Три уровня решения — от простого к сложному.
1. Шаблон в макете
Создайте макет типа «Текстовый документ», вставьте в него HTML с метками вида %1, %2 или {{Организация}}. В коде получите текст и подставьте значения:
Макет = Обработки.ИнформационнаяПанель.ПолучитьМакет("ШаблонПанели");
Шаблон = Макет.ПолучитьТекст();
Результат = СтрЗаменить(Шаблон, "{{Организация}}", ЭкранироватьHTML(НаименованиеОрганизации));
Плюс: вёрстку правит дизайнер или аналитик, не трогая код. В типовой конфигурации такой макет лучше добавлять через расширение, чтобы обновления не затирали правки.
2. XSLT-преобразование
Если данные уже есть в XML (выгрузка, ответ веб-сервиса), объект ПреобразованиеXSL превращает их в HTML по таблице стилей:
Преобразование = Новый ПреобразованиеXSL;
Преобразование.ЗагрузитьТаблицуСтилейXSLИзСтроки(ТекстXSL);
СтрокаHTML = Преобразование.ПреобразоватьИзСтроки(ТекстXML);
Таблицу стилей XSL удобно хранить в том же текстовом макете. XSLT хорош для единообразных документов из обмена — например, для человекочитаемого просмотра XML-файла электронного документа.
3. HTTP-сервис, отдающий страницу
База может сама отдавать HTML в браузер. В HTTP-сервисе обработчик метода возвращает ответ с нужным заголовком:
Функция СтатусЗаказаGET(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "text/html; charset=utf-8");
Ответ.УстановитьТелоИзСтроки(СформироватьСтраницу(Запрос), КодировкаТекста.UTF8);
Возврат Ответ;
КонецФункции
Сервис публикуется на веб-сервере вместе с базой. Доступ закрывайте аутентификацией: страница работает с правами пользователя, под которым идёт подключение.
Обмен с JavaScript внутри поля
Из JavaScript в 1С проще всего передавать команды через ссылки и событие ПриНажатии (приём с #doc: выше). Это работает одинаково в тонком клиенте и веб-клиенте, без зависимостей от движка. Обратное направление — вызов функции страницы из 1С — делается через объект Документ элемента после события ДокументСформирован, но его поведение зависит от движка поля, так что проверяйте в нужном клиенте.
Частые ошибки при работе с HTML в 1С
<meta charset="utf-8"> или файл записан не в UTF-8. Добавьте meta в head и указывайте КодировкаТекста.UTF8 при записи.<, > или &. Пропускайте все значения через функцию экранирования.Отдельно про безопасность: если в HTML попадает текст, который вводят пользователи или присылают контрагенты (комментарии, назначения платежа), без экранирования в поле может выполниться чужой скрипт. Экранирование — не косметика, а защита.