При автоматизации почтовых рассылок из 1С часто возникает задача: уведомить ответственных сотрудников о поступлении товаров, прикрепив список номенклатуры прямо в текст сообщения. Нередко разработчики пытаются сохранить печатную форму или табличную часть как файл PDF или графический файл и вставить его внутрь HTML-письма через тег <img> с локальным путем. В результате получатель видит пустую область или красный крестик.
Проанализируем причины этой ошибки и разберем надежные способы отправки табличных данных непосредственно в теле письма.
Разберем типичные ошибки, с которыми сталкиваются при реализации таких задач:
file:///C:/temp/... в теле письма работает только на том компьютере, где файл физически записан на диск. Почтовый клиент получателя ищет путь на своем устройстве и закономерно не находит файл.<img> стандарта HTML предназначен только для растровой и векторной графики. Файлы формата PDF почтовые клиенты в нем не отображают.ТабличныйДокумент в платформе «из коробки» не поддерживает сохранение напрямую в графические форматы через метод Записать(). Попытка указать расширение изображения приведет к ошибке выполнения.Рассмотрим наиболее простой и универсальный вариант. Если для документа уже разработана печатная форма или макет отчета, мы можем вывести данные в ТабличныйДокумент, сохранить его во временный HTML-файл, прочитать как строку и передать в тело сообщения.
Разберем по шагам реализацию данного механизма:
ТипФайлаТабличногоДокумента.HTML.ЧтениеТекста в кодировке UTF-8.ТипТекстаПочтовогоСообщения.HTML.Посмотрим на пример кода отправки:
// 1. Формируем табличный документ
ТабДок = Новый ТабличныйДокумент;
// ... здесь заполняем ТабДок макетом и данными документа ...
// 2. Сохраняем во временный HTML-файл
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("html");
ТабДок.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.HTML);
// 3. Считываем HTML-код из файла
Чтение = Новый ЧтениеТекста;
Чтение.Открыть(ИмяВременногоФайла, КодировкаТекста.UTF8);
ТекстHTML = Чтение.Прочитать();
Чтение.Закрыть();
УдалитьФайлы(ИмяВременногоФайла);
// 4. Формируем почтовое сообщение
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Поступление товаров";
Письмо.Тексты.Добавить(ТекстHTML, ТипТекстаПочтовогоСообщения.HTML);
// ... дальнейшая отправка через ИнтернетПочта ...
Если печатной формы нет и нужно быстро отправить содержимое конкретной табличной части документа, эффективнее всего выгрузить строки в ТаблицаЗначений и программно сгенерировать HTML-разметку с помощью объекта ДокументHTML.
Рассмотрим подробнее функцию, которая принимает таблицу данных и формирует готовую разметку для письма:
Функция ПолучитьHTMLизТаблицыЗначений(ТаблицаДанных, СтруктураПараметров = Неопределено) Экспорт
Если СтруктураПараметров = Неопределено Тогда
СтруктураПараметров = Новый Структура;
КонецЕсли;
ШиринаРамки = 1;
ЦветРамки = "#CCCCCC";
// Создаем основу HTML-документа
ДокHTML = Новый ДокументHTML("");
ТелоДокумента = ДокHTML.СоздатьЭлемент("BODY");
ДокHTML.Тело = ТелоДокумента;
// Добавляем сопроводительный текст
Параграф = ДокHTML.СоздатьЭлемент("P");
Параграф.ТекстовоеСодержимое = "Поступил новый товар по документу:";
ТелоДокумента.ДобавитьДочерний(Параграф);
// Создаем саму таблицу
ЭлементТаблица = ДокHTML.СоздатьЭлемент("TABLE");
ЭлементТаблица.Рамка = Формат(ШиринаРамки, "ЧГ=0");
ЭлементТаблица.ОтступДоЯчейки = "4";
ЭлементТаблица.РасстояниеМеждуЯчейками = "0";
ЭлементТаблица.Ширина = "100%";
// Устанавливаем цвет границы
АтрибутЦвета = ДокHTML.СоздатьАтрибут("borderColor");
АтрибутЦвета.Значение = ЦветРамки;
ЭлементТаблица.Атрибуты.УстановитьИменованныйЭлемент(АтрибутЦвета);
ТелоДокумента.ДобавитьДочерний(ЭлементТаблица);
ТелоТаблицы = ДокHTML.СоздатьЭлемент("TBODY");
ЭлементТаблица.ДобавитьДочерний(ТелоТаблицы);
// Создаем строку заголовков
СтрокаШапки = ДокHTML.СоздатьЭлемент("TR");
СтрокаШапки.ЦветФона = "#EAEAEA";
ТелоТаблицы.ДобавитьДочерний(СтрокаШапки);
Для Каждого Колонка Из ТаблицаДанных.Колонки Цикл
Ячейка = ДокHTML.СоздатьЭлемент("TH");
Ячейка.ТекстовоеСодержимое = Колонка.Имя;
СтрокаШапки.ДобавитьДочерний(Ячейка);
КонецЦикла;
// Заполняем строки данными
Для Каждого Стр Из ТаблицаДанных Цикл
СтрокаДанных = ДокHTML.СоздатьЭлемент("TR");
ТелоТаблицы.ДобавитьДочерний(СтрокаДанных);
Для Каждого Колонка Из ТаблицаДанных.Колонки Цикл
Ячейка = ДокHTML.СоздатьЭлемент("TD");
Ячейка.ТекстовоеСодержимое = СокрЛП(Строка(Стр[Колонка.Имя]));
СтрокаДанных.ДобавитьДочерний(Ячейка);
КонецЦикла;
КонецЦикла;
// Записываем DOM-документ в строку
ЗаписьHTML = Новый ЗаписьHTML;
ЗаписьHTML.УстановитьСтроку();
ЗаписьDOM = Новый ЗаписьDOM;
ЗаписьDOM.Записать(ДокHTML, ЗаписьHTML);
Возврат ЗаписьHTML.Закрыть();
КонецФункции
Разберем пример использования этой функции при отправке документа:
ТаблицаТоваров = ДокументСсылка.Товары.Выгрузить();
// Оставляем только нужные пользователю колонки
КолонкиДляУдаления = Новый Массив;
Для Каждого Кол Из ТаблицаТоваров.Колонки Цикл
Если Кол.Имя <> "Номенклатура" И Кол.Имя <> "Количество" И Кол.Имя <> "ЕдиницаИзмерения" Тогда
КолонкиДляУдаления.Добавить(Кол);
КонецЕсли;
КонецЦикла;
Для Каждого Кол Из КолонкиДляУдаления Цикл
ТаблицаТоваров.Колонки.Удалить(Кол);
КонецЦикла;
ТекстСообщенияHTML = ПолучитьHTMLизТаблицыЗначений(ТаблицаТоваров);
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Поступление товаров № " + ДокументСсылка.Номер;
Письмо.Тексты.Добавить(ТекстСообщенияHTML, ТипТекстаПочтовогоСообщения.HTML);
Обратим внимание на важные детали при работе с рассылкой таблиц:
.html и открыть в любом браузере.