Как изменить отображаемое имя вложения при отправке почты в 1С?

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

При реализации автоматической рассылки отчетов, расчетных листков или табелей учета рабочего времени разработчики часто сталкиваются с задачей формирования файлов во временном каталоге. Чтобы избежать конфликтов доступа и блокировок при одновременной работе нескольких пользователей или фоновых заданий, файл сохраняется на диск с помощью функции ПолучитьИмяВременногоФайла. В результате получается физический файл со случайным системным именем, например v8_AFE0_ef.xlsx.

Для конечного получателя такое название в письме выглядит неинформативно. Логично передать во второй параметр метода Добавить коллекции вложений понятное человеку наименование, например «Транспортный цех.xlsx». Однако на практике почтовые клиенты (Outlook, Thunderbird, веб-интерфейсы Яндекс, Mail.ru, Gmail) продолжают отображать исходное имя временного файла. Разберем, почему это происходит и как правильно передавать вложения с нужным именем.

Причина поведения платформы и почтовых клиентов

Выясним причину такого поведения на уровне почтовых протоколов и формирования заголовков MIME-сообщения:

  1. Когда мы передаем в метод Сообщение.Вложения.Добавить(ПутьКФайлу, "ИмяДляПользователя") путь к файлу на диске, платформа 1С записывает переданную строку во внутренний заголовок Content-Type: ...; name="...", а реальное имя файла с жесткого диска помещает в служебный заголовок Content-Disposition: attachment; filename="...".
  2. По современным почтовым стандартам (RFC 2183 и RFC 6266) почтовые клиенты и веб-сервисы определяют имя скачиваемого файла именно по параметру filename из заголовка Content-Disposition, полностью игнорируя параметр name из Content-Type. В результате адресат видит имя сгенерированного временного файла v8_AFE0_ef.xlsx.
  3. Свойство ИмяФайла объекта ИнтернетПочтовоеВложение при добавлении файла с диска доступно только для чтения, поэтому изменить его напрямую после добавления невозможно.

Основное решение: передача двоичных данных

Для того чтобы обойти разделение имен между заголовками, необходимо исключить передачу дискового пути в почтовое сообщение. Если вместо строкового пути передать объект ДвоичныеДанные, у платформы не будет информации о физическом файле на диске. В этом случае 1С использует строку из второго параметра для заполнения обоих MIME-заголовков.

Посмотрим на пример правильного формирования вложения:


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

// Читаем файл в двоичные данные
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяВременногоФайла);

// Формируем почтовое сообщение
Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Отправитель = Отправитель;
Сообщение.ИмяОтправителя = "Роботизированная рассылка";
Сообщение.Получатели.Добавить(ЭлектроннаяПочтаПолучателя);
Сообщение.Тема = "Табель учета рабочего времени";

// Важно: передаем двоичные данные и желаемое имя с расширением
ИмяДляПолучателя = "Транспортный цех.xlsx";
Вложение = Сообщение.Вложения.Добавить(ДвоичныеДанныеФайла, ИмяДляПолучателя);

// При необходимости указываем кодировку для корректного отображения кириллицы
Вложение.Кодировка = "utf-8";

// Отправляем письмо через установленное почтовое соединение
ПочтовоеСоединение.Послать(Сообщение);

// Удаляем временный файл с диска
УдалитьФайлы(ИмяВременногоФайла);

Важные нюансы формирования имени вложения

При использовании этого метода обратим внимание на обязательные технические детали:

  1. Обязательное расширение файла: во втором параметре метода Добавить необходимо обязательно указывать расширение файла (например, .xlsx или .pdf). Если передать просто строку "Транспортный цех", почтовый клиент не сможет определить тип файла и сохранит его без расширения либо назначит системное расширение по умолчанию (.bin, .dat). В результате пользователь не сможет открыть файл двойным кликом.
  2. Очистка недопустимых символов: названия подразделений, контрагентов или документов в базе 1С часто содержат знаки препинания или спецсимволы (кавычки, слэши, двоеточия). Перед формированием имени файла обязательно удалим из строки символы, запрещенные операционной системой: \ / : * ? " < > |.
  3. Кодировка заголовков: для исключения искажения русских букв («кракозябр») в старых почтовых клиентах рекомендуется явно задавать свойство Вложение.Кодировка = "utf-8";.

Альтернативный вариант: формирование документа в памяти без записи на диск

Если табличный документ формируется программно, можно вообще отказаться от использования временных файлов на диске. Платформа 1С позволяет записать результат в поток памяти и сразу получить двоичные данные. Это ускоряет работу, снижает нагрузку на дисковую подсистему сервера и исключает проблемы с очисткой временных файлов при аварийном завершении регламентных заданий.

Разберем реализацию через работу с потоками:


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

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

// Добавляем вложение в сообщение
ИмяФайлаВложения = "Табель_Транспортный_цех.xlsx";
Сообщение.Вложения.Добавить(ДвоичныеДанныеОтчета, ИмяФайлаВложения);

Использование механизмов БСП

Если конфигурация разработана на основе «1С:Библиотеки стандартных подсистем» (БСП), ручную работу с объектами ИнтернетПочта и ИнтернетПочтовоеСообщение лучше заменить на вызовы штатных методов общего модуля РаботаСЭлектроннойПочтой. Механизмы БСП автоматически корректно формируют почтовые заголовки, упаковывают вложения и контролируют кодировки.

Посмотрим на пример отправки через подсистему БСП:


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

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

ПараметрыПисьма.Вставить("Вложения", Вложения);

// Отправляем письмо через системную или пользовательскую учетную запись
РаботаСЭлектроннойПочтой.ОтправитьПисьмо(УчетнаяЗапись, ПараметрыПисьма);

Такой подход обеспечивает полную кроссплатформенную совместимость и избавляет от необходимости вручную настраивать параметры MIME-сообщений.

← На главную