将xhtml2pdf

时间:2019-10-24 06:19:55

标签: django django-views xhtml2pdf

我对此没有足够的经验,因此我对xhtml2pdf的{​​{3}}理解不够,因为它的细节非常模糊。请告诉我我在做什么错。

根据将相对网址路径转换为绝对值的文档,我需要使用提供的功能:

def link_callback(uri, rel):
    """
    Convert HTML URIs to absolute system paths so xhtml2pdf can access those
    resources
    """
    # 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, ""))
    else:
        return uri  # handle absolute uri (ie: http://some.tld/foo.png)

    # 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

我在views.py中添加了完全相同的功能,并使用此功能生成pdf(也在views.py中,几乎直接从文档中获取):

def PGP_result(request):

    data = request.session['form_data']

    lietuvosPgp = data['LtPGP']
    valstybe = data['pVal']
    kastai = data['iKastai']
    rezultatas = data['result']  
    today = timezone.now()

    params = {
            'LtPgp': lietuvosPgp,
            'Valstybe': valstybe,
            'Kastai': kastai,
            'Rezultatas': rezultatas,
            'today': today,
        }

    template_path = 'PGP_results_pdf.html'

    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="test.pdf"'

    template = get_template(template_path)
    html = template.render(params)

    pisaStatus = pisa.CreatePDF(
        html, dest=response, link_callback=link_callback
        )
    if pisaStatus.err:
        return HttpResponse('Ups kažkas nepavyko <pre>' + html + '</pre>')
    return response

Pdf已生成,但未使用static/fonts文件夹中的字体文件。我无法弄清楚如何正确编写相对URL路径,因此它将转换为绝对路径。我认为解决方案应该非常简单,但是由于缺乏经验,我无法找到解决方案(我厌倦了各种编写方法,但没有一种起作用)。

我的(当前)模板代码(不知道如何修复src: url(sUrl/fonts/Arial.ttf)部分):

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Test</title>
   <style type="text/css">
         @font-face {
            font-family: "Arial"; src: url(sUrl/fonts/Arial.ttf);
        }
        .container {
            font-family: "Arial"
        }
    </style>
</head>
<body>
<div class="container">
    <div class="card">
        <div class="card-header">
            <h3>Skaičiuota - {{ today | date:"d/m/Y" }}</h3>
        </div>  
        <div class="list-group">
            <p>{{ LtPgp }}</p>
            <p>{{ Valstybe }}</p>
            <p>{{ Kastai }}</p>
            <p>{{ Rezultatas }}</p>
        </div>
    </div>
</div>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

在阅读了一堆或多或少类似的问题之后,我偶然发现了建议先运行py manage.py collectstatic命令的注释。阅读并分析了`link_callback函数后,我找到了解决方法:

模板中的应该为:font-family: "Arial"; src: "static/fonts/Arial.ttf";

在我的结论中,link_callback函数检查链接的第一部分,如果发现该链接以static开头,则将其替换为目录STATIC_ROOT(绝对路径)。由于我使用Debug=True在开发服务器上工作,因此我不需要collectstatic进行其他所有操作,因此,在一切正常的情况下,link_callback的功能直接指向不存在的目录。收集所有静态信息并修复源链接后,我开始使用它。

P.S。我不是专业人士,也没有编程背景,所以如果错误,请修正我的假设(我真的想学习和了解更多)。但是,即使假设错误,代码也可以正常工作。