pdf xhtml2pdf 中的图像输出失败

image output failed in pdf 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 路径字符串,但在图像中没有。我错过了什么吗?请帮帮我。我已经被困了好几个小时了。

Xhtmltopdf 不使用 "real" css 规则。您的背景图片必须是 pdf 格式。尝试将 '/media/image/mainbg.jpg' 转换为 pdf 并使用 background-image: url('/media/image/mainbg.pdf').

问题是 xhtml2pdf 无法找到这些图像,除非您定义一个 link_callback 函数来定义静态和媒体文件的路径。

这个函数在 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)

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

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

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

在我删除之前,我一直在为类似的问题苦苦挣扎:

<pdf:pagecount>

试试看

回答晚了,但上面的 none 为我解决了。

以下是为我解决问题的方法:

将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