Я использую модуль 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/
Добавить комментарий