5.4. 带分页、页眉和页脚的 HTML/PDF 报表示例
假设要创建一个这样的报表:横向展示、每页上都显示页码和固定的页眉页脚,使用特殊的 CSS 规则和属性进行配置。输出格式是 HTML 并可以导出为 PDF。
此报表示例及其演示项目也可在 CUBA GitHub 上找到。
-
数据模型
报表将显示有关
Client
实体的信息。它包含两个 String 属性:title
和summary
,在报表结构中会使用它们。public class Client extends StandardEntity { @NotNull @Column(name = "TITLE", nullable = false) protected String title; @Lob @Column(name = "SUMMARY") protected String summary; ... }
-
创建一个没有参数的简单报表。使用 JPQL 查询所有 Client 实体的本地属性:
title
和summary
。 -
报表模板.
现在创建报表模板文件。在这里定义页眉和页脚块,页眉和页脚会在每页 PDF 都打印 。这需要使用特殊的
page-break-before
:always
CSS 属性。它会在每个 Client 信息块之前生成分页符。如下所示,使用 FreeMarker 语法将数据插入到模板中。请在此处查看完整的 FreeMarker 参考: https://freemarker.apache.org/docs/ 。
<body> <h1>Clients report</h1> <!-- Custom HTML header --> <div class="header"> Annual Report of our Company </div> <!-- Custom HTML footer --> <div class="footer"> Address: William Road </div> <#assign clients = Root.bands.Clients /> <#list clients as client> <div class="custom-page-start" style="page-break-before: always;"> <h2>Client</h2> <p>Name: ${client.fields.title}</p> <p>Summary: ${client.fields.summary}</p> </div> </#list> </body>
-
CSS 规则
将使用以下 CSS 代码来调整 PDF 页面显示:
body { font: 12pt Georgia, "Times New Roman", Times, serif; line-height: 1.3; } @page { /* switch to landscape */ size: landscape; /* set page margins */ margin: 0.5cm; @top-center { content: element(header); } @bottom-center { content: element(footer); } @bottom-right{ content: counter(page) " of " counter(pages); } }
此 CSS 代码将设置页眉/页脚位置:
div.header { display: block; text-align: center; position: running(header); width: 100%; } div.footer { display: block; text-align: center; position: running(footer); width: 100%; }
之后,需要填充主要内容的边距以防止内容和页眉/页脚重叠:
/* Fix overflow of headers and content */ body { padding-top: 50px; } .custom-page-start { margin-top: 50px; }
最终,完整的
paging-template.html
文件如下所示:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Invoice</title> <style type="text/css"> body { font: 12pt Georgia, "Times New Roman", Times, serif; line-height: 1.3; padding-top: 50px; } div.header { display: block; text-align: center; position: running(header); width: 100%; } div.footer { display: block; text-align: center; position: running(footer); width: 100%; } @page { /* switch to landscape */ size: landscape; /* set page margins */ margin: 0.5cm; @top-center { content: element(header); } @bottom-center { content: element(footer); } @bottom-right { content: counter(page) " of " counter(pages); } } .custom-page-start { margin-top: 50px; } </style> </head> <body> <h1>Clients report</h1> <!-- Custom HTML header --> <div class="header"> Annual Report of our Company </div> <!-- Custom HTML footer --> <div class="footer"> Address: William Road </div> <#assign clients = Root.bands.Clients /> <#list clients as client> <div class="custom-page-start" style="page-break-before: always;"> <h2>Client</h2> <p>Name: ${client.fields.title}</p> <p>Summary: ${client.fields.summary}</p> </div> </#list> </body> </html>
-
上传模板文件并运行报表。
正如所见,报表包含标题页、每个 Client 信息前都分页、每页都显示页眉和页脚。