使用 XSLT 生成 PDF 时,一页横向,另一页纵向

One page in landscape while others in Portrait in generating PDF using XSLT

我正在使用以下 XSLT 生成 PDF:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family = "Helvetica" font-size = "10px">
            <fo:layout-master-set>
                <fo:simple-page-master margin-bottom="0.5cm" margin-left="0.75cm" margin-right="0.75cm" margin-top="0.5cm" master-name="first" page-height="27.9cm" page-width="21.6cm">
                    <fo:region-body margin-bottom = "0.5cm" margin-top = "0.25cm"/>
                    <fo:region-before extent = "0cm"/>
                    <fo:region-after extent = "0.5cm"/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            <xsl:for-each select="Rowsets">
                <fo:page-sequence master-reference="first">
                    <fo:static-content flow-name="xsl-region-before">
                        <fo:block font-size="9pt" line-height="3pt" text-align-last="justify">

                        </fo:block>
                    </fo:static-content>
                    <fo:static-content flow-name="xsl-region-after">
                        <fo:block font-size="8pt" line-height="6pt" text-align-last="justify">
                            Report
                            <fo:inline id="Date">
                                Date [currentDate]
                            </fo:inline>
                            <fo:leader leader-pattern = "space"/>
                            Page
                            <fo:page-number/>
                        </fo:block>
                    </fo:static-content>
                    <fo:flow flow-name="xsl-region-body">
                        <xsl:for-each select="Rowset">
                            <xsl:choose>
                                <xsl:when test="position()=25">
                                    <fo:table border-color="black" border-style="solid" border-width="1pt" table-layout="fixed" width="100%">
                                        <xsl:variable name="columns">
                                            <xsl:value-of select="count(Columns/Column)" />
                                        </xsl:variable>
                                        <xsl:for-each select="Columns/Column">
                                            <xsl:choose>
                                                <xsl:when test="position()=1">
                                                    <fo:table-column column-width="30pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=2">
                                                    <fo:table-column column-width="55pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=3">
                                                    <fo:table-column column-width="32pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=5">
                                                    <fo:table-column column-width="35pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=4">
                                                    <fo:table-column column-width="60pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=8">
                                                    <fo:table-column column-width="40pt"/>
                                                </xsl:when>

                                                <xsl:when test="position()=12">
                                                    <fo:table-column column-width="100pt"/>
                                                </xsl:when>
                                                <xsl:otherwise>
                                                    <fo:table-column/>
                                                </xsl:otherwise>
                                            </xsl:choose>
                                        </xsl:for-each>
                                        <fo:table-body font-size="10pt">
                                            <fo:table-row height="13pt">
                                                <fo:table-cell background-color="#000000" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt" number-columns-spanned="{$columns}">
                                                    <fo:block font-weight="bold" text-align="center" color="#FFFFFF">
                                                        <xsl:value-of select="Columns/Column[1]/@Description" />
                                                    </fo:block>
                                                </fo:table-cell>
                                            </fo:table-row>
                                            <xsl:if test="Columns/Column[2]/@Description='true'">
                                                <fo:table-row height="13pt">
                                                    <xsl:for-each select="Columns/Column">
                                                        <fo:table-cell background-color="#CCCCCC" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt">
                                                            <fo:block font-weight="bold" text-align="left">
                                                                <xsl:value-of select="translate(@Name,'_',' ')" />
                                                            </fo:block>
                                                        </fo:table-cell>
                                                    </xsl:for-each>
                                                </fo:table-row>
                                            </xsl:if>
                                            <xsl:for-each select="Row">
                                                <fo:table-row height="13pt">
                                                    <xsl:for-each select="child::*">
                                                        <fo:table-cell background-color="#FFFFFF" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt">
                                                            <fo:block font-weight="normal" text-align="left">
                                                                <xsl:value-of select="." />
                                                            </fo:block>
                                                        </fo:table-cell>
                                                    </xsl:for-each>
                                                </fo:table-row>
                                            </xsl:for-each>
                                        </fo:table-body>
                                    </fo:table>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:choose>
                                        <xsl:when test="Columns/Column[1]/@Description = 'Break'">
                                            <fo:block page-break-before="always" />
                                        </xsl:when>
                                        <xsl:otherwise>
                                            <fo:table border-color="black" border-style="solid" border-width="1pt" table-layout="fixed" width="100%">
                                                <xsl:variable name="columns">
                                            <xsl:value-of select="count(Columns/Column)" />
                                        </xsl:variable>
                                                <xsl:for-each select="Columns/Column">
                                                    <fo:table-column />
                                                </xsl:for-each>
                                                <fo:table-body font-size="10pt">
                                                    <fo:table-row height="13pt">
                                                        <fo:table-cell background-color="#000000" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt" number-columns-spanned="{$columns}">
                                                            <fo:block font-weight="bold" text-align="center" color="#FFFFFF">
                                                                <xsl:value-of select="Columns/Column[1]/@Description" />
                                                            </fo:block>
                                                        </fo:table-cell>
                                                    </fo:table-row>
                                                    <xsl:if test="Columns/Column[2]/@Description='true'">
                                                        <fo:table-row height="13pt">
                                                            <xsl:for-each select="Columns/Column">
                                                                <fo:table-cell background-color="#CCCCCC" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt">
                                                                    <fo:block font-weight="bold" text-align="left">
                                                                        <xsl:value-of select="translate(@Name,'_',' ')" />
                                                                    </fo:block>
                                                                </fo:table-cell>
                                                            </xsl:for-each>
                                                        </fo:table-row>
                                                    </xsl:if>
                                                    <xsl:for-each select="Row">
                                                        <fo:table-row height="13pt">
                                                            <xsl:for-each select="child::*">
                                                                <fo:table-cell background-color="#FFFFFF" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt">
                                                                    <fo:block font-weight="normal" text-align="left">
                                                                        <xsl:value-of select="." />
                                                                    </fo:block>
                                                                </fo:table-cell>
                                                            </xsl:for-each>
                                                        </fo:table-row>
                                                    </xsl:for-each>
                                                </fo:table-body>
                                            </fo:table>
                                            <fo:block text-indent="2pc" space-after="7pt" space-before.minimum="6pt" space-before.optimum="8pt" space-before.maximum="10pt">
                                            </fo:block>
                                        </xsl:otherwise>
                                    </xsl:choose>
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:for-each>
                    </fo:flow>
                </fo:page-sequence>
            </xsl:for-each>
        </fo:root>
    </xsl:template>
</xsl:stylesheet>

它工作得很好。唯一的问题是对于 Rowset 25,我的列太多,看起来不太好,所以我想将方向更改为横向,只为我的 XML 的 Rowset 25,而我希望其他人为纵向。

XML 中我需要横向显示的部分如下所示:

<?xml version="1.0" encoding="utf-8" ?>

<Rowset>
    <Columns>
        <Column Description="Box Number" MaxRange="100" MinRange="0" Name="Tote" SQLDataType="1" SourceColumn="Tote"/>
        <Column Description="true" MaxRange="100" MinRange="0" Name="Status" SQLDataType="1" SourceColumn="Status"/>
        <Column Description="" MaxRange="100" MinRange="0" Name="Shift" SQLDataType="1" SourceColumn="Shift"/>
        <Column Description="" MaxRange="100" MinRange="0" Name="Lot" SQLDataType="1" SourceColumn="Lot"/>
        <Column Description="" MaxRange="100" MinRange="0" Name="Qty" SQLDataType="1" SourceColumn="Qty"/>
        <Column Description="" MaxRange="100" MinRange="0" Name="Date" SQLDataType="1" SourceColumn="Date"/>
        <Column Description="" MaxRange="100" MinRange="0" Name="User" SQLDataType="1" SourceColumn="User"/>
        <Column Description="" MaxRange="100" MinRange="0" Name="Cavity" SQLDataType="1" SourceColumn="Cavity"/>
        <Column Description="" MaxRange="100" MinRange="0" Name="Mainbody_Cavity" SQLDataType="1" SourceColumn="Mainbody_Cavity"/>
        <Column Description="" MaxRange="100" MinRange="0" Name="Canc_By" SQLDataType="1" SourceColumn="Canc_By"/>
        <Column Description="" MaxRange="100" MinRange="0" Name="Canc_On" SQLDataType="1" SourceColumn="Canc_On"/>
        <Column Description="" MaxRange="100" MinRange="0" Name="Comment" SQLDataType="1" SourceColumn="Comment"/>
    </Columns>
    <Row>
        <Tote>1</Tote>
        <Status>Inspection Stock</Status>
        <Shift>1</Shift>
        <Lot>12345678</Lot>
        <Qty>10</Qty>
        <Date>01/13/2016 09:14:26</Date>
        <User>XYZ</User>
        <Cavity>K11</Cavity>
        <Mainbody_Cavity>P11, P21, P31</Mainbody_Cavity>
        <Canc_By>ABCXYZ</Canc_By>
        <Canc_On>01/13/2016 09:20:26</Canc_On>
        <Comment>Cancelled.</Comment>
    </Row>
    <Row>
        <Tote>2</Tote>
        <Status>Inspection Stock</Status>
        <Shift>1</Shift>
        <Lot>12345678</Lot>
        <Qty>10</Qty>
        <Date>01/13/2016 09:14:26</Date>
        <User>XYZ</User>
        <Cavity>K11</Cavity>
        <Mainbody_Cavity>P11, P21, P31</Mainbody_Cavity>
        <Canc_By>ABCXYZ</Canc_By>
        <Canc_On>01/13/2016 09:20:26</Canc_On>
        <Comment>Cancelled.</Comment>
    </Row>
    <Row>
        <Tote>3</Tote>
        <Status>Inspection Stock</Status>
        <Shift>1</Shift>
        <Lot>12345678</Lot>
        <Qty>10</Qty>
        <Date>01/13/2016 09:14:26</Date>
        <User>XYZ</User>
        <Cavity>K11</Cavity>
        <Mainbody_Cavity>P11, P21, P31</Mainbody_Cavity>
        <Canc_By>ABCXYZ</Canc_By>
        <Canc_On>01/13/2016 09:20:26</Canc_On>
        <Comment>Cancelled.</Comment>
    </Row>
</Rowset>

此行集出现在第 25 位。

有可能实现吗?

谢谢!

在 Kevin 的回答后,我尝试使用以下 XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family = "Helvetica" font-size = "10px">
            <fo:layout-master-set>
                <fo:simple-page-master margin-bottom="0.5cm" margin-left="0.75cm" margin-right="0.75cm" margin-top="0.5cm" master-name="first" page-height="27.9cm" page-width="21.6cm">
                    <fo:region-body margin-bottom = "0.5cm" margin-top = "0.25cm"/>
                    <fo:region-before extent = "0cm"/>
                    <fo:region-after extent = "0.5cm"/>
                </fo:simple-page-master>
                <fo:simple-page-master margin-bottom="0.5cm" margin-left="0.75cm" margin-right="0.75cm" margin-top="0.5cm" master-name="landscape" page-height="21.6cm" page-width="27.9cm">
                    <fo:region-body margin-bottom = "0.5cm" margin-top = "0.25cm"/>
                    <fo:region-before extent = "0cm"/>
                    <fo:region-after extent = "0.5cm"/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            <xsl:for-each select="Rowsets">
                <xsl:for-each select="Rowset">
                    <xsl:choose>
                        <xsl:when test="position()=27">
                            <fo:page-sequence master-reference="landscape">
                                <fo:static-content flow-name="xsl-region-before">
                                    <fo:block font-size="9pt" line-height="3pt" text-align-last="justify">
                                        <fo:inline id="DNumber">
                                DNumber [DNumber]
                            </fo:inline>
                                        <fo:leader leader-pattern = "space"/>
                                        <fo:inline id="DNumberVersion">
                                Version [DNumberVersion]
                            </fo:inline>
                                    </fo:block>
                                </fo:static-content>
                                <fo:static-content flow-name="xsl-region-after">
                                    <fo:block font-size="8pt" line-height="6pt" text-align-last="justify">
                            Eletronic Batch Record
                            <fo:inline id="Date">
                                Date [currentDate]
                            </fo:inline>
                            <fo:leader leader-pattern = "space"/>
                            Page
                            <fo:page-number/>
                        </fo:block>
                                </fo:static-content>
                                <fo:flow flow-name="xsl-region-body">
                                    <fo:table border-color="black" border-style="solid" border-width="1pt" table-layout="fixed" width="100%">
                                        <xsl:variable name="columns">
                                            <xsl:value-of select="count(Columns/Column)" />
                                        </xsl:variable>
                                        <xsl:for-each select="Columns/Column">
                                            <xsl:choose>
                                                <xsl:when test="position()=1">
                                                    <fo:table-column column-width="30pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=2">
                                                    <fo:table-column column-width="55pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=3">
                                                    <fo:table-column column-width="32pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=4">
                                                    <fo:table-column column-width="35pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=5">
                                                    <fo:table-column column-width="55pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=6">
                                                    <fo:table-column column-width="40pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=7">
                                                    <fo:table-column column-width="35pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=8">
                                                    <fo:table-column column-width="58pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=9">
                                                    <fo:table-column column-width="55pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=10">
                                                    <fo:table-column column-width="51pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=11">
                                                    <fo:table-column column-width="55pt"/>
                                                </xsl:when>
                                                <xsl:when test="position()=12">
                                                    <fo:table-column column-width="75pt"/>
                                                </xsl:when>
                                                <xsl:otherwise>
                                                    <fo:table-column/>
                                                </xsl:otherwise>
                                            </xsl:choose>
                                        </xsl:for-each>
                                        <fo:table-body font-size="10pt">
                                            <fo:table-row height="13pt">
                                                <fo:table-cell background-color="#000000" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt" number-columns-spanned="{$columns}">
                                                    <fo:block font-weight="bold" text-align="center" color="#FFFFFF">
                                                        <xsl:value-of select="Columns/Column[1]/@Description" />
                                                    </fo:block>
                                                </fo:table-cell>
                                            </fo:table-row>
                                            <xsl:if test="Columns/Column[2]/@Description='true'">
                                                <fo:table-row height="13pt">
                                                    <xsl:for-each select="Columns/Column">
                                                        <fo:table-cell background-color="#CCCCCC" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt">
                                                            <fo:block font-weight="bold" text-align="left">
                                                                <xsl:value-of select="translate(@Name,'_',' ')" />
                                                            </fo:block>
                                                        </fo:table-cell>
                                                    </xsl:for-each>
                                                </fo:table-row>
                                            </xsl:if>
                                            <xsl:for-each select="Row">
                                                <fo:table-row height="13pt">
                                                    <xsl:for-each select="child::*">
                                                        <fo:table-cell background-color="#FFFFFF" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt">
                                                            <fo:block font-weight="normal" text-align="left">
                                                                <xsl:value-of select="." />
                                                            </fo:block>
                                                        </fo:table-cell>
                                                    </xsl:for-each>
                                                </fo:table-row>
                                            </xsl:for-each>
                                        </fo:table-body>
                                    </fo:table>
                                </fo:flow>
                            </fo:page-sequence>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:choose>
                                <xsl:when test="Columns/Column[1]/@Description = 'Break'">
                                    <fo:block page-break-before="always" />
                                </xsl:when>
                                <xsl:otherwise>
                                    <fo:page-sequence master-reference="first">
                                        <fo:static-content flow-name="xsl-region-before">
                                            <fo:block font-size="9pt" line-height="3pt" text-align-last="justify">
                                                <fo:inline id="DNumber">
                                DNumber [DNumber]
                            </fo:inline>
                                                <fo:leader leader-pattern = "space"/>
                                                <fo:inline id="DNumberVersion">
                                Version [DNumberVersion]
                            </fo:inline>
                                            </fo:block>
                                        </fo:static-content>
                                        <fo:static-content flow-name="xsl-region-after">
                                            <fo:block font-size="8pt" line-height="6pt" text-align-last="justify">
                            Eletronic Batch Record
                            <fo:inline id="Date">
                                Date [currentDate]
                            </fo:inline>
                            <fo:leader leader-pattern = "space"/>
                            Page
                            <fo:page-number/>
                        </fo:block>
                                        </fo:static-content>
                                        <fo:flow flow-name="xsl-region-body">
                                            <fo:table border-color="black" border-style="solid" border-width="1pt" table-layout="fixed" width="100%">
                                                <xsl:variable name="columns">
                                            <xsl:value-of select="count(Columns/Column)" />
                                        </xsl:variable>
                                                <xsl:for-each select="Columns/Column">
                                                    <fo:table-column />
                                                </xsl:for-each>
                                                <fo:table-body font-size="10pt">
                                                    <fo:table-row height="13pt">
                                                        <fo:table-cell background-color="#000000" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt" number-columns-spanned="{$columns}">
                                                            <fo:block font-weight="bold" text-align="center" color="#FFFFFF">
                                                                <xsl:value-of select="Columns/Column[1]/@Description" />
                                                            </fo:block>
                                                        </fo:table-cell>
                                                    </fo:table-row>
                                                    <xsl:if test="Columns/Column[2]/@Description='true'">
                                                        <fo:table-row height="13pt">
                                                            <xsl:for-each select="Columns/Column">
                                                                <fo:table-cell background-color="#CCCCCC" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt">
                                                                    <fo:block font-weight="bold" text-align="left">
                                                                        <xsl:value-of select="translate(@Name,'_',' ')" />
                                                                    </fo:block>
                                                                </fo:table-cell>
                                                            </xsl:for-each>
                                                        </fo:table-row>
                                                    </xsl:if>
                                                    <xsl:for-each select="Row">
                                                        <fo:table-row height="13pt">
                                                            <xsl:for-each select="child::*">
                                                                <fo:table-cell background-color="#FFFFFF" border-style="solid" border-width="1pt" padding-left="5pt" padding-top="5pt">
                                                                    <fo:block font-weight="normal" text-align="left">
                                                                        <xsl:value-of select="." />
                                                                    </fo:block>
                                                                </fo:table-cell>
                                                            </xsl:for-each>
                                                        </fo:table-row>
                                                    </xsl:for-each>
                                                </fo:table-body>
                                            </fo:table>
                                            <fo:block text-indent="2pc" space-after="7pt" space-before.minimum="6pt" space-before.optimum="8pt" space-before.maximum="10pt">
                                            </fo:block>
                                        </fo:flow>
                                    </fo:page-sequence>
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:for-each>
            </xsl:for-each>
        </fo:root>
    </xsl:template>
</xsl:stylesheet>

但是我遇到了以下错误:

[ERROR] [Renderer_1]org.apache.fop.fo.ValidationException: Property ID "DNumber" (found on "fo:inline") previously used; ID values must be unique within a document! (See position 4:-1)

不确定出了什么问题?如何在不产生此错误的情况下在两个地方都提供内联 ID?

这是一个示例:

<pages>
<page type="landscape">
    <p>Hello I am a landscape page</p>
</page>
<page type="portrait">
    <p>Hello I am a Portrait page</p>
</page>
<page type="landscape">
    <p>Hello I am a landscape page</p>
</page>
<page type="landscape">
    <p>Hello I am a landscape page</p>
</page>
<page type="square">
    <p>Hello I am a square page</p>
</page>
<page type="portrait">
    <p>Hello I am a Portrait page</p>
</page>
<page type="square">
    <p>Hello I am a square page</p>
</page>
</pages>

使用此样式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/pages">
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family = "Helvetica" font-size = "10px">
        <fo:layout-master-set>
            <fo:simple-page-master master-name="portrait" margin-bottom="0.5cm" margin-left="0.75cm" margin-right="0.75cm" margin-top="0.5cm" page-height="11in" page-width="8.5in">
                <fo:region-body margin-bottom = "0.5cm" margin-top = "0.25cm"/>
                <fo:region-before extent = "0cm"/>
                <fo:region-after extent = "0.5cm"/>
            </fo:simple-page-master>
        </fo:layout-master-set>
        <fo:layout-master-set>
            <fo:simple-page-master master-name="landscape" margin-bottom="0.5cm" margin-left="0.75cm" margin-right="0.75cm" margin-top="0.5cm" page-height="8.5in" page-width="11in">
                <fo:region-body margin-bottom = "0.5cm" margin-top = "0.25cm"/>
                <fo:region-before extent = "0cm"/>
                <fo:region-after extent = "0.5cm"/>
            </fo:simple-page-master>
        </fo:layout-master-set>
        <fo:layout-master-set>
            <fo:simple-page-master master-name="square" margin-bottom="0.5cm" margin-left="0.75cm" margin-right="0.75cm" margin-top="0.5cm" page-height="6in" page-width="6in">
                <fo:region-body margin-bottom = "0.5cm" margin-top = "0.25cm"/>
                <fo:region-before extent = "0cm"/>
                <fo:region-after extent = "0.5cm"/>
            </fo:simple-page-master>
        </fo:layout-master-set>
        <xsl:for-each select="page">
            <fo:page-sequence>
                <xsl:attribute name="master-reference">
                    <xsl:value-of select="@type"/>
                </xsl:attribute>
                <fo:flow flow-name="xsl-region-body">
                    <fo:block font-size="42pt"><xsl:value-of select="p"/></fo:block>
                </fo:flow>
            </fo:page-sequence>
        </xsl:for-each>
    </fo:root>
</xsl:template>
</xsl:stylesheet>

生成此 PDF 的对象:

如您所见,所有不同的页面大小。

现在,您没有提供有关您选择页面大小的方式的信息,并且您没有除 1 以外的任何大小的页面模板。这些信息应该足以回答问题 "is is even possible to achieve it"。我正在努力让您向我们提供有助于我们帮助您的信息。