我的 multi-page 迭代 PDF 转换器应该使用哪种 XSLT:FO 布局?
What XSLT:FO layout should I use for my multi-page iterative PDF converter?
我正在使用 Apache 的 XML Graphics FOP 2.6 创建一个至少包含 2 页的 PDF 文档。没有最大页数。
每一页都使用完全相同的header。
第1页(见附件)
需要包含带有总框数的文本,总框数中包含的项目总数以及具有 1、2 或 3 行的 table。每行都有一张盒子的照片、它的名字和它包含的物品数量。至少会有一个盒子包含至少一件物品。
第 2 页
仅当有 4 个或更多个框时才存在,并且它包含第 1 页 table 的第 4、5、6、7、8 和 9 行(共 6 行)。如果有更多比 9 (= 3 + 6 X 1) 个框,需要有一个新页面将包含第 2 页的布局,但包含框 10,...,15 的行。将遵循此模式直到最后一个盒子.
第 3 页
将包含第一个盒子的照片、姓名和物品数量。下面会有一个table,一行包含列名,最多4行,对应第一个框的前4项。
第 4 页
如果第一个框有超过 4 个项目,将有新页面,称为第 4 页,仅包含 table 的延续,包括带有列名称的行。它总共有 7 个项目,如果第一个框有超过 11(= 4 + 7 X 1)个项目,则紧随其后的是另一页。以此类推,直到所有项目结束。
第5页(不附,以免重复)
将遵循与第 3 页相同的逻辑,但在本例中为第二个框,如果有第二个框。以此类推,直到所有框结束。
任何人都可以帮助我了解如何根据我的要求在 XSL 文件中构建 layout-master-set 吗?我不是在寻找完整的解决方案。仅针对一般布局结构。答案不必太详细或太定制以满足我的需要。如果需要我可以调整它。
<xsl:template match="/doc">
<xsl:variable name="Logo"><xsl:value-of select="Logo"/></xsl:variable>
...
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"
font-family="Nexus Sans Pro" font-weight="normal">
<fo:layout-master-set>
<fo:simple-page-master master-name="Boxes-A4" page-width="297mm" page-height="210mm"
margin-top="0mm" margin-bottom="0mm" margin-left="0mm" margin-right="0mm">
<fo:region-body region-name="xsl-region-body"/>
<fo:region-before region-name="xsl-region-before" extent="70mm"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="Items-A4" page-width="297mm" page-height="210mm"
margin-top="0mm" margin-bottom="0mm" margin-left="0mm" margin-right="0mm">
<fo:region-body region-name="xsl-region-body"/>
<fo:region-before region-name="xsl-region-before" extent="70mm"/>
</fo:simple-page-master>
</fo:layout-master-set>
我已经尝试了上面的代码(使用 xsl:stylesheet version="1.0"),但未能适当地安排内容。 table 中不适合页面的行不会显示在下一页上,即使我用 break-before="page" aka page-break-before= 标记适当的行“总是”。
作为帮助,我可以将后端数据结构中的索引插入到库使用的参数中,这样我就知道每个元素的索引。
非常感谢。
Page 1
Page 2
Page 3
Page 4
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/doc">
<fo:root font-family="Nexus Sans Pro" font-weight="normal">
<fo:layout-master-set>
<fo:simple-page-master master-name="Boxes-A4" page-width="297mm" page-height="210mm"
margin-top="0mm" margin-bottom="0mm" margin-left="0mm" margin-right="0mm">
<fo:region-body region-name="xsl-region-body"/>
<fo:region-before region-name="xsl-region-before" extent="70mm"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="Items-A4" page-width="297mm" page-height="210mm"
margin-top="0mm" margin-bottom="0mm" margin-left="0mm" margin-right="0mm">
<fo:region-body region-name="xsl-region-body"/>
<fo:region-before region-name="xsl-region-before" extent="70mm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:call-template name="boxes-template"/>
<xsl:call-template name="items-template"/>
</fo:root>
</xsl:template>
<xsl:template name="boxes-template">
<fo:page-sequence master-reference="Boxes-A4" font-family="Nexus Sans Pro" font-weight="normal">
<fo:static-content flow-name="xsl-region-before">
<fo:block-container border-bottom-width="1pt"
border-bottom-style="solid"
border-bottom-color="rgb(220,220,220)"
position="absolute" top="1mm" left="5mm" right="5mm" height="60mm">
<xsl:variable name="Logo" select="Logo"/>
<fo:block-container
background-image="url({$Logo})"
top="5mm" left="5mm" width="50mm" height="50mm"
background-repeat="no-repeat"
fox:background-image-width="50mm" fox:background-image-height="50mm"
absolute-position="absolute">
<fo:block/>
</fo:block-container>
<xsl:variable name="Stamp" select="Stamp"/>
<fo:block-container
background-image="url({$Stamp})"
top="5mm" right="5mm" width="50mm" height="50mm"
background-repeat="no-repeat"
fox:background-image-width="50mm" fox:background-image-height="50mm"
absolute-position="absolute">
<fo:block/>
</fo:block-container>
<fo:block-container position="absolute" top="8mm" left="80mm" width="120mm" height="42mm">
<fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="100%"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell height="12mm">
<fo:block font-family="Nexus Sans Pro Bold"
text-align="center" font-size="32pt"> Header Text
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell display-align="after" height="10mm">
<fo:block font-family="Nexus Sans Pro"
display-align="after" text-align="center" font-size="32pt"
color="rgb(233,113,28)">
<xsl:value-of select="user"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
<fo:block-container position="absolute" top="48mm" left="77mm" width="157mm" height="10mm">
<fo:table table-layout="fixed" width="100%">
<fo:table-body>
<fo:table-row>
<fo:table-cell height="10mm">
<fo:block font-family="Nexus Sans Pro" font-weight="normal" font-size="15pt"
color="rgb(128,128,128)">
From:
<xsl:value-of select="fromDate"/>
</fo:block>
</fo:table-cell>
<fo:table-cell height="10mm">
<fo:block font-family="Nexus Sans Pro" font-weight="normal" font-size="15pt"
color="rgb(128,128,128)">
To:
<xsl:value-of select="toDate"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
</fo:block-container>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<fo:block-container position="absolute" top="75mm" left="110mm" width="120mm" height="20mm">
<fo:table table-layout="fixed" width="100%">
<fo:table-column column-number="1" column-width="50%"/>
<fo:table-column column-number="2" column-width="50%"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell height="10mm">
<fo:block
font-family="Nexus Sans Pro Bold"
font-size="15pt" color="rgb(35,31,32)">
Total number of boxes:
</fo:block>
</fo:table-cell>
<fo:table-cell height="10mm">
<fo:block font-family="Nexus Sans Pro Bold"
font-size="15pt" color="rgb(35,31,32)">
<xsl:value-of select="totalNumberOfBoxes"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell height="10mm">
<fo:block font-family="Nexus Sans Pro Bold"
font-size="15pt" color="rgb(35,31,32)">
Total number of items:
</fo:block>
</fo:table-cell>
<fo:table-cell height="10mm">
<fo:block font-family="Nexus Sans Pro Bold"
font-size="15pt" color="rgb(35,31,32)">
<xsl:value-of select="totalNumberOfItems"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
<xsl:for-each select="/doc/box">
<xsl:variable name="boxImageURL" select="boxImageURL"/>
<fo:block-container position="absolute" top="105mm" left="30mm" width="220mm" height="26mm">
<fo:table table-layout="fixed" width="100%">
<fo:table-column column-number="1" column-width="15%"/>
<fo:table-column column-number="2" column-width="70%"/>
<fo:table-column column-number="3" column-width="15%"/>
<fo:table-body>
<fo:table-row page-break-inside="auto"
border-top-width="1pt"
border-top-style="solid"
border-top-color="rgb(220,220,220)"
margin-bottom="2mm"
height="24mm">
<fo:table-cell>
<xsl:if test="$boxImageURL != 'null'">
<fo:block-container
background-image="url({$boxImageURL})"
top="110mm" right="15mm" width="15mm" height="20mm"
background-repeat="no-repeat" margin-top="2mm"
fox:background-image-width="15mm" fox:background-image-height="20mm">
<fo:block/>
</fo:block-container>
</xsl:if>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="boxTitle"/>
</fo:block>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="numberOfItems"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</xsl:template>
<xsl:template name="items-template">
<xsl:variable name="Logo"><xsl:value-of select="Logo"/></xsl:variable>
<xsl:variable name="Stamp"><xsl:value-of select="Stamp"/></xsl:variable>
<xsl:variable name="user"><xsl:value-of select="user"/></xsl:variable>
<xsl:variable name="fromDate"><xsl:value-of select="fromDate"/></xsl:variable>
<xsl:variable name="toDate"><xsl:value-of select="toDate"/></xsl:variable>
<xsl:for-each select="/doc/box">
<xsl:variable name="boxImageURL" select="boxImageURL"/>
<fo:page-sequence master-reference="Items-A4" font-family="Nexus Sans Pro" font-weight="normal">
<fo:static-content flow-name="xsl-region-before">
... Same header as on the Box-A4
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<fo:block-container page-break-before="always"
position="absolute" top="70mm" left="30mm" width="220mm" height="24mm">
<fo:table page-break-before="always" table-layout="fixed" width="100%">
<fo:table-column column-number="1" column-width="15%"/>
<fo:table-column column-number="2" column-width="85%"/>
<fo:table-body>
<fo:table-row margin-bottom="2mm"
height="22mm">
<fo:table-cell>
<xsl:if test="$boxImageURL != 'null'">
<fo:block-container
background-image="url({$boxImageURL})"
top="110mm" right="15mm" width="15mm" height="20mm"
background-repeat="no-repeat" margin-top="2mm"
fox:background-image-width="15mm" fox:background-image-height="20mm">
<fo:block/>
</fo:block-container>
</xsl:if>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block margin-top="4mm" text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="boxTitle"/>
<fo:block margin-top="4mm" text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="numberOfThings"/> things
</fo:block>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
<fo:block-container position="absolute" top="100mm" left="30mm" width="220mm" height="24mm">
<fo:table page-break-before="always" table-layout="fixed" width="100%">
<fo:table-column column-number="1" column-width="60%"/>
<fo:table-column column-number="2" column-width="15%"/>
<fo:table-column column-number="3" column-width="25%"/>
<fo:table-body>
<fo:table-row border-top-width="1pt"
border-top-style="solid"
border-top-color="rgb(220,220,220)"
margin-bottom="2mm"
height="22mm">
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
Item title
</fo:block>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
Revision
</fo:block>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
Date completed
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
<fo:block-container position="absolute" top="125mm" left="30mm" width="220mm" height="24mm">
<fo:table page-break-before="always" table-layout="fixed" width="100%">
<fo:table-column column-number="1" column-width="60%"/>
<fo:table-column column-number="2" column-width="15%"/>
<fo:table-column column-number="3" column-width="25%"/>
<fo:table-body>
<xsl:for-each select="items/item">
<fo:table-row keep-together.within-page="always"
break-after="page"
border-top-width="1pt"
border-top-style="solid"
border-top-color="rgb(220,220,220)"
margin-bottom="2mm"
height="22mm">
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="itemTitle"/>
</fo:block>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="revision"/>
</fo:block>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="dateCompleted"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block-container>
</fo:flow>
</fo:page-sequence>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我的简化parameters.xml(缺少几行):
<doc>
<Logo>ELogo.jpg</Logo>
<Stamp>Stamp.jpg</Stamp>
<backgroundImageURL>bkg.jpg</backgroundImageURL>
<user>John Richard Edgar Bowens-Robins III</user>
<fromDate>1st March 2021</fromDate>
<toDate>31 November 2021</toDate>
<totalNumberOfBoxes>5</totalNumberOfBoxes>
<totalNumberOfItems>19</totalNumberOfItems>
<box>
<boxImageURL>box1.jpg</boxImageURL>
<boxTitle>JREBR's Box 1</boxTitle>
<items>
<item>
<itemTitle>The Nice Item 11</itemTitle>
</item>
<item>
<itemTitle>The Nice Item 12</itemTitle>
</item>
<item>
<itemTitle>The Nice Item 13</itemTitle>
</item>
</items>
</box>
<box>
<boxImageURL>box2.jpg</boxImageURL>
<boxTitle>JREBR's Box 2</boxTitle>
<items>
<item>
<itemTitle>The Nice Item 21</itemTitle>
</item>
<item>
<itemTitle>The Nice Item 22</itemTitle>
</item>
<item>
<itemTitle>The Nice Item 23</itemTitle>
</item>
</items>
</box>
</doc>
使用 fo:table
,并为每个 fo:table-row
指定 height
(https://www.w3.org/TR/xsl11/#height) 和一个 suitable 值,这将使您获得所需的数量每页行数。
您可能还需要指定 keep-together.within-page="always"
以避免破坏 table 行。 FOP 在 fo:table-row
(或 fo:table-cell
)上可能支持也可能不支持。
你所谓的“第 1 页”、“第 2 页”……你的意思是这样的:
第 1 部分是所有框。这可能是 1 到 x 页,具体取决于盒子的数量。所有页面模板都相同,因此这是一个页面序列和一个页面母版。
第 2 到第 n 部分是列出所有项目的每个框的页面序列。所有这些页面序列都是相同的(一个简单的页面母版)。
您没有解释 header 中的照片 1 和照片 2 是什么,但我认为它们在每一页上都是相同的。如果这不是真的并且“盒子”和“物品”不同,那么您可能有不同的 headers.
所以你只有两个 simple-page-masters 一个叫做“盒子”,一个叫做“物品”。您只需为框创建引用 simple-page-master 的“框”page-sequence。您没有提供样本 XML,所以为了简单起见,我们只说它看起来像这样:
<order>
<box>
<name>Box 1</name>
<items>
<item>Item 1:1</item>
<item>Item 1:2</item>
<item>Item 1:3</item>
</items>
</box>
<box>
<name>Box 2</name>
<items>
<item>Item 2:1</item>
<item>Item 2:2</item>
<item>Item 2:3</item>
</items>
</box>
<box>
<name>Box 3</name>
<items>
<item>Item 3:1</item>
<item>Item 3:2</item>
<item>Item 3:3</item>
</items>
</box>
</order>
然后这个简单的 XSL 会为这些盒子和这些盒子中的项目抛出页面:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="boxes" page-width="7in" page-height="4in">
<fo:region-body region-name="body" margin-top="0.5in" margin-bottom="0.5in" margin-left="0.5in" margin-right="0.5in"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="items" page-width="7n" page-height="4in">
<fo:region-body region-name="body" margin-top="0.5in" margin-bottom="0.5in" margin-left="0.5in" margin-right="0.5in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:call-template name="boxes"/>
<xsl:call-template name="items"/>
</fo:root>
</xsl:template>
<xsl:template name="boxes">
<fo:page-sequence master-reference="boxes">
<fo:flow flow-name="body">
<!-- Output the table of boxes -->
<xsl:for-each select="/order/box">
<fo:block>
<xsl:value-of select="name"/>
</fo:block>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</xsl:template>
<xsl:template name="items">
<xsl:for-each select="/order/box">
<fo:page-sequence master-reference="items">
<fo:flow flow-name="body">
<xsl:for-each select="items/item">
<fo:block>
<xsl:value-of select="."/>
</fo:block>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这导致:
将此与@Tony Graham 关于制作表格的建议相结合,您便拥有了整个布局。如果您想知道它如何与自动页面流一起工作,这里是上面的确切示例,其中包含更多框和一个框(框 4),其中包含更多项目……我只将 fo:block font-size 更改为导致分页。
我正在使用 Apache 的 XML Graphics FOP 2.6 创建一个至少包含 2 页的 PDF 文档。没有最大页数。
每一页都使用完全相同的header。
第1页(见附件)
需要包含带有总框数的文本,总框数中包含的项目总数以及具有 1、2 或 3 行的 table。每行都有一张盒子的照片、它的名字和它包含的物品数量。至少会有一个盒子包含至少一件物品。
第 2 页
仅当有 4 个或更多个框时才存在,并且它包含第 1 页 table 的第 4、5、6、7、8 和 9 行(共 6 行)。如果有更多比 9 (= 3 + 6 X 1) 个框,需要有一个新页面将包含第 2 页的布局,但包含框 10,...,15 的行。将遵循此模式直到最后一个盒子.
第 3 页
将包含第一个盒子的照片、姓名和物品数量。下面会有一个table,一行包含列名,最多4行,对应第一个框的前4项。
第 4 页
如果第一个框有超过 4 个项目,将有新页面,称为第 4 页,仅包含 table 的延续,包括带有列名称的行。它总共有 7 个项目,如果第一个框有超过 11(= 4 + 7 X 1)个项目,则紧随其后的是另一页。以此类推,直到所有项目结束。
第5页(不附,以免重复)
将遵循与第 3 页相同的逻辑,但在本例中为第二个框,如果有第二个框。以此类推,直到所有框结束。
任何人都可以帮助我了解如何根据我的要求在 XSL 文件中构建 layout-master-set 吗?我不是在寻找完整的解决方案。仅针对一般布局结构。答案不必太详细或太定制以满足我的需要。如果需要我可以调整它。
<xsl:template match="/doc">
<xsl:variable name="Logo"><xsl:value-of select="Logo"/></xsl:variable>
...
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"
font-family="Nexus Sans Pro" font-weight="normal">
<fo:layout-master-set>
<fo:simple-page-master master-name="Boxes-A4" page-width="297mm" page-height="210mm"
margin-top="0mm" margin-bottom="0mm" margin-left="0mm" margin-right="0mm">
<fo:region-body region-name="xsl-region-body"/>
<fo:region-before region-name="xsl-region-before" extent="70mm"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="Items-A4" page-width="297mm" page-height="210mm"
margin-top="0mm" margin-bottom="0mm" margin-left="0mm" margin-right="0mm">
<fo:region-body region-name="xsl-region-body"/>
<fo:region-before region-name="xsl-region-before" extent="70mm"/>
</fo:simple-page-master>
</fo:layout-master-set>
我已经尝试了上面的代码(使用 xsl:stylesheet version="1.0"),但未能适当地安排内容。 table 中不适合页面的行不会显示在下一页上,即使我用 break-before="page" aka page-break-before= 标记适当的行“总是”。 作为帮助,我可以将后端数据结构中的索引插入到库使用的参数中,这样我就知道每个元素的索引。
非常感谢。
Page 1
Page 2
Page 3
Page 4
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/doc">
<fo:root font-family="Nexus Sans Pro" font-weight="normal">
<fo:layout-master-set>
<fo:simple-page-master master-name="Boxes-A4" page-width="297mm" page-height="210mm"
margin-top="0mm" margin-bottom="0mm" margin-left="0mm" margin-right="0mm">
<fo:region-body region-name="xsl-region-body"/>
<fo:region-before region-name="xsl-region-before" extent="70mm"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="Items-A4" page-width="297mm" page-height="210mm"
margin-top="0mm" margin-bottom="0mm" margin-left="0mm" margin-right="0mm">
<fo:region-body region-name="xsl-region-body"/>
<fo:region-before region-name="xsl-region-before" extent="70mm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:call-template name="boxes-template"/>
<xsl:call-template name="items-template"/>
</fo:root>
</xsl:template>
<xsl:template name="boxes-template">
<fo:page-sequence master-reference="Boxes-A4" font-family="Nexus Sans Pro" font-weight="normal">
<fo:static-content flow-name="xsl-region-before">
<fo:block-container border-bottom-width="1pt"
border-bottom-style="solid"
border-bottom-color="rgb(220,220,220)"
position="absolute" top="1mm" left="5mm" right="5mm" height="60mm">
<xsl:variable name="Logo" select="Logo"/>
<fo:block-container
background-image="url({$Logo})"
top="5mm" left="5mm" width="50mm" height="50mm"
background-repeat="no-repeat"
fox:background-image-width="50mm" fox:background-image-height="50mm"
absolute-position="absolute">
<fo:block/>
</fo:block-container>
<xsl:variable name="Stamp" select="Stamp"/>
<fo:block-container
background-image="url({$Stamp})"
top="5mm" right="5mm" width="50mm" height="50mm"
background-repeat="no-repeat"
fox:background-image-width="50mm" fox:background-image-height="50mm"
absolute-position="absolute">
<fo:block/>
</fo:block-container>
<fo:block-container position="absolute" top="8mm" left="80mm" width="120mm" height="42mm">
<fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="100%"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell height="12mm">
<fo:block font-family="Nexus Sans Pro Bold"
text-align="center" font-size="32pt"> Header Text
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell display-align="after" height="10mm">
<fo:block font-family="Nexus Sans Pro"
display-align="after" text-align="center" font-size="32pt"
color="rgb(233,113,28)">
<xsl:value-of select="user"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
<fo:block-container position="absolute" top="48mm" left="77mm" width="157mm" height="10mm">
<fo:table table-layout="fixed" width="100%">
<fo:table-body>
<fo:table-row>
<fo:table-cell height="10mm">
<fo:block font-family="Nexus Sans Pro" font-weight="normal" font-size="15pt"
color="rgb(128,128,128)">
From:
<xsl:value-of select="fromDate"/>
</fo:block>
</fo:table-cell>
<fo:table-cell height="10mm">
<fo:block font-family="Nexus Sans Pro" font-weight="normal" font-size="15pt"
color="rgb(128,128,128)">
To:
<xsl:value-of select="toDate"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
</fo:block-container>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<fo:block-container position="absolute" top="75mm" left="110mm" width="120mm" height="20mm">
<fo:table table-layout="fixed" width="100%">
<fo:table-column column-number="1" column-width="50%"/>
<fo:table-column column-number="2" column-width="50%"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell height="10mm">
<fo:block
font-family="Nexus Sans Pro Bold"
font-size="15pt" color="rgb(35,31,32)">
Total number of boxes:
</fo:block>
</fo:table-cell>
<fo:table-cell height="10mm">
<fo:block font-family="Nexus Sans Pro Bold"
font-size="15pt" color="rgb(35,31,32)">
<xsl:value-of select="totalNumberOfBoxes"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell height="10mm">
<fo:block font-family="Nexus Sans Pro Bold"
font-size="15pt" color="rgb(35,31,32)">
Total number of items:
</fo:block>
</fo:table-cell>
<fo:table-cell height="10mm">
<fo:block font-family="Nexus Sans Pro Bold"
font-size="15pt" color="rgb(35,31,32)">
<xsl:value-of select="totalNumberOfItems"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
<xsl:for-each select="/doc/box">
<xsl:variable name="boxImageURL" select="boxImageURL"/>
<fo:block-container position="absolute" top="105mm" left="30mm" width="220mm" height="26mm">
<fo:table table-layout="fixed" width="100%">
<fo:table-column column-number="1" column-width="15%"/>
<fo:table-column column-number="2" column-width="70%"/>
<fo:table-column column-number="3" column-width="15%"/>
<fo:table-body>
<fo:table-row page-break-inside="auto"
border-top-width="1pt"
border-top-style="solid"
border-top-color="rgb(220,220,220)"
margin-bottom="2mm"
height="24mm">
<fo:table-cell>
<xsl:if test="$boxImageURL != 'null'">
<fo:block-container
background-image="url({$boxImageURL})"
top="110mm" right="15mm" width="15mm" height="20mm"
background-repeat="no-repeat" margin-top="2mm"
fox:background-image-width="15mm" fox:background-image-height="20mm">
<fo:block/>
</fo:block-container>
</xsl:if>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="boxTitle"/>
</fo:block>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="numberOfItems"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</xsl:template>
<xsl:template name="items-template">
<xsl:variable name="Logo"><xsl:value-of select="Logo"/></xsl:variable>
<xsl:variable name="Stamp"><xsl:value-of select="Stamp"/></xsl:variable>
<xsl:variable name="user"><xsl:value-of select="user"/></xsl:variable>
<xsl:variable name="fromDate"><xsl:value-of select="fromDate"/></xsl:variable>
<xsl:variable name="toDate"><xsl:value-of select="toDate"/></xsl:variable>
<xsl:for-each select="/doc/box">
<xsl:variable name="boxImageURL" select="boxImageURL"/>
<fo:page-sequence master-reference="Items-A4" font-family="Nexus Sans Pro" font-weight="normal">
<fo:static-content flow-name="xsl-region-before">
... Same header as on the Box-A4
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<fo:block-container page-break-before="always"
position="absolute" top="70mm" left="30mm" width="220mm" height="24mm">
<fo:table page-break-before="always" table-layout="fixed" width="100%">
<fo:table-column column-number="1" column-width="15%"/>
<fo:table-column column-number="2" column-width="85%"/>
<fo:table-body>
<fo:table-row margin-bottom="2mm"
height="22mm">
<fo:table-cell>
<xsl:if test="$boxImageURL != 'null'">
<fo:block-container
background-image="url({$boxImageURL})"
top="110mm" right="15mm" width="15mm" height="20mm"
background-repeat="no-repeat" margin-top="2mm"
fox:background-image-width="15mm" fox:background-image-height="20mm">
<fo:block/>
</fo:block-container>
</xsl:if>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block margin-top="4mm" text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="boxTitle"/>
<fo:block margin-top="4mm" text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="numberOfThings"/> things
</fo:block>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
<fo:block-container position="absolute" top="100mm" left="30mm" width="220mm" height="24mm">
<fo:table page-break-before="always" table-layout="fixed" width="100%">
<fo:table-column column-number="1" column-width="60%"/>
<fo:table-column column-number="2" column-width="15%"/>
<fo:table-column column-number="3" column-width="25%"/>
<fo:table-body>
<fo:table-row border-top-width="1pt"
border-top-style="solid"
border-top-color="rgb(220,220,220)"
margin-bottom="2mm"
height="22mm">
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
Item title
</fo:block>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
Revision
</fo:block>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
Date completed
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block-container>
<fo:block-container position="absolute" top="125mm" left="30mm" width="220mm" height="24mm">
<fo:table page-break-before="always" table-layout="fixed" width="100%">
<fo:table-column column-number="1" column-width="60%"/>
<fo:table-column column-number="2" column-width="15%"/>
<fo:table-column column-number="3" column-width="25%"/>
<fo:table-body>
<xsl:for-each select="items/item">
<fo:table-row keep-together.within-page="always"
break-after="page"
border-top-width="1pt"
border-top-style="solid"
border-top-color="rgb(220,220,220)"
margin-bottom="2mm"
height="22mm">
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="itemTitle"/>
</fo:block>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="revision"/>
</fo:block>
</fo:table-cell>
<fo:table-cell display-align="center" height="20mm">
<fo:block text-align="left" font-size="16pt" color="rgb(35,31,32)">
<xsl:value-of select="dateCompleted"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block-container>
</fo:flow>
</fo:page-sequence>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我的简化parameters.xml(缺少几行):
<doc>
<Logo>ELogo.jpg</Logo>
<Stamp>Stamp.jpg</Stamp>
<backgroundImageURL>bkg.jpg</backgroundImageURL>
<user>John Richard Edgar Bowens-Robins III</user>
<fromDate>1st March 2021</fromDate>
<toDate>31 November 2021</toDate>
<totalNumberOfBoxes>5</totalNumberOfBoxes>
<totalNumberOfItems>19</totalNumberOfItems>
<box>
<boxImageURL>box1.jpg</boxImageURL>
<boxTitle>JREBR's Box 1</boxTitle>
<items>
<item>
<itemTitle>The Nice Item 11</itemTitle>
</item>
<item>
<itemTitle>The Nice Item 12</itemTitle>
</item>
<item>
<itemTitle>The Nice Item 13</itemTitle>
</item>
</items>
</box>
<box>
<boxImageURL>box2.jpg</boxImageURL>
<boxTitle>JREBR's Box 2</boxTitle>
<items>
<item>
<itemTitle>The Nice Item 21</itemTitle>
</item>
<item>
<itemTitle>The Nice Item 22</itemTitle>
</item>
<item>
<itemTitle>The Nice Item 23</itemTitle>
</item>
</items>
</box>
</doc>
使用 fo:table
,并为每个 fo:table-row
指定 height
(https://www.w3.org/TR/xsl11/#height) 和一个 suitable 值,这将使您获得所需的数量每页行数。
您可能还需要指定 keep-together.within-page="always"
以避免破坏 table 行。 FOP 在 fo:table-row
(或 fo:table-cell
)上可能支持也可能不支持。
你所谓的“第 1 页”、“第 2 页”……你的意思是这样的:
第 1 部分是所有框。这可能是 1 到 x 页,具体取决于盒子的数量。所有页面模板都相同,因此这是一个页面序列和一个页面母版。
第 2 到第 n 部分是列出所有项目的每个框的页面序列。所有这些页面序列都是相同的(一个简单的页面母版)。
您没有解释 header 中的照片 1 和照片 2 是什么,但我认为它们在每一页上都是相同的。如果这不是真的并且“盒子”和“物品”不同,那么您可能有不同的 headers.
所以你只有两个 simple-page-masters 一个叫做“盒子”,一个叫做“物品”。您只需为框创建引用 simple-page-master 的“框”page-sequence。您没有提供样本 XML,所以为了简单起见,我们只说它看起来像这样:
<order>
<box>
<name>Box 1</name>
<items>
<item>Item 1:1</item>
<item>Item 1:2</item>
<item>Item 1:3</item>
</items>
</box>
<box>
<name>Box 2</name>
<items>
<item>Item 2:1</item>
<item>Item 2:2</item>
<item>Item 2:3</item>
</items>
</box>
<box>
<name>Box 3</name>
<items>
<item>Item 3:1</item>
<item>Item 3:2</item>
<item>Item 3:3</item>
</items>
</box>
</order>
然后这个简单的 XSL 会为这些盒子和这些盒子中的项目抛出页面:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="boxes" page-width="7in" page-height="4in">
<fo:region-body region-name="body" margin-top="0.5in" margin-bottom="0.5in" margin-left="0.5in" margin-right="0.5in"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="items" page-width="7n" page-height="4in">
<fo:region-body region-name="body" margin-top="0.5in" margin-bottom="0.5in" margin-left="0.5in" margin-right="0.5in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:call-template name="boxes"/>
<xsl:call-template name="items"/>
</fo:root>
</xsl:template>
<xsl:template name="boxes">
<fo:page-sequence master-reference="boxes">
<fo:flow flow-name="body">
<!-- Output the table of boxes -->
<xsl:for-each select="/order/box">
<fo:block>
<xsl:value-of select="name"/>
</fo:block>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</xsl:template>
<xsl:template name="items">
<xsl:for-each select="/order/box">
<fo:page-sequence master-reference="items">
<fo:flow flow-name="body">
<xsl:for-each select="items/item">
<fo:block>
<xsl:value-of select="."/>
</fo:block>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这导致:
将此与@Tony Graham 关于制作表格的建议相结合,您便拥有了整个布局。如果您想知道它如何与自动页面流一起工作,这里是上面的确切示例,其中包含更多框和一个框(框 4),其中包含更多项目……我只将 fo:block font-size 更改为导致分页。