Отправка электронных писем с табличными данными из 1С — это стандартная задача для многих корпоративных систем. Однако разработчики часто сталкиваются с тем, что в почтовом клиенте Microsoft Outlook (особенно версий 2013, 2016 и новее) таблицы отображаются некорректно: появляются двойные рамки, колонки «схлопываются» или расползаются, а стили ведут себя непредсказуемо. Выясним, почему это происходит, и разберем по шагам, как сформировать идеальную HTML-таблицу.
Главная техническая особенность заключается в том, что десктопные версии MS Outlook для Windows используют для рендеринга писем движок текстового процессора Microsoft Word, а не полноценный браузерный движок (как WebKit или Blink). Движок Word имеет крайне ограниченную поддержку современных стандартов HTML и CSS.
В частности, движок Word:
<style> в заголовке документа, особенно если таблицы генерируются динамически.border-collapse: collapse, если оно задано не у самой таблицы, а в общем CSS-файле или применяется к многократно вложенным элементам.cellspacing и cellpadding.Проанализируем типичные ошибки разработчиков и рассмотрим правильные варианты реализации кода в 1С.
---
В первом сообщении темы автор совершает критическую ошибку — он объявляет стили и саму таблицу внутри цикла по контрагентам:
Для Каждого Контрагент Из МассивСтрокКонтрагентов Цикл
ТекущийТабДокHTML = "TABLE{border-collapse:collapse;...}";
ТекущийТабДокHTML = ТекущийТабДокHTML + "<table>...</table>";
// ...
КонецЦикла;
В результате такого подхода в тело письма записывается множество разрозненных блоков таблиц, каждый из которых пытается переопределить стили. Outlook путается в такой разметке, игнорирует свойство слияния границ, что и приводит к появлению некрасивых двойных рамок.
Решение: Стили и саму таблицу необходимо объявить строго один раз. Внутри цикла должны формироваться только строки данных <tr> и ячейки <td>.
---
При попытке объединить данные в одну общую таблицу разработчики часто забывают корректно открывать и закрывать строки таблицы <tr> внутри вложенных циклов по колонкам. Это приводит к тому, что разметка ломается, и ячейки начинают хаотично смещаться по горизонтали.
Также важно разделять ячейки заголовков и ячейки данных. Для заголовков следует использовать тег <th> (Table Header), а для обычных строк — тег <td> (Table Data). Это не только семантически верно, но и помогает Outlook правильно применить форматирование.
---
Чтобы гарантировать 100% одинаковое отображение границ в любых почтовых клиентах (включая Outlook, Gmail, Mail.ru и веб-интерфейсы), рекомендуется полностью отказаться от глобального тега <style> и использовать инлайновые стили (Inline CSS) непосредственно внутри HTML-тегов.
Для тега <table> обязательно нужно задавать атрибуты сброса отступов:
<table cellspacing="0" cellpadding="0" style="border-collapse: collapse; width: 100%; table-layout: fixed;">
Для ячеек <td> и <th> границы и внутренние отступы задаются через атрибут style:
<td style="border: 1px solid #000000; padding: 4px; text-align: center;">Значение</td>
---
Чтобы колонки таблицы имели строго одинаковую ширину, мы должны использовать свойство table-layout: fixed для таблицы. При этом ширину колонок достаточно жестко задать только один раз — в самой первой строке (строке заголовков <th>).
Вычислим ширину динамически в коде 1С. Если у нас есть массив колонок, то ширина одной колонки в процентах рассчитывается как: 100 / КоличествоКолонок. Пропишем это значение в стиле каждой ячейки первой строки.
---
Рассмотрим правильный алгоритм сборки HTML-письма на встроенном языке 1С. Этот код формирует одну общую таблицу, автоматически рассчитывает равную ширину для всех колонок, убирает двойные границы и корректно отображает данные в Outlook.
// Очищаем и готовим строковую переменную для текста письма
ТекстПисьма = "";
// Определяем параметры таблицы
КоличествоКолонок = ТЗДаныеОКонтейнерах.Колонки.Количество();
Если КоличествоКолонок > 0 Тогда
ШиринаКолонкиПроцент = Окр(100 / КоличествоКолонок, 2);
Иначе
ШиринаКолонкиПроцент = 100;
КонецЕсли;
// Шаг 1. Открываем тег таблицы с необходимыми атрибутами для Outlook
// Свойства mso-table-lspace и mso-table-rspace принудительно убирают лишние отступы в Outlook
ТекстПисьма = "<table cellspacing=""0"" cellpadding=""0"" style=""border-collapse: collapse; width: 100%; table-layout: fixed; mso-table-lspace: 0pt; mso-table-rspace: 0pt;"">";
// Шаг 2. Формируем строку заголовков (шапку таблицы)
ТекстПисьма = ТекстПисьма + "<tr style=""background-color: #f2f2f2;"">";
Для Каждого Колонка Из ТЗДаныеОКонтейнерах.Колонки Цикл
// Задаем ширину только в ячейках шапки. Outlook применит её ко всей колонке.
ТекстПисьма = ТекстПисьма + "<th style=""width: " + Строка(ШиринаКолонкиПроцент) + "%; border: 1px solid #000000; padding: 6px; text-align: center; font-weight: bold;"">" + Колонка.Имя + "</th>";
КонецЦикла;
ТекстПисьма = ТекстПисьма + "</tr>";
// Шаг 3. Заполняем строки таблицы данными в цикле
Для Каждого Контрагент Из МассивСтрокКонтрагентов Цикл
// Каждую новую строку обязательно оборачиваем в тег <tr>
ТекстПисьма = ТекстПисьма + "<tr>";
Для Каждого Колонка Из ТЗДаныеОКонтейнерах.Колонки Цикл
ЗначениеЯчейки = Строка(Контрагент[Колонка.Имя]);
Если ПустаяСтрока(ЗначениеЯчейки) Тогда
// Защита от "схлопывания" пустых ячеек в старых версиях Outlook
ЗначениеЯчейки = " ";
КонецЕсли;
// Добавляем ячейку с инлайновыми стилями границ и отступов
ТекстПисьма = ТекстПисьма + "<td style=""border: 1px solid #000000; padding: 4px; text-align: center;"">" + ЗначениеЯчейки + "</td>";
КонецЦикла;
ТекстПисьма = ТекстПисьма + "</tr>";
КонецЦикла;
// Шаг 4. Закрываем таблицу
ТекстПисьма = ТекстПисьма + "</table>";
// Для полной валидности оборачиваем полученную таблицу в теги html и body
ТекстПисьма = "<html><body style=""font-family: Arial, sans-serif; font-size: 12px;"">" + ТекстПисьма + "</body></html>";
Возврат ТекстПисьма;
---
<table> в самом начале и закрываем в самом конце формирования строки письма. Никаких дублирующихся таблиц в цикле.<td> и <th> мы явно прописали рамку border: 1px solid #000000;. Это исключает игнорирование стилей почтовыми клиентами.<th>. Последующие строки автоматически унаследовали эту разметку. гарантирует, что сетка таблицы не «поплывет» в старых версиях Outlook, которые некорректно отображают абсолютно пустые ячейки.Используя данный подход, вы получите предсказуемый, чистый и профессионально выглядящий отчет во всех популярных почтовых программах, включая десктопный Outlook любой версии.