图像输出在pdf xhtml2pdf中失败

时间:2015-01-07 07:29:06

标签: django xhtml2pdf

我的观点设置如下:

views.py

class PDFTemplateView(TemplateView):
    Model = TemplateInfo
    template_name = 'hello.html'


    def get(self, *args, **kwargs):
        obj = self.Model.objects.get(id = kwargs['pk'])

        html  = get_template(self.template_name).render(Context({'object' : obj}))

        result = StringIO.StringIO()
        rendering = pisa.pisaDocument(StringIO.StringIO(html.encode("ISO-8859-1")), result)

        if not rendering.err:
            return HttpResponse(result.getvalue(), mimetype='application/pdf')
        return HttpResponse('We had some errors<pre>%s</pre>' % escape(html))

我找到了一个解决这个问题的解决方案,它具有fetch_resource()函数的定义,但这并没有帮助我。我阅读了文档,没有这个功能我感觉更好。

这是我的模板“hello.html”

<style type="text/css">

@page {
    background-image: url('/media/image/mainbg.jpg'); #this wouldnot give image too
    size: letter portrait;

    @frame header_frame {           /* Static Frame */
        -pdf-frame-content: header_content;
        left: 50pt; width: 512pt; top: 50pt; height: 40pt;
        -pdf-frame-border: 1;    /* for debugging the layout */
    }
    @frame content_frame {          /* Content Frame */
        left: 50pt; width: 512pt; top: 90pt; height: 632pt;
        -pdf-frame-border: 1;    /* for debugging the layout */
    }
    @frame footer_frame {           /* Another static Frame */
        -pdf-frame-content: footer_content;
        left: 50pt; width: 512pt; top: 772pt; height: 20pt;
        -pdf-frame-border: 1;    /* for debugging the layout */
    }

 </style>
 </head>
<div id="header_content">Lyrics-R-Us</div>

<div id="footer_content">(c) - page <pdf:pagenumber>
    of <pdf:pagecount>
</div>

<ul>
    <li>{{ object.emp_name }}</li>
    <li>{{ object.designation }}</li>
    <li>{{ object.image.url }}</li>
</ul>

到目前为止,一切似乎都很好。但是我无法在pdf中获得图像。这个{{ object.image.url}}给了我一个pdf中的fie路径字符串,但不是图像。我错过了什么。请帮帮我。我已经被困了几个小时了。

5 个答案:

答案 0 :(得分:1)

问题是除非你定义了一个定义静态和媒体文件路径的link_callback函数,否则xhtml2pdf找不到这些图像。

此功能位于xhtml2pdf文档中:

def link_callback(uri, rel):
    # use short variable names
    sUrl = settings.STATIC_URL      # Typically /static/
    sRoot = settings.STATIC_ROOT    # Typically /home/userX/project_static/
    mUrl = settings.MEDIA_URL       # Typically /static/media/
    mRoot = settings.MEDIA_ROOT     # Typically /home/userX/project_static/media/

    # convert URIs to absolute system paths
    if uri.startswith(mUrl):
        path = os.path.join(mRoot, uri.replace(mUrl, ""))
    elif uri.startswith(sUrl):
        path = os.path.join(sRoot, uri.replace(sUrl, ""))

    # 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

确保定义link_callback函数中的所有路径(STATIC_URL ...等)。然后,当您渲染文档时,请包含link_callback,如下所示:

rendering = pisa.pisaDocument(StringIO.StringIO(html.encode("ISO-8859-1")), result, link_callback=link_callback)

答案 1 :(得分:0)

Xhtmltopdf不使用&#34;真实&#34; css规则。您的背景图片必须是pdf格式。尝试转换&#39; /media/image/mainbg.jpg'到pdf并使用background-image: url('/media/image/mainbg.pdf')

答案 2 :(得分:0)

我遇到了同样的问题。请检查设置中的STATIC_ROOT,因为它应指向存储静态文件的位置。

django-easy-pdf无法找到您的资产(图片,css等),直到您将它们指向STATIC_ROOT。

https://github.com/nigma/django-easy-pdf/blob/master/docs/usage.rst

答案 3 :(得分:0)

我一直在努力解决类似的问题,直到我删除:

<pdf:pagecount>

试一试

答案 4 :(得分:0)

最新答案,但以上都不为我解决。

这是为我解决问题的方法:

在settings.py中将STATIC_ROOT定义为:

os.path.abspath('collected-static/')

另一个难题是,编写link_callback函数的方式必须定义MEDIA_URL,因为MEDIA_URL的默认值为“”,它与每个URI的开头都匹配。

定义MEDIA_URL或重写link_callback函数以首先检查静态链接:

def link_callback(uri, rel):
    # use short variable names
    sUrl = settings.STATIC_URL      # Typically /static/
    sRoot = settings.STATIC_ROOT    # Typically /home/userX/project_static/
    mUrl = settings.MEDIA_URL       # Typically "" if not defined in settings.py
    mRoot = settings.MEDIA_ROOT     # Typically /home/userX/project_static/media/

    # convert URIs to absolute system paths
    if uri.startswith(sUrl):
        # Replaces 'static/image.png' with 'c:\\my-project\\collected-static/image.png'
        path = os.path.join(sRoot, uri.replace(sUrl, ""))
    elif uri.startswith(mUrl):
        # MEDIA_URL default value is "" so everything matches this
        path = os.path.join(mRoot, uri.replace(mUrl, ""))

    # 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