Как программно отправить табличную часть или табличный документ во вложении письма в формате XLSX?

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

При разработке различных регламентных заданий и отчетов в системе 1С:Предприятие часто возникает задача автоматической рассылки данных. Типичный сценарий: есть сформированный табличный документ (результат сравнения данных, отчет или печатная форма), который необходимо отправить пользователю по электронной почте в формате XLSX. В этой статье мы подробно разберем, как реализовать этот механизм правильно, избегая типичных ошибок, таких как использование статических путей на сервере или попытка вставить объект табличного документа напрямую в тело письма.

Анализ проблемы и выбор стратегии

Рассмотрим ситуацию: у нас есть объект ТабличныйДокумент (в коде автора он называется ПолеТабДок). Попытка просто вставить его в структуру параметров письма в поле "Тело" не приведет к успеху, так как почтовые серверы и библиотеки 1С ожидают там либо простой текст, либо HTML-код. Для того чтобы файл пришел именно как вложение, нам нужно преобразовать ТабличныйДокумент в поток двоичных данных и правильно заполнить структуру вложений для Библиотеки Стандартных Подсистем (БСП).

Проанализируем два основных способа решения этой задачи:

  1. Использование временных файлов: универсальный метод, работающий на любых версиях платформы.
  2. Использование потоков в памяти: наиболее современный и быстрый способ, доступный начиная с версии платформы 8.3.9, который не требует записи данных на жесткий диск.

Способ №1. Использование временных файлов (универсальный)

Этот метод заключается в сохранении табличного документа во временную папку операционной системы, чтении его в двоичные данные и последующем удалении. Важно не использовать фиксированные пути вроде "\\server\Admin\...", так как у службы 1С может не быть прав на запись в эту сетевую папку, а имена файлов могут конфликтовать при одновременной работе нескольких пользователей.

Разберем по шагам, как это реализовать:


// 1. Получаем уникальное имя временного файла
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");

// 2. Записываем табличный документ в файл
ПолеТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);

// 3. Подготавливаем структуру вложения
МассивВложений = Новый Массив;
СтруктураВложения = Новый Структура;
СтруктураВложения.Вставить("Данные", Новый ДвоичныеДанные(ИмяФайла));
СтруктураВложения.Вставить("ИмяФайла", "ОтчетПоСравнению.xlsx");
МассивВложений.Добавить(СтруктураВложения);

// 4. Формируем параметры письма для БСП
ПараметрыПисьма = Новый Структура;
ПараметрыПисьма.Вставить("Кому", АдресаЭП); 
ПараметрыПисьма.Вставить("Тема", "Регл.задание: Отчет");
ПараметрыПисьма.Вставить("Тело", "Добрый день! Во вложении файл с результатами сравнения.");
ПараметрыПисьма.Вставить("Вложения", МассивВложений);

// 5. Отправка (используем стандартный механизм БСП)
ПодготовленноеПисьмо = РаботаСПочтовымиСообщениями.ПодготовитьПисьмо(СистемнаяУчетнаяЗапись, ПараметрыПисьма);
РаботаСПочтовымиСообщениями.ОтправитьПисьмо(СистемнаяУчетнаяЗапись, ПодготовленноеПисьмо);

// 6. Обязательно удаляем временный файл
УдалитьФайлы(ИмяФайла);

В данном примере мы используем объект ДвоичныеДанные, который считывает файл с диска в оперативную память. Это позволяет нам сразу после формирования структуры вложения безопасно удалить файл с диска, не дожидаясь фактической отправки письма сервером.

Способ №2. Использование потока в памяти (без записи на диск)

Если ваша версия платформы позволяет использовать ПотокВПамяти, мы рекомендуем этот способ. Он исключает лишние операции ввода-вывода (I/O) и считается более надежным для высоконагруженных систем.

Проанализируем код реализации этого метода:


// Создаем поток в памяти
Поток = Новый ПотокВПамяти();

// Записываем табличный документ непосредственно в поток в формате XLSX
ПолеТабДок.Записать(Поток, ТипФайлаТабличногоДокумента.XLSX);

// Получаем двоичные данные из потока
ДвоичныеДанныеФайла = Поток.ЗакрытьИПолучитьДвоичныеДанные();

// Формируем вложение
МассивВложений = Новый Массив;
Вложение = Новый Структура("Представление, Данные", "Отчет.xlsx", ДвоичныеДанныеФайла);
МассивВложений.Добавить(Вложение);

// Далее передаем МассивВложений в ПараметрыПисьма.Вставить("Вложения", МассивВложений);

Важный момент: Обратите внимание на имена ключей в структуре вложения. В зависимости от версии БСП, используемой в вашей конфигурации, ключи могут называться "ИмяФайла" или "Представление". Рекомендуется проверить определение функции РаботаСПочтовымиСообщениями.ПодготовитьПисьмо в вашей базе.

Способ №3. Отображение таблицы прямо в теле письма (HTML)

Иногда пользователю удобнее увидеть таблицу сразу при открытии письма, не скачивая вложение. В этом случае нам нужно конвертировать ТабличныйДокумент в формат HTML. Выясним, как это сделать правильно.

Рассмотрим функцию-помощник:


Функция ПолучитьHTMLТекстИзТабДока(ТабДок)
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("html");
    // Сохраняем в HTML4 для лучшей совместимости с почтовыми клиентами
    ТабДок.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.HTML);
    
    ТекстовыйДок = Новый ТекстовыйДокумент;
    ТекстовыйДок.Прочитать(ИмяВременногоФайла, КодировкаТекста.UTF8);
    Результат = ТекстовыйДок.ПолучитьТекст();
    
    УдалитьФайлы(ИмяВременногоФайла);
    Возврат Результат;
КонецФункции

После получения текста HTML, в параметрах письма необходимо указать соответствующий тип текста:


ПараметрыПисьма.Вставить("ТипТекста", Перечисления.ТипыТекстовЭлектронныхПисем.HTML);
ПараметрыПисьма.Вставить("Тело", ПолучитьHTMLТекстИзТабДока(ПолеТабДок));

Рекомендации по работе с регламентными заданиями

Поскольку автор в исходном сообщении упоминает "Регл.задание", следует учитывать несколько критически важных моментов:

  1. Права доступа: Регламентное задание выполняется на стороне сервера под учетной записью службы «1С:Предприятие». Убедитесь, что у этой учетной записи есть права на чтение/запись во временные папки сервера.
  2. Системная учетная запись: Для отправки почты в фоновом задании должна быть настроена системная учетная запись электронной почты (в разделе «Администрирование» — «Органайзер»), так как интерактивный выбор почтового ящика в фоновом режиме невозможен.
  3. Обработка ошибок: Всегда оборачивайте вызов РаботаСПочтовымиСообщениями.ОтправитьПисьмо в конструкцию Попытка...Исключение, чтобы ошибка отправки почты (например, из-за временной недоступности SMTP-сервера) не приводила к аварийному завершению всего регламентного задания.
  4. Формат PDF: Если получателю не нужно редактировать таблицу, мы рекомендуем использовать формат ТипФайлаТабличногоДокумента.PDF. Он гарантирует, что оформление отчета (цвета, шрифты, границы) будет выглядеть одинаково на всех устройствах, включая смартфоны.

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

← На главную