Сообщить об ошибке.

Создание отчетов и писем по шаблонам в Python

Довольно часто возникают ситуации, когда нужно генерировать определенные отчеты или манипулировать строками. Общим для всех этих ситуаций является то, что создание отчета или обработка строк следует определенному шаблону. Обычно шаблоны очень похожи и мы их используем повторно. Python предоставляет класс string.Template(), который может помочь в генерации каких то стандартных отчетов, приглашений, писем и т.д.

Этот класс предназначен для создания текста на основе данных с применением шаблонов. Преимуществ использования string.Template() по сравнению с другими решениями.

  • Модуль string доступен в Python по умолчанию и как говориться "работает из коробки", следовательно не требуется никаких дополнительных зависимостей.
  • Он легкий по сравнению с другими, широко используемыми движками шаблонов, таких как Jinja2 и Mako и т.д.
  • Разделение кода и текста шаблона: вместо встраивания шаблонного текста непосредственно в код, файл шаблона можно поместить в файл, что позволит обмениваться файлом шаблона вместо того, чтобы передавать весь код.

И так, допустим надо сделать рассылку приглашений на какое-то мероприятие, и есть шаблон письма, который храниться в файле mail-invitation.tpl:

Уважаемый ${name_member}!

Мы будем рады видеть сотрудников Вашей компании среди участников конференции ${name_event}, которая пройдет ${date_event} в городе ${city_event} на территории: ${address_event}.

Основной целью конференции является ознакомление руководителей, а также IT-директоров крупных и малых предприятий с возможностями современных информационных технологий и их влиянием на развитие бизнеса.

В ходе конференции своим опытом поделятся представители таких международных компаний, как: ${firms}.

С уважением, ${name_head}.

Данные будут подставляться в переменные, определенные в шаблоне в виде ${name_variable}.

Массив с данными участников мероприятия хранится, например в базе данных, в .csv или .json файлах это не принципиально так как эти форматы данных легко преобразовываются в словари dict Python, с которыми прекрасно работает string.Template():

Пускай это будет .json файл с названием data.json и небольшим куском данных как показано ниже:

[
    {"name": "Анатолий Сергеевич", "email": "one@server.ru"},
    {"name": "Иван Иванович", "email": "two@server.ru"},
    {"name": "Сергей Анатольевич", "email": "three@server.ru"}
]

Реализуем Python-скрипт c названием report.py в текущем рабочем каталоге. Данные мероприятия можно так-же загрузить из файла, в данном случае они представлены в виде словаря. Получившиеся письма выведем в терминал.

# report.py
import json, string

# Данные мероприятия
data = {
    'name_head': 'Александр Викторович',
    'city_event': 'Москва',
    'date_event': '15.03.2021',
    'name_event': '«Развитие бизнеса с помощью информационных технологий»',
    'address_event': 'Рождественский бульвар, 28',
    'firms': ['ООО «Innovation»', 'ООО «Science»', 'ООО «InternationalData»']
    }

# Преобразуем список компаний участников в строку
data['firms'] = ', '.join(data['firms'])

# Загружаем шаблон
with open('mail-invitation.tpl') as tpl:
    temp = tpl.read()

template = string.Template(temp)

# Загружаем данные участников 
with open('data.json') as fp:
    members = json.load(fp)

# Проходим по участникам и генерируем 
# письма, которые выведем в терминал
for member in members:
    # Добавим к данным мероприятия 
    # имя участника из .json файла
    data['name_member'] = member['name']
    # получаем готовое письмо
    output = template.substitute(data)
    print('-'*30)
    # Почта, на которую отправляем письмо
    print('Почта:', member['email'])
    # готовое письмо к отправке
    print(output)

Таким же образом можно генерировать письма или отчеты в формате HTML.

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

>>> firms = ['ООО «Innovation»', 'ООО «Science»', 'ООО «InternationalData»']
# добавляем пустую строку в начало списка
>>> firms.insert(0, '')
# объединяем список в столбик
>>> out = '\n- '.join(firms)
>>> print(out)

# - ООО «Innovation»
# - ООО «Science»
# - ООО «InternationalData»