Использование python-docx-template для динамического создания закладок и ссылок на них в документах Word

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Я использую модуль python-docx-template для генерации файлов docx по шаблону.

Подробнее о модуле можно почитать здесь: https://docs-python.ru/packages/modul-python-docx-python/modul-docx-template/

Модуль содержит функционал для вставки в документ внешних ссылок, но когда мне понадобилось создавать по шаблону внутренние ссылки (на конкретное место в документе), такого функционала не нашлось, поиск в сети тоже ничего не дал.

Здесь я предлагаю свой способ вставки закладок (bookmarks) и ссылок (hyperlinks) на них при помощи python-docx-template.

Решение

В состав модуля входит объект RichText(). Метод add(string) этого объекта создает xml код, который помещается в RichText().xml и далее вставляется как есть в документ docx.

Например:

rt = RichText()
rt.add('TEST')
print(rt.xml)
# <w:r><w:t xml:space="preserve">TEST</w:t></w:r>

Я решил самостоятельно генерировать и напрямую помещать нужный мне код xml в RichText().xml и это сработало.

Ниже пример кода:

from docxtpl import DocxTemplate, RichText


def add_bookmarks_and_links(data):
    for i, item in enumerate(data['articles']):
        # создаем закладку
        bookmark_name = f'article_{i}'
        bookmark = RichText(item["title"])
        bookmark.xml = f'<w:bookmarkStart w:id="" w:name="{bookmark_name}"/>' + \
                       bookmark.xml + \
                       '<w:bookmarkEnd w:id=""/>'
        item['title_with_bookmark'] = bookmark

        # создаем ссылку на закладку
        hyperlink_start = RichText()
        hyperlink_end = RichText()
        hyperlink_start.xml = f'<w:hyperlink w:anchor="{bookmark_name}" w:history="1">'
        hyperlink_end.xml = '</w:hyperlink>'
        item['hyperlink_start'] = hyperlink_start
        item['hyperlink_end'] = hyperlink_end


data = {'report_title': 'Report title',
        'articles': [{'title': 'Title Article 1',
                      'description': 'Description Article 1',
                      'body': 'Body Article 1'},
                     {'title': 'Title Article 2',
                      'description': 'Description Article 2',
                      'body': 'Body Article 2'}
                     ]
        }

template_filename = 'template.docx'
result_filename = 'result.docx'

add_bookmarks_and_links(data)
tpl = DocxTemplate(template_filename)
tpl.render(data)
tpl.save(result_filename)

Файл шаблона docx выглядит примерно так:

{{ report_title }}
Дайджест
{% for article in articles %}
{{r article.hyperlink_start }}{{ article.title }}{{r article.hyperlink_end }}
{{ article.description }}
{% endfor %}
Полные тексты статей
{% for article in articles %}
{{ article.title_with_bookmark }}
{{ article.description }}
{{ article.body }}
{% endfor %}

В результате выполнения кода получаем документ с разделом дайджестов статей, с ссылками в заголовках, которые ведут на полные тексты статей:

Аналогичным образом можно вставлять в поля шаблона любой другой неподдерживаемый модулем python-docx-template xml-код.

Спасибо за внимание.

Источник: https://habr.com/ru/articles/749706/


Интересные статьи

Интересные статьи

Привет! Меня зовут Артемий Козырь, и я Analytics Engineer в Wheely.Мы могли бы долго и нудно обсуждать, кто такой Analytics (Data / Backend) Engineer, какими инструментами он должен владеть, какие buz...
Мне нравится создавать и решать кодовые ката. Код Ката — это головоломки по программированию, которые помогут вам отточить свои навыки программирования. Я написал статью под названием «Learn...
— Статья, которая поможет вам разобраться в принципе работы и идее, стоящей за Word2Vec.Источник: GoogleВ предыдущей статье я рассказывал об основах NLP (Natural Language Processing — обработка естест...
Что делаю Для личного проекта потребовалось найти решение, для работы с некоторым количеством разных gltf моделей. Небольшой опыт работы с three.js у меня был, поэтому, после ознако...
Каждые несколько лет в индустрии разработки ПО происходит смена парадигмы. Одним из таких явлений можно признать рост интереса к концепции микросервисов. Хотя микросервисы — это технология не сам...