Как вывести все строки табличной части документа в печатную форму HTML в 1С

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

При разработке печатных форм разработчики 1С чаще всего используют стандартный табличный документ (ТабличныйДокумент). Однако в ряде задач требуется сформировать документ именно в формате HTML — например, для встраивания интерактивных элементов, отправки письма в формате HTML или вывода информации в поле HTML-документа на форме. Нередко возникает ситуация, когда при попытке вывести список строк табличной части (например, сотрудников из документа КадровоеПеремещение) в результирующем документе отображается только одна строка. Выясним причину этой проблемы и рассмотрим несколько надежных способов правильного формирования HTML-печатной формы.

Причины некорректного вывода строк в HTML-разметку

В отличие от табличного документа, где секции выводятся построчно через именованные области (Область), текстовый макет HTML требует соблюдения строгой иерархии тегов и корректной сборки строки. Ошибки обычно связаны со следующими факторами:

  1. Перезапись переменной вместо конкатенации: если внутри цикла обхода табличной части переменной со строкой присваивается новое значение вместо добавления к уже накопленному тексту, на экран попадет только последняя итерация.
  2. Некорректная структура и незакрытые теги: отсутствие закрывающих тегов </td> или </tr>, а также пропущенные кавычки в атрибутах приводят к тому, что парсер браузера скрывает последующие строки таблицы.
  3. Неправильная шаблонизация макета: если в макете-шаблоне заменяется единственный маркер автоподстановки функцией СтрЗаменить без разбивки макета на шапку, повторяемую строку и подвал, то заменится только одно вхождение.

Способ 1. Программная сборка HTML-кода через конкатенацию строк

Разберем базовый и наиболее прямолинейный подход, при котором HTML-разметка динамически формируется во встроенном языке 1С. Для обеспечения корректного отображения во всех браузерах и встроенных компонентах рендеринга важно соблюдать базовую структуру документа с тегами <html> и <body>.

Посмотрим на пример кода формирования таблицы по табличной части документа:


ТекстHTML = "<html>
    |<head>
    |    <meta http-equiv=""Content-Type"" content=""text/html; charset=utf-8"">
    |</head>
    |<body>
    |<table border='1' cellpadding='4' cellspacing='0' style='border-collapse: collapse; width: 100%;'>
    |    <tr style='background-color: #f2f2f2;'>
    |        <th>№</th>
    |        <th>Сотрудник</th>
    |        <th>Должность</th>
    |    </tr>";

НомерСтроки = 0;
Для Каждого Стр Из СсылкаНаОбъект.Сотрудники Цикл
    НомерСтроки = НомерСтроки + 1;
    ТекстHTML = ТекстHTML + "
    |    <tr>
    |        <td align='center'>" + НомерСтроки + "</td>
    |        <td>" + Стр.Сотрудник + "</td>
    |        <td>" + Стр.Должность + "</td>
    |    </tr>";
КонецЦикла;

ТекстHTML = ТекстHTML + "
    |</table>
    |</body>
    |</html>";

// Вывод сформированного текста в поле HTML-документа
ЭлементыФормы.ПолеHTML.УстановитьТекст(ТекстHTML);

Обратим внимание на ключевой момент: шапка таблицы создается до начала цикла, тело таблицы наполняется строками <tr> на каждой итерации цикла, а закрывающие теги таблицы и документа добавляются строго после завершения обхода коллекции.

Способ 2. Разбиение готового HTML-макета на секции

Если макет печатной формы сложный, хранить весь HTML-код внутри модуля неудобно. В этом случае создадим текстовый или HTML-макет в конфигурации и разделим его специальными маркерами в комментариях: <!--ШАПКА-->, <!--СТРОКА-->, <!--ПОДВАЛ-->.

Рассмотрим, как прочитать макет, разделить его на блоки и собрать результирующий документ:


МакетТекст = ПолучитьМакет("МакетПечати").ПолучитьТекст();

// Находим позиции разделителей секций
ПозСтрокаНачало = СтрНайти(МакетТекст, "<!--СТРОКА-->");
ПозСтрокаКонец  = СтрНайти(МакетТекст, "<!--/СТРОКА-->");

Шапка  = Лев(МакетТекст, ПозСтрокаНачало - 1);
ШаблонСтроки = Сред(МакетТекст, ПозСтрокаНачало + 13, ПозСтрокаКонец - (ПозСтрокаНачало + 13));
Подвал = Сред(МакетТекст, ПозСтрокаКонец + 14);

ВсеСтроки = "";
Для Каждого Стр Из ТабличнаяЧасть Цикл
    ТекущаяСтрокаHTML = ШаблонСтроки;
    ТекущаяСтрокаHTML = СтрЗаменить(ТекущаяСтрокаHTML, "[Сотрудник]", Стр.Сотрудник);
    ТекущаяСтрокаHTML = СтрЗаменить(ТекущаяСтрокаHTML, "[Подразделение]", Стр.Подразделение);
    ВсеСтроки = ВсеСтроки + ТекущаяСтрокаHTML;
КонецЦикла;

ИтоговыйHTML = Шапка + ВсеСтроки + Подвал;
ЭлементыФормы.ПолеHTML.УстановитьТекст(ИтоговыйHTML);

Способ 3. Использование объекта ЗаписьHTML

Для предотвращения ошибок синтаксиса и автоматического контроля закрытия тегов платформа 1С предоставляет специализированный объект ЗаписьHTML. Проанализируем пример его использования:


Запись = Новый ЗаписьHTML;
Запись.УстановитьСтроку();

Запись.ЗаписатьНачалоЭлемента("html");
Запись.ЗаписатьНачалоЭлемента("body");
Запись.ЗаписатьНачалоЭлемента("table");
Запись.ЗаписатьАтрибут("border", "1");

Для Каждого Стр Из ТабличнаяЧасть Цикл
    Запись.ЗаписатьНачалоЭлемента("tr");
    
    Запись.ЗаписатьНачалоЭлемента("td");
    Запись.ЗаписатьТекст(Строка(Стр.Сотрудник));
    Запись.ЗаписатьКонецЭлемента(); // td
    
    Запись.ЗаписатьКонецЭлемента(); // tr
КонецЦикла;

Запись.ЗаписатьКонецЭлемента(); // table
Запись.ЗаписатьКонецЭлемента(); // body
Запись.ЗаписатьКонецЭлемента(); // html

РезультатHTML = Запись.Закрыть();

Способ 4. Формирование через ТабличныйДокумент с экспортом в HTML

Если макет уже реализован в виде классического табличного документа с именованными областями, нет необходимости переписывать всю логику вручную. Сформируем стандартный ТабличныйДокумент и сохраним его в HTML:


ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("ПечатьКадровогоПеремещения");

ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ТабДок.Вывести(ОбластьШапка);

ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Для Каждого Стр Из ДокументОбъект.РаботникиОрганизации Цикл
    ОбластьСтрока.Параметры.Заполнить(Стр);
    ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

ВременныйФайл = ПолучитьИмяВременногоФайла("html");
ТабДок.Записать(ВременныйФайл, ТипФайлаТабличногоДокумента.HTML5);

ТекстHTML = Новый ЧтениеТекста(ВременныйФайл, КодировкаТекста.UTF8);
ЭлементыФормы.ПолеHTML.УстановитьТекст(ТекстHTML.Прочитать());
ТекстHTML.Закрыть();
УдалитьФайлы(ВременныйФайл);

Разрыв страниц при печати HTML

Если печатная форма кадрового перемещения требует вывода каждого сотрудника на отдельном листе, используем специальные стили CSS. Вставим между записями блок с разрывом страницы:

ТекстHTML = ТекстHTML + "<div style='page-break-after: always;'></div>";

При отправке сформированного документа на печать браузер или компонент формы автоматически разобьет печатный документ на отдельные листы в указанных местах.

← На главную