使用具有通用页眉/页脚和分页的 WeasyPrint 生成 PDF

Posted

技术标签:

【中文标题】使用具有通用页眉/页脚和分页的 WeasyPrint 生成 PDF【英文标题】:Generate PDF with WeasyPrint having common header/footer and pagination 【发布时间】:2017-02-17 21:54:00 【问题描述】:

我正在使用 Wea​​syPrint 在 Django 中生成 PDF。我可以从如下所示的静态 html 文件生成 pdf -

from django.template import Context, Template
import weasyprint

with open('static_file.html', 'r') as myfile:
    html_str = myfile.read()

template = Template(html_message)
    context = Context('some_key': 'some_value')
    rendered_str = template.render(context)

weasyprint.HTML(string=rendered_str).write_pdf('generated.pdf')

但我想生成一个 PDF,我可以在每个页面中包含一个通用的页眉/页脚并添加分页。

如果有人能告诉如何包含自定义字体来生成 PDF,这将非常有帮助。我已经在操作系统(Ubuntu 14.04)中安装了字体,但它不工作。

我在网上搜索了很多关于这些的内容。但找不到合适的解决方案。

【问题讨论】:

【参考方案1】:

由于 Weasyprint 支持 CSS Paged Media Module Level 3,简单页眉和页脚(例如分页,就像你提到的那样)可以使用 CSS 完成:

@page 
    @top-right
        content: "Page " counter(page) " of " counter(pages);
    

确保在渲染时包含样式表:

HTML(string=rendered_html,
     base_url=settings.SITE_URL).write_pdf(stylesheets=[CSS(settings.STATIC_ROOT + '/css/pdf_render.css')])

然而,让更多复杂页眉/页脚呈现可能会更......复杂。有人建议在标题中包含一个仅用于打印的 div 元素的方法(但我必须承认,我只能使用这种方法获得简单的元素以正确呈现):

@page 
    @top-left 
        content: element(pageHeader);
    

@media print 
    #divHeader
        position: running(pageHeader);
    

还有另一种使用固定位置的方法,如本要点所示:https://gist.github.com/pikhovkin/5642563

【讨论】:

使用命令行可执行文件,您可以将 CSS 保存在一个文件中,然后使用 -s 标志传递它:weasyprint https://www.somepage.org printed.pdf -s pagination.css【参考方案2】:

当前运行元素are not supported by WeasyPrint。尽管如此,我还是找到了一种使用named strings 实现相同结果的方法:

 @page 
   @top-center 
     content:  string(title);
   
 

 header 
   width: 0;
   height: 0;
   visibility: hidden;
   string-set: title content();

现在您可以将内容添加到不可见的 HTML 标头元素中。

<header>Content of the header goes here</header>

【讨论】:

还是不支持多行【参考方案3】:

我可以通过使用 position: fixed 作为页眉和页脚来实现这一点。

首先,由于位置固定的元素不会占用页面空间,因此您必须通过在页面上提供适当的边距来考虑它,例如:

@page 
    margin: 5cm 0 3cm 0;
    size: A4;

然后简单地相对于这个边距定位页眉和页脚:

header, footer 
    position: fixed;
    left: 0;
    right: 0;

header 
    /* subtract @page margin */
    top: 5cm;
    height: 5cm

footer 
    /* subtract @page margin */
    bottom: 3cm;
    height: 3cm;

有了这个,您可以在&lt;header&gt;&lt;footer&gt; 元素中放置任意HTML,它们将在每个页面上重复。

页面计数器似乎在那里不起作用,因此您需要根据其他答案中所述的@page 规则来实现它们。

【讨论】:

以上是关于使用具有通用页眉/页脚和分页的 WeasyPrint 生成 PDF的主要内容,如果未能解决你的问题,请参考以下文章

reportlab 中的多行(段落)页脚和页眉

PHP Wiletize页眉,页脚和其他所有使用论文的钩子

在单个单元格中显示页眉页脚和单元格?

带有 % extends 的每页上的 Django 页脚和页眉

已解决WPS2018 从第三页开始插入页眉页码(即前两页不要页眉页码)

在 Google Web Toolkit (GWT) 中实现页眉、页脚和菜单栏