본문 바로가기
Programming

Django pdf 사용하는 방법 feat. xhtml2pdf module

by 하하호호 2021. 10. 6.
반응형

 

 

 

 

xhtml2pdf 설치

pip install xhtml2pdf

weasyprint 모듈과는 다르게,

기본 모듈만 설치해주면,

개발자가 추가적인 종속성을 

설정해주거나,

추가적인 모듈을 설치해주지 않아도

pdf 출력 기능을 사용할 수 있다.

 

 

 

xhtml2pdf 모듈 사용하기

 

Django pdf 사용하는 방법은

먼저 필요한 모듈을 import 한다.

 

 

import os
from django.conf import settings
from django.http import HttpResponse
from django.template.loader import get_template
from xhtml2pdf import pisa
from django.contrib.staticfiles import finders

#new class
from django.veiws.generic import ListView
from .models import Person

class Person(ListView):
    person = Person
    template_name = 'test.html'
        
def person_render_pdf_view(request, *args):
    pk = args.get('pk')
    person = get_object_or_400(Person, pk=pk)

    template_path = 'user_printer2.html'
    context = {'myvar': 'this is your template context'}
    # Create a Django response object, and specify content_type as pdf
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="report.pdf"'
    # find the template and render it.
    template = get_template(template_path)
    html = template.render(context)

    # create a pdf
    pisa_status = pisa.CreatePDF(
    html, dest=response, link_callback=link_callback)
    # if error then show some funy view
    if pisa_status.err:
    return HttpResponse('We had some errors <pre>' + html + '</pre>')
    return response

def link_callback(uri, rel):
    """
    Convert HTML URIs to absolute system paths so xhtml2pdf can access those
    resources
    """
    result = finders.find(uri)
    if result:
    if not isinstance(result, (list, tuple)):
    result = [result]
    result = list(os.path.realpath(path) for path in result)
    path=result[0]
    else:
    sUrl = settings.STATIC_URL        # Typically /static/
    sRoot = settings.STATIC_ROOT      # Typically /home/userX/project_static/
    mUrl = settings.MEDIA_URL         # Typically /media/
    mRoot = settings.MEDIA_ROOT       # Typically /home/userX/project_static/media/

    if uri.startswith(mUrl):
    path = os.path.join(mRoot, uri.replace(mUrl, ""))
    elif uri.startswith(sUrl):
    path = os.path.join(sRoot, uri.replace(sUrl, ""))
    else:
    return uri

    # make sure that file exists
    if not os.path.isfile(path):
    raise Exception(
    'media URI must start with %s or %s' % (sUrl, mUrl)
    )
    return path
def render_pdf_view(request):
    template_path = 'user_printer.html'
    context = {'myvar': 'this is your template context'}
    # Create a Django response object, and specify content_type as pdf
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="report.pdf"'
    # find the template and render it.
    template = get_template(template_path)
    html = template.render(context)

    # create a pdf
    pisa_status = pisa.CreatePDF(
    html, dest=response, link_callback=link_callback)
    # if error then show some funy view
    if pisa_status.err:
    return HttpResponse('We had some errors <pre>' + html + '</pre>')
    return response

앱 폴더의 views.py에서 render_pdf_view()를 정의해주고,

template_path="test.html" test.html를 새로 만들어준다.

test.html에 context 데이터를 보내주어, 렌더링을

진행한다.

 

 

 

클래스 이용하기

 

listView 모듈을 사용해서,

models.py에 저장된 클래스를 가지고 와서,

모델링 데이터를 가져올 수 있다.

 

listView는 제네릭 뷰의 정보를

HTML로 object_list로 보내주기 때문에,

모델링 속성값들을 정리해주면 된다.

 

pdf가 출력되는 html페이지에서

{{person}}으로 가지고 와서

렌더링을 해주면 된다.

 

 

 

반응형

댓글