[PYTHON] Ausgabe Django Detailansicht als PDF (japanische Unterstützung)

Dies ist eine Methode zum Ausgeben japanischer PDF-Dateien mit Generic DetailView in Django.

Ich möchte PDF aus der HTML-Vorlage ausgeben, daher verwende ich eine Bibliothek namens xhtml2pdf. Bitte beachten Sie, dass nur die Dev-Version mit Python3 funktioniert.

pip3 install --pre xhtml2pdf

Bereiten Sie zunächst die japanische Schriftart vor, die Sie verwenden möchten. Platzieren Sie dann die Schriftart in "<prj_name> / <prj_name> / static / fonts". Übergeben Sie nach der Installation den Pfad zu settings.py.

prj_name/prj_name/settings.py


BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, '<prj_name>', 'static')

Als nächstes werde ich eine Ansicht schreiben. Dieses Mal wird beispielsweise die Detailansicht des Modells Foo von foo_app ( <prj_name> / foos) als PDF ausgegeben. Verwenden Sie generic.DetailView, um nur den Teil render_to_response zu überschreiben.

prj_name/foos/views.py


import io
import os
from django.conf import settings
from django.views import generic
from django.http import HttpResponse
from django.template.loader import get_template
from xhtml2pdf import pisa

class FooPDFView(generic.DetailView):
    model = Foo
    template_name = 'foos/pdf.html'

    def render_to_response(self, context):
        html = get_template(self.template_name).render(self.get_context_data())
        result = io.BytesIO()
        pdf = pisa.pisaDocument(
            io.BytesIO(html.encode('utf-8')),
            result,
            link_callback=link_callback,
            encoding='utf-8',
        )

        if not pdf.err:
            return HttpResponse(
                result.getvalue(),
                content_type='application/pdf'
            )

        return HttpResponse('<pre>%s</pre>' % escape(html))

def link_callback(uri, rel):
    sUrl = settings.STATIC_URL
    sRoot = settings.STATIC_ROOT
    path = os.path.join(sRoot, uri.replace(sUrl, ""))

    if not os.path.isfile(path):
        raise Exception(
            '%s must start with %s' % \
            (uri, sUrl)
        )

    return path

Ich werde eine Vorlage schreiben. Bitte beachten Sie, dass Japanisch nicht wie erwartet angezeigt wird, wenn Sie die Schriftart nicht festlegen.

prj_name/foos/templates/foos/pdf.html


<!DOCTYPE html>{% load static %}
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <style type="text/css">
    @font-face {
      font-family: "japanese";
      src: url("{% static 'fonts/<your_font>.ttf' %}");
    }
    @page {
      size: A4;
      font-family: "japanese";
    }
    html, body {
      font-family: "japanese";
    }
  </style>
</head>
<body>
  <div>
Name{{ object.name }}
  </div>
</body>
</html>

URLs festlegen.

prj_name/foos/urls.py


app_name = 'foos'
urlpatterns = [
    url(r'^(?P<pk>[0-9]+)/pdf/$',views.FooPDFView.as_view(), name='foo-pdf'),
]

Gehen Sie die Projekt-URLs durch.

prj_name/prj_name/urls.py


urlpatterns = [
    url(r'^foos/', include('foos.urls')),
]

Wenn Sie jetzt auf / foos /: foo_id / pdf zugreifen, sollten Sie ein PDF erhalten.

Recommended Posts

Ausgabe Django Detailansicht als PDF (japanische Unterstützung)
Django funktionsbasierte Ansicht
Django klassenbasierte Ansicht
Die Geschichte, die Japan ausgab, wurde mit Django verwechselt