【问题标题】:image output failed in pdf xhtml2pdfpdf xhtml2pdf中的图像输出失败
【发布时间】:2015-01-07 07:29:05
【问题描述】:

我的视图设置如下:

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 路径字符串,但不是图像。我是不是错过了什么。请帮帮我。我已经被困了几个小时了。

【问题讨论】:

  • 我自己想通了。我太着急了,我想我只是复制并粘贴代码sinppet。很抱歉给您带来了困扰。

标签: django xhtml2pdf


【解决方案1】:

问题是 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)

【讨论】:

  • 我在这一行 rendering = pisa.pisaDocument(StringIO.StringIO(html.encode("ISO-8859-1")), result, link_callback=link_callback) 中收到此错误 global name link_callback is not defined。我已经完全按照你说的定义了函数link_callback。
  • PDFTemplateView 类中的link_callback 是否可以让get 访问该函数?
  • 是的,在课堂上。我遵循了文档,但我收到了该错误。我找到了一个对我有用的解决方案,即从类中删除 link_callback() 函数并定义硬编码的媒体 URL。但我仍然想知道是什么导致了这个错误。我遵循了文档中的所有说明。
  • link_callback 是一个函数,它告诉 xhtml2pdf 在哪里可以找到您的静态和媒体文件(只要 url 在 settings.py 中正确)。请注意,模块文档有错误,但我尝试了我发布的解决方案并且没有问题。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 您好,谢谢您的回答。但这并没有做任何事情。我还是卡住了!
    • 我记得我也被这个问题困扰过...试试background-image: url(/media/image/mainbg.pdf) 不带引号。
    • 我已经这样做了,有无引号。你还记得你是怎么熬过来的吗??
    • 我的模板 (doc.html) 代码是 @page { background-image: url({{ bgpdf }}); size: ... },我使用 render 和参数 {'bgpdf':'path/to/doc.pdf'} 调用它。我会做两件事:首先尝试以 html 格式呈现视图以确保文档的路径正确,然后尝试引用本机 pdf 文件以确保格式正确。我还在我的代码中注释了 link_callback=fetch_resource。
    • 谢谢你的回答。让我试试,我会回复你的
    【解决方案4】:

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

    <pdf:pagecount>
    

    试试看

    【讨论】:

      【解决方案5】:

      迟到的答案,但以上都没有为我解决。

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

      在 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-03
        • 1970-01-01
        • 2021-10-14
        • 2016-05-22
        • 1970-01-01
        • 1970-01-01
        • 2017-07-11
        • 2016-01-27
        相关资源
        最近更新 更多