使用具有通用 header/footer 和分页的 WeasyPrint 生成 PDF
Generate PDF with WeasyPrint having common header/footer and pagination
我正在使用 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,其中我可以在每个页面中包含一个常见的header/footer并添加分页。
此外,如果有人能告诉您如何包含自定义字体来生成 PDF,那将非常有帮助。我已经在 OS (Ubuntu 14.04) 中安装了字体,但它不起作用。
关于这些我在网上搜索了很多。但找不到合适的解决方案。
由于 Weasyprint 支持 CSS 分页媒体模块级别 3,简单 headers 和页脚(例如分页,就像你提到的)可以使用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')])
然而,渲染得更 复杂 headers/footers 可能会更……复杂。有些人提出了在 header 中包含一个 div 元素的方法,该元素仅为打印呈现(但我必须承认我只能使用这种方法正确呈现简单的元素):
@page {
@top-left {
content: element(pageHeader);
}
}
@media print {
#divHeader{
position: running(pageHeader);
}
}
还有另一种使用固定位置的方法,如本要点所示:https://gist.github.com/pikhovkin/5642563
当前 运行 个元素 are not supported by WeasyPrint. Nevertheless I found a way to achieve the same result using named strings:
@page {
@top-center {
content: string(title);
}
}
header {
width: 0;
height: 0;
visibility: hidden;
string-set: title content();
}
现在您可以将您的内容添加到不可见的 HTML header 元素中。
<header>Content of the header goes here</header>
我可以简单地通过使用 position: fixed
作为页眉和页脚来实现它。
首先,由于固定位置的元素在页面上不占space,因此您必须通过在页面上留出适当的边距来考虑它,例如:
@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 在 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,其中我可以在每个页面中包含一个常见的header/footer并添加分页。
此外,如果有人能告诉您如何包含自定义字体来生成 PDF,那将非常有帮助。我已经在 OS (Ubuntu 14.04) 中安装了字体,但它不起作用。
关于这些我在网上搜索了很多。但找不到合适的解决方案。
由于 Weasyprint 支持 CSS 分页媒体模块级别 3,简单 headers 和页脚(例如分页,就像你提到的)可以使用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')])
然而,渲染得更 复杂 headers/footers 可能会更……复杂。有些人提出了在 header 中包含一个 div 元素的方法,该元素仅为打印呈现(但我必须承认我只能使用这种方法正确呈现简单的元素):
@page {
@top-left {
content: element(pageHeader);
}
}
@media print {
#divHeader{
position: running(pageHeader);
}
}
还有另一种使用固定位置的方法,如本要点所示:https://gist.github.com/pikhovkin/5642563
当前 运行 个元素 are not supported by WeasyPrint. Nevertheless I found a way to achieve the same result using named strings:
@page {
@top-center {
content: string(title);
}
}
header {
width: 0;
height: 0;
visibility: hidden;
string-set: title content();
}
现在您可以将您的内容添加到不可见的 HTML header 元素中。
<header>Content of the header goes here</header>
我可以简单地通过使用 position: fixed
作为页眉和页脚来实现它。
首先,由于固定位置的元素在页面上不占space,因此您必须通过在页面上留出适当的边距来考虑它,例如:
@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
规则实施它们。