[PYTHON] Afficher la vue détaillée de Django au format PDF (prise en charge du japonais)

Il s'agit d'une méthode pour générer un PDF japonais à l'aide de Generic DetailView dans Django.

Je veux produire un PDF à partir d'un modèle html, j'utilise donc une bibliothèque appelée xhtml2pdf. Veuillez noter que seule la version de développement fonctionne avec python3.

pip3 install --pre xhtml2pdf

Tout d'abord, préparez la police japonaise que vous souhaitez utiliser. Placez ensuite la police dans <prj_name> / <prj_name> / static / fonts. Après l'installation, transmettez le chemin à 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')

Ensuite, j'écrirai une vue. Cette fois, à titre d'exemple, la vue détaillée du modèle Foo de foo_app ( <prj_name> / foos) est sortie au format PDF. Utilisez generic.DetailView pour remplacer uniquement la partie render_to_response.

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

J'écrirai un modèle. Veuillez noter que si vous ne définissez pas la police, le japonais ne s'affichera pas comme prévu.

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>
Nom{{ object.name }}
  </div>
</body>
</html>

Définissez les URL.

prj_name/foos/urls.py


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

Parcourez les URL du projet.

prj_name/prj_name/urls.py


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

Maintenant, lorsque vous accédez à / foos /: foo_id / pdf, vous devriez obtenir un PDF.

Recommended Posts

Afficher la vue détaillée de Django au format PDF (prise en charge du japonais)
Vue basée sur les fonctions Django
Vue basée sur les classes Django
L'histoire de la confusion entre la production japonaise et Django