如何将Reportlab与基于Django类的视图合并? [英] How to incorporate Reportlab with Django Class Based View?

查看:101
本文介绍了如何将Reportlab与基于Django类的视图合并?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将HTML转换为PDF。我观看了本教程 https://www.codingforentrepreneurs。 com / blog / html-template-to-pdf-in-django / 中,我就能够成功获得该教程以使用硬编码值。问题是...我无法弄清楚如何动态地将我的模型及其属性合并到此示例中。



这是我遵循的步骤...



首先,我使用以下版本将reportlab安装到我的环境中...

 点安装--pre xhtml2pdf 

这可行...



然后我按照指示将utils.py文件添加到我的项目中。



然后我将此代码复制到utils.py文件中...

  from io从django.io导入BytesIO 
.http从django.template.loader导入HttpResponse
导入get_template

从xhtml2pdf导入比萨

def render_to_pdf(template_src, context_dict = {}):
模板= get_template(template_src)
html = template.render(context_dict)
结果= BytesIO()
pdf = pisa.pisaDocument(BytesIO(html .encode( ISO-8859-1)),结果)
如果不是pdf.err:
返回HttpResponse(result.getvalue(),content_type ='application / pdf')
返回无

然后,我创建了一个如下所示的HTML文件:

 <!DOCTYPE HTML PUBLIC-// W3C / / DTD HTML 4.01 Transitional // EN http://www.w3.org/TR/html4/loose.dtd\"> 
< html>
< head>
< title>标题< / title>
< style type = text / css>
body {
font-weight:200;
font-size:14px;
}
.header {
font-size:20px;
字体粗细:100;
text-align:center;
颜色:#007cae;
}
.title {
font-size:22px;
字体粗细:100;
/ * text-align:right; * /
padding:10px 20px 0px 20px;
}
.title span {
color:#007cae;
}
.details {
padding:10px 20px 0px 20px;
text-align:left!important;
/ * margin-left:40%; * /
}
.hrItem {
border:none;
高度:1像素;
/ *设置小时颜色* /
颜色:#333; / *旧版IE * /
background-color:#fff; / *现代浏览器* /
}
< / style>
< / head>
< body>
< div class ='包装器'>
< div class = header>
< p class =’title’>发票编号< / p>
< / div>
< div>
< div class ='details'>
帐单发送至:{{customer_name}}< br />
金额:{{金额}}< br />
日期:
< hr class = hrItem />
< / div>
< / div>
< / body>
< / html>

我还创建了必要的URL...。



然后我创建了一个类似于以下定义的视图:



from django.http import HttpResponse
从django.views.generic导入查看

从yourproject.utils导入render_to_pdf#在步骤4中创建的

类GeneratePdf(View):
def get(self,请求,* args,** kwargs):
data = {
'today':datetime.date.today(),
'amount':39.99,
'customer_name' :'Cooper Mann',
'order_id':1233434,
}
pdf = render_to_pdf('pdf / invoice.html',数据)
return HttpResponse(pdf,content_type = 'application / pdf')

当我单击指向该视图的链接时...输出显示就像教程中说的那样...



但是,如果我试图让我的模型以这种格式显示...我很困惑那。我尝试了一个DetailView...。然后我得到了数据,但没有PDF...。我也搜索了许多其他地方,但似乎找不到一个可以动态获取模型并提取模型的示例。

解决方案

如果要使用 DetailView ,我想您可以这样做:

  class SomeDetailView(DetailView): 
模型= YourModel
template_name ='pdf / invoice.html'

def get_context_data(self,** kwargs):
context = super(SomeDetailView,self) .get_context_data(** kwargs)
#如果需要可以添加额外的上下文
返回上下文

def render_to_response(self,context,** kwargs):
pdf = render_to_pdf (self.template_name,context)
return HttpResponse(pdf,content_type ='application / pdf')

此处我要覆盖 render_to_response 覆盖DetailView的默认响应以返回PDF响应。在这里,进入的上下文来自 get_context_data 。在 get_context_data 中,可以根据需要添加任何其他上下文。


I am trying to convert my HTML to a PDF. I watched this tutorial, https://www.codingforentrepreneurs.com/blog/html-template-to-pdf-in-django/ and I was able to successfully get the tutorial to work with hardcoded values. The problem is...I can't figure out how to dynamically incorporate my model and it's attributes into this example.

Here are the steps I followed...

First I installed reportlab into my environment with the following version...

pip install --pre xhtml2pdf 

This worked...

Then I added a utils.py file to my project as instructed.

Then I copied this code into my utils.py file...

from io import BytesIO
from django.http import HttpResponse
from django.template.loader import get_template

from xhtml2pdf import pisa

def render_to_pdf(template_src, context_dict={}):
    template = get_template(template_src)
    html  = template.render(context_dict)
    result = BytesIO()
    pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result)
    if not pdf.err:
        return HttpResponse(result.getvalue(), content_type='application/pdf')
    return None

Then I created an HTML file like the one below:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>Title</title>
        <style type="text/css">
            body {
                font-weight: 200;
                font-size: 14px;
            }
            .header {
                font-size: 20px;
                font-weight: 100;
                text-align: center;
                color: #007cae;
            }
            .title {
                font-size: 22px;
                font-weight: 100;
               /* text-align: right;*/
               padding: 10px 20px 0px 20px;  
            }
            .title span {
                color: #007cae;
            }
            .details {
                padding: 10px 20px 0px 20px;
                text-align: left !important;
                /*margin-left: 40%;*/
            }
            .hrItem {
                border: none;
                height: 1px;
                /* Set the hr color */
                color: #333; /* old IE */
                background-color: #fff; /* Modern Browsers */
            }
        </style>
    </head>
    <body>
        <div class='wrapper'>
            <div class='header'>
                <p class='title'>Invoice # </p>
            </div>
        <div>
        <div class='details'>
            Bill to: {{ customer_name }} <br/>
            Amount: {{ amount }} <br/>
            Date: 
            <hr class='hrItem' />
        </div>
    </div>
    </body>
</html>

I also created the necessary URL....

Then I created a view similar to what is defined below:

from django.http import HttpResponse
from django.views.generic import View

from yourproject.utils import render_to_pdf #created in step 4

class GeneratePdf(View):
    def get(self, request, *args, **kwargs):
        data = {
             'today': datetime.date.today(), 
             'amount': 39.99,
            'customer_name': 'Cooper Mann',
            'order_id': 1233434,
        }
        pdf = render_to_pdf('pdf/invoice.html', data)
        return HttpResponse(pdf, content_type='application/pdf')

When I click on my link to this view...the output shows just like the tutorial says...

However, if I am trying to get my model to display in this format...I'm stumped as to how to do that. I tried a DetailView....and then I get the data but no PDF....I've also searched many other places and I can't seem to find an example that would allow me to get my model dynamically and pull in attributes as needed...Thanks in advance for any help or pointers.

解决方案

If you want to use DetailView, I think you can do it like this:

class SomeDetailView(DetailView):
    model = YourModel
    template_name = 'pdf/invoice.html'

    def get_context_data(self, **kwargs):
        context = super(SomeDetailView, self).get_context_data(**kwargs)
        # add extra context if needed
        return context

    def render_to_response(self, context, **kwargs):
        pdf = render_to_pdf(self.template_name, context)
        return HttpResponse(pdf, content_type='application/pdf')

Here I am overriding render_to_response to override the default response from DetailView to return a PDF response. Here, the context that comes in are from get_context_data. in get_context_data you can add any extra context if needed.

这篇关于如何将Reportlab与基于Django类的视图合并?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆