Django создает документы.odt или.docx для загрузки

Мне нужно сгенерировать файлы.odt или.docx на основе информации, имеющейся в моей базе данных. Допустим, у меня есть модель:

class Contact(models.Model):
    first_name = models.CharField()
    last_name = models.CharField()
    email = models.EmailField()

Я хочу, чтобы пользователи могли создавать офисный документ, который содержит эту информацию, а также некоторый другой текст. Я посмотрел на этот пример, который использует python-docx, и он дает мне представление о том, как сгенерировать этот документ. Но я не могу понять, где этот файл сохранен или он вообще создан. В моем шаблоне у меня есть ссылка:

<a href="{{ contact.generate_docx }}">generate .docx document</a>

где generate_docx() запускает код, который можно найти по ссылке, которую я предоставил выше.

Как я могу внедрить свою систему так, чтобы при нажатии на мою ссылку документ создавался или обновлялся на основе данных в базе данных и после этого загружался на компьютер пользователя? Не обязательно сохранять этот документ в базе данных, но мне также интересно узнать, как это сделать.

3 ответа

Вы можете использовать язык шаблонов django внутри файла docx, который на самом деле представляет собой zip-архив xml-файлов, а затем запустить соответствующий xml-файл через механизм шаблонов. Я получил идею здесь: http://reinout.vanrees.org/weblog/2012/07/04/document-automation.html

Легче сказать, чем сделать, хотя. В конце концов, я запустил его в python3 так:

from zipfile import ZipFile
from io import BytesIO

from django.template import Context, Template

def render_to_docx(docx, context):
    tmp = BytesIO()
    with ZipFile(tmp, 'w') as document_zip, ZipFile(docx) as template_zip:
        template_archive = {name: template_zip.read(name) for name in template_zip.namelist()}
        template_xml = template_archive.pop('word/document.xml')
        for n, f in template_archive.items():
            document_zip.writestr(n, f)
        t = Template(template_xml)
        document_zip.writestr('word/document.xml', t.render(Context(context)))        
    return tmp

И в представлении:

response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
response['Content-Disposition'] = 'attachment; filename=document.docx'
zipfile = render_to_docx('template.docx'), context_dictionary)
response.write(zipfile.getvalue())
return response

Вы можете создать свой файл.docx, используя Py2docx ( https://github.com/rafaels88/py2docx). Поместите свой код в представление, и после этого вы можете сделать это:

# Here goes the Py2docx code
# After save the .docx file, do this:

file_docx = open("path/file.docx", 'r')
response = HttpResponse(mimetype='text/html')
response['Content-Disposition'] = 'attachment; filename=file_name.docx'
response['Content-Encoding'] = 'UTF-8'
response['Content-type'] = 'text/html; charset=UTF-8'
response.write(file_docx.read())
file_docx.close()
return response

Затем создайте ссылку на HTML на URL вашего представления.

Если pdf Это также приемлемый формат, вы можете рассмотреть возможность использования django-wkhtmltopdf, Это позволит вам создать обычную страницу и преобразовать ее в pdf используя бинарную форму webkit.

Другие вопросы по тегам