XSL-FO 不同 header/footer 取决于 page-position

XSL-FO Different header/footer depending on page-position

这可能是 XSL-FO 的一个很常见的问题:我尝试建立一个具有明确规范的账单:

  1. "Main Header":在每一页上(文本、徽标和条形码)
  2. "Sub Header":(客户数据)

    -> 在第一页上,此块应约为页面高度的 10%

    -> 在所有其他页面上,这个块应该小一半左右,所以假设 5%

  3. "Last-Page Footer": 就在课程的最后一页(总数和签名)

  4. "Every-page Footer": 仅供打印日期

  5. "Body":计费内容(每个位置)应自动在所有 header 和页脚之间流动

所以我知道有些点可以通过使用属性来实现 page-position:

<fo:page-sequence-master master-name="masterSequenceName1">
<fo:repeatable-page-master-alternatives>
  <fo:conditional-page-master-reference master-reference="masterNamePageFirst1" page-position="first"></fo:conditional-page-master-reference>
  <fo:conditional-page-master-reference master-reference="masterNamePageLast1"  page-position="last"></fo:conditional-page-master-reference>
  <fo:conditional-page-master-reference master-reference="masterNamePageAny"    page-position="any"></fo:conditional-page-master-reference>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>

我可以为每个案例定义区域,但遇到以下问题:

  1. 如果第一页是最后一页(只有一页),则不会出现最后一页页脚。知道 page-position 可以有值 "only",也可以为此设置一个 static-content。但是我仍然会有两个相同内容的块,每当我想编辑这部分时,我都必须更改它两次。
  2. 主要的 header 通常可以通过 region-before 参考 page-position="any" (这是标准)来设置,但不知何故这不会'不适合我。我只是在不是第一个或最后一个页面上得到 header。这实际上不应该是 page-position="rest" 所需的功能吗?

page-position 属性 定义中的注释指出(强调):

Several of these values can be true simultaneously; for example, 'any' is always true and 'only' is true when both 'first' and 'last' are true. For that reason, it is necessary to order the fo:conditional-page-master-references so that the least inclusive test is performed before the more inclusive test which are also true.

换句话说,被选为建立页面的conditional-page-master-reference第一个条件为真的,后面的引用甚至都没有被考虑考虑。

要记住的另一个重点是条件 (page-position, odd-or-even, blank-or-not-blank) select 一个页面母版,而不是特定的静态内容.

所以,看看你的问题:

1. If the first page is the last ( only one page), the last page footer won't appear.

发生这种情况是因为第一个 conditional-page-master-reference 适用于第一页也是唯一的页面,在您的示例中,指向 "masterNamePageFirst1" 的那个(我猜,因为它不在问题中)有一个区域-之后只有 "every page footer" 被映射。

Knowing that page-position can have the value "only", a possiblity would be to set a static-content for this, too. But still I would have two blocks of the same content and whenever I wanted to edit this part, I would have to change it twice.

您不必重复两次相同的内容:您可以将其放入命名模板,然后从两个静态内容中调用该模板。

2. The main header normally can be set by a region-before with a reference to page-position="any" (which is the standard), but somehow this won't work for me. I'm just getting the header at pages which aren't first or last. Shouldn't this actually be the desired function of page-position="rest"?

静态内容映射到一个区域:检查第一页和最后一页的页面母版中是否实际存在该区域

编辑:完成示例

这里是一个示例,显示 不同的页面几何结构 only/first/rest/any 页面和 不同的 headers/footers 根据页面位置 使用 fo:markers and fo:retrieve-markers.

我用 FOP 1.1 测试过,生成的 pdf 应该符合您的规格。

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <fo:layout-master-set>
        <fo:simple-page-master master-name="singlePage" margin="1cm">
            <fo:region-body margin-top="5cm" margin-bottom="4cm" background-color="#FFFFAA"/>
            <fo:region-before extent="4cm" background-color="#AAFFFF"/>
            <fo:region-after extent="3cm" background-color="#FFAAFF" display-align="after"/>
        </fo:simple-page-master>
        <fo:simple-page-master master-name="firstPage" margin="1cm">
            <fo:region-body margin-top="5cm" margin-bottom="2cm" background-color="#FFFFAA"/>
            <fo:region-before extent="4cm" background-color="#AAFFFF"/>
            <fo:region-after extent="1cm" background-color="#FFAAFF" display-align="after"/>
        </fo:simple-page-master>
        <fo:simple-page-master master-name="middlePage" margin="1cm">
            <fo:region-body margin-top="2cm" margin-bottom="2cm" background-color="#FFFFAA"/>
            <fo:region-before extent="1cm" background-color="#AAFFFF"/>
            <fo:region-after extent="1cm" background-color="#FFAAFF" display-align="after"/>
        </fo:simple-page-master>
        <fo:simple-page-master master-name="lastPage" margin="1cm">
            <fo:region-body margin-top="2cm" margin-bottom="4cm" background-color="#FFFFAA"/>
            <fo:region-before extent="1cm" background-color="#AAFFFF"/>
            <fo:region-after extent="3cm" background-color="#FFAAFF" display-align="after"/>
        </fo:simple-page-master>
        <fo:page-sequence-master master-name="allPages">
            <fo:repeatable-page-master-alternatives>
                <fo:conditional-page-master-reference page-position="only" master-reference="singlePage"/>
                <fo:conditional-page-master-reference page-position="first" master-reference="firstPage"/>
                <fo:conditional-page-master-reference page-position="rest" master-reference="middlePage"/>
                <fo:conditional-page-master-reference page-position="last" master-reference="lastPage"/>
            </fo:repeatable-page-master-alternatives>
        </fo:page-sequence-master>
    </fo:layout-master-set>
    <fo:page-sequence master-reference="allPages">
        <!--
            header
        -->
        <fo:static-content flow-name="xsl-region-before" font-size="90%">
            <!-- main header on every page -->
            <fo:block>Text, logo, barcode</fo:block>
            <!-- sub header -->
            <fo:retrieve-marker retrieve-class-name="subHeader" retrieve-position="first-starting-within-page"/>
        </fo:static-content>
        <!--
            footer
        -->
        <fo:static-content flow-name="xsl-region-after" font-size="90%">
            <!-- special footer -->
            <fo:retrieve-marker retrieve-class-name="footer" retrieve-position="first-starting-within-page"/>
            <!-- common footer on every page -->
            <fo:block>printing date dd/mm/yyyy</fo:block>
        </fo:static-content>
        <!--
            document body
        -->
        <fo:flow flow-name="xsl-region-body">
            <!-- empty blocks with markers for the header -->
            <fo:block>
                <!-- sub header for the first page -->
                <fo:marker marker-class-name="subHeader">
                    <fo:block>LARGE SUB HEADER</fo:block>
                </fo:marker>
            </fo:block>
            <fo:block>
                <!-- sub header for the not-first pages -->
                <fo:marker marker-class-name="subHeader">
                    <fo:block>small sub header</fo:block>
                </fo:marker>
            </fo:block>
            <!-- normal content -->
            <!-- 
                YOUR REAL CONTENT GOES HERE 
                (I just put some blocks with page breaks to produce a few pages)
            -->
            <fo:block break-after="page">Long sequence with many pages ...</fo:block>
            <fo:block break-after="page">... bla bla bla ...</fo:block>
            <fo:block>... the end</fo:block>
            <!-- empty block with marker for the footer -->
            <fo:block>
                <!-- footer for the last page -->
                <fo:marker marker-class-name="footer">
                    <fo:block>TOTAL AMOUNT $$$ AND SIGNATURES</fo:block>
                </fo:marker>
            </fo:block>
       </fo:flow>
    </fo:page-sequence>
</fo:root>