使用xhtml2pdf将unicode模板转换为pdf时出现问题

时间:2013-08-23 02:16:25

标签: python unicode flask xhtml2pdf

我的html页面中使用了unicode,它在html页面中正确显示。但是在使用xhtml2pdf将其转换为html时,它会在unicodes中生成黑色实心方框。是否有UTF-8设置以外的unicode设置。我不认为它的unicode问题。

# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
        StringIO(sourceHtml.encode('utf-8')),                 
        dest=resultFile)

完整的py代码:

# -*- coding: utf-8 -*-

from xhtml2pdf import pisa
from StringIO import StringIO

source = """<html>
            <style>
                @font-face {
                font-family: Preeti;
                src: url("preeti.ttf");
                }

                body {
                font-family: Preeti;
                }
            </style>
            <body>
                This is a test <br/>
                       सरल
            </body>
        </html>"""

# Utility function
def convertHtmlToPdf(source):
    # open output file for writing (truncated binary)

    pdf = StringIO()
    pisaStatus = pisa.CreatePDF(StringIO(source.encode('utf-8')), pdf)

    # return True on success and False on errors
    print "Success: ", pisaStatus.err
    return pdf

# Main program
if __name__=="__main__":
    print pisa.showLogging()
    pdf = convertHtmlToPdf(source)
    fd = open("test.pdf", "w+b")
    fd.write(pdf.getvalue())
    fd.close()

generated pdf file

我是否需要包含font-face ??

4 个答案:

答案 0 :(得分:4)

部分解决了。提供字体的绝对路径,即

    <style>
        @font-face {
        font-family: Preeti;
        src: url("c:/static/fonts/preeti.ttf");
        }

        body {
        font-family: Preeti;
        }
    </style>  

现在又出现了另一个问题。我有混合文本,部分在unicode和部分正常字体(我想我应该说它是普通字体:D),因为字体已被覆盖,现在正常的字体是在矩形框中。在这种情况下一个空盒子。

答案 1 :(得分:1)

有点迟到但我认为重要的是要知道为什么相对路径在fontface中不能用于xhtml2pdf:

CreatePDF函数(与https://github.com/chrisglass/xhtml2pdf/blob/master/xhtml2pdf/pisa.py中可见的pisaDocument方法相同)具有path命名参数。现在,如果您没有设置此参数并使用相对路径,那么它将尝试在名为__dummy__的文件夹下找到您的字体,如文件https://github.com/chrisglass/xhtml2pdf/blob/master/xhtml2pdf/context.py所示(搜索虚设)。

因此,当您使用绝对路径时,这就是您的.ttf个文件的原因。

要解决此问题,您可以:

  • 创建一个__dummy__文件夹并将.ttf个文件放在那里,或
  • 将值传递给path命名参数CreatePDF

例如,就我而言,我正在通过django创建PDF,所以我通过了path='.'并将我的.ttf放入与我的manage.py相同的相同的文件夹中 - - 一切都很好。更好的解决方案是定义SETTINGS.PROJECT_PATH并使用它。

答案 2 :(得分:0)

the documentation开始,看起来您应该给CreatePDF编码,否则“这是HTML5解析器猜到的。”

因此,请说HTML文件的标题指定了Devanagari使用的任何遗留字符集。在您向我们展示的代码之前,您可以将其正确解码为Unicode,然后将其重新编码为UTF-8,但标头指定了不同的字符集。在这种情况下,html5lib将猜测错误的字符集,并错误地解释字符并给你mojibake。

当然,如果没有一个完整的例子,我无法确定你面临的问题是什么,但它可能像那样。最可能的解决方案是相同的:如果你编码为UTF-8,告诉转换器使用UTF-8而不是猜测:

pisaStatus = pisa.CreatePDF(
    StringIO(sourceHtml.encode('utf-8')),                 
    dest=resultFile,
    encoding='utf-8')

答案 3 :(得分:0)

使用xhtml2pdf和pisa将html转换为pdf时,我的pdf中有一个黑盒子字符。原来我在文档中有一个BOM(字节顺序标记)字符。

可以通过在大多数文本编辑器中执行“另存为”来删除BOM。在UltraEdit中,我选择了另存为...并选择了UTF-8类型(无BOM)。

请参阅: How do I remove the BOM character from my xml file