使用具有通用页眉/页脚和分页的 WeasyPrint 生成 PDF
Posted
技术标签:
【中文标题】使用具有通用页眉/页脚和分页的 WeasyPrint 生成 PDF【英文标题】:Generate PDF with WeasyPrint having common header/footer and pagination 【发布时间】:2017-02-17 21:54:00 【问题描述】:我正在使用 WeasyPrint 在 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;
有了这个,您可以在<header>
和<footer>
元素中放置任意HTML,它们将在每个页面上重复。
页面计数器似乎在那里不起作用,因此您需要根据其他答案中所述的@page
规则来实现它们。
【讨论】:
以上是关于使用具有通用页眉/页脚和分页的 WeasyPrint 生成 PDF的主要内容,如果未能解决你的问题,请参考以下文章
带有 % extends 的每页上的 Django 页脚和页眉