Маркированные списки через Python-docx-template (docxtpl)

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

  • первыйэлемент
  • второйэлемент
  • третийэлемент

Причем тег должен быть под вторым номером. в шаблоне это выглядит примерно так:

  • первыйэлемент
  • {{ item }}
  • третийэлемент

Но в таком варианте несколько минусов:

  1. если нет данных для элемента, он оставляет пустую строку и получается такой вид:
  • первыйэлемент
  • третийэлемент

А должно быть два маркированных элемента такого вида:

  • первыйэлемент
  • третийэлемент
  1. если тег вставить в конец предыдущего тега, при вставке элемента оно сломает табуляцию.

Как решить эту проблему?


Ответы (1 шт):

Автор решения: insolor

docxtpl работает на основе шаблонизатора jinja2. В jinja2 есть управляющие конструкции типа if или for, работающие примерно аналогично таким же конструкциям в python (только блоки кода обозначаются не отступами, а закрывающими тегами endif и endfor).

Например, скрытие/отображение элемента с помощью if (если в item будет None, то его строка вообще не отобразится):

{%- if item %}
- {{ item }}
{%- endif %}

- черточка после % означает, что сама эта строка с тегом будет удалена

Отображение набора элементов с помощью for:

{%- for item in items %}
- {{ item }}
{%- endfor %}

В коде через items передается список элементов, при заполнении шаблона одна строка - {{ item }} превратится в несколько строк по количеству элементов в списке items. Если список items будет пустой, то вообще ни одна строка не отобразится.

Рабочий пример кода:

from docxtpl import DocxTemplate

doc = DocxTemplate('template.docx')

item = None  # Пустой элемент, соответствующий пункт не отобразится

items = [
    "первый элемент",
    "второй элемент",
    "третий элемент",
]

context = {'item': item, 'items': items}

doc.render(context)
doc.save('output.docx')

Шаблон (файл template.docx):

Скриншот шаблона

Или такой вариант, сами строки с if/endif тоже могут быть элементами списка (при заполнении шаблона удалятся, благодаря "магической" черточке):

Скриншот шаблона

Результат заполнения шаблона (файл output.docx):

введите сюда описание изображения

→ Ссылка